+There are three pieces to the shuffleboard robot software:
+* `mdc-telnet.py`: Listens to the USB serial controllers, exposes an
+TCP port that prints the voltage and six raw count measurements.
+* `Puma.py`: Contacts the telnet server and uses `PumaFk.py` to translate
+the raw counts to joint angles and XYZ position / ASN angles. Accepts
+commands on stdin like `home`, `hold`, and XYZ positions like `300 130 0`.
+* `Shuffleboard.py`: Opens a TCP port to accept commands frmo the
+game server. Contacts the telnet server and translate commands
+line `move 300 -5` into XYZ coordinates and ASN angles, Then uses
+`PumaIk.py` to generate raw joint commands to send the arm to the
+# *HIT THE E-STOP SWITCH*
+# Use the brake release switch to pose the arm into the home position.
+# Power cycle the arm to reset the counters for the home position.
+# Plug in the USB if it is not already.
+# Run `mdc-telnet.py`, wait for all six axes to report.
+# Run `Puma.py` to contact the server.
+## Send `r` command to read raw joint counters,
+## Send `a` command to read the joint angles.
+## Send `p` command to print XYZ, ASN coordinates
+## Send `hold` command to hold current position
+# Run `Shuffleboard.py` to start the shuffleboard server
+# Run `telnet localhost 27189` to verify data
+# Twist the E-stop to unlock the brake.
+# If anything looks weird -- *HIT THE E-STOP SWITCH*.
+# If the sixth axis is spinning, hit the E-stop and wait a few seconds before releasing it.
+# Sometimes it takes two or three times to settle back down.
+To calibrate the arm positions at different distances:
+# Values are in `Shuffleboard.py` function `map_z`.
+# Yes, it could be written in a much better fashion.
+# To test, send a command from the `Puma.py` program:
+## And then adjust the Z value downwards:
+# Write that value into the `map_z` function.