PiPER arm on the Jetson — install it, then leave it running
A deployment runbook for the AgileX PiPER arm on a Jetson Orin Nano, run as a remotely-operated, unattended robot. Reflects the real bring-up — including the JetPack 6.2 driver gap that isn't in any official guide.
Arm · AgileX PiPERLink · TailscaleCompute · Orin Nano · JP6.2Unattended after install
How it fits together
The key idea: the arm's control loop runs on the Jetson, next to the hardware. The long-haul link only carries your commands and the camera feed — never the real-time joint control — so hundreds of ms of latency can't destabilize the arm.
On hand before you start
The Jetson, flashed & booting (JP6.2)SSH works on the local network
PiPER arm + its USB-to-CAN modulePlus the arm's own power supply
Logitech C920 (or USB camera)Onboard H.264/MJPG — ideal for streaming
Internet for the JetsonNeeded to build the driver + install
Your Tailscale accountSame account on laptop + Jetson
A second network to test fromYour phone hotspot works
Phase 1 · do this first
Remote access with Tailscale
Prove you can reach the board from outside her network before anything else. Everything after this you can finish remotely.
1
Update the system on good Wi-Fi
Do this while you have real bandwidth.
$ sudo apt update && sudo apt upgrade -y
Don't let anything replace the nvidia-l4t-* packages — that's the GPU/BSP stack and a bad upgrade can brick the graphics/CUDA layer. Plain upgrade is fine; avoid a full dist-upgrade.
2
Install Tailscale and bring it up
One command to install, one to join your network.
$ curl -fsSL https://tailscale.com/install.sh | sh
$ sudo tailscale up --ssh --hostname=arm-jetson
Tailscale SSH (--ssh) means no SSH keys to manage — auth goes through your Tailscale identity. The Jetson becomes reachable as arm-jetson from any device on your tailnet.
3
Make it permanent, then prove it from outside
Don't skip the off-network test.
That last step is the acceptance test for the whole deployment. If SSH works only on the site's Wi-Fi, you have local access, not remote access. Verify over the phone hotspot before you fly.
Phase 2 · the arm
PiPER over CAN
The showstopper: JetPack 6.2 ships no gs_usb driver, so the adapter is invisible until you build it. Then the arm is a renamed CAN interface, can_piper.
4
Prep the Jetson & build the CAN driver
Online required — the stock kernel is missing the driver the PiPER adapter needs.
The single biggest JP6.2 surprise. The stock kernel ships no gs_usb driver, so the PiPER adapter appears in lsusb but never creates a CAN interface. This builder compiles the module against your exact kernel, installs it, and sets it to auto-load. ~1.2 GB source download + a few minutes.
5
Bring up the arm's CAN interface
The arm is the gs_usb USB adapter — not the Jetson's built-in controller.
$ sudo ip link set can1 type can bitrate 1000000
$ sudo ip link set can1 up
can0 is the Jetson's built-in Tegra controller (40-pin pins, nothing attached) — ignore it. The PiPER adapter comes up as can1 (or can2), which is exactly why Phase 4 pins it to a fixed name, can_piper.
6
Talk to the arm with piper_control
Use the wrapper — raw piper_sdk's enable is flaky and dropped the arm mid-move.
The control pattern that matters:reset_arm() briefly disables the motors (the arm droops for a moment), so call it once at startup then stream command_joint_positions() — never reset between moves, or the joints drop. Clear the workspace and keep a hand near power before the first commanded move.
Phase 3 · eyes on it
The camera feed
Two low-latency feeds over the same Tailscale link — an overview cam on the canvas and a gripper cam on the wrist. Made permanent in Phase 4.
7
Serve both cameras over WebRTC
Two USB cams → two feeds. Pin each to its stable by-id path.
Two gotchas. Pin each camera to its /dev/v4l/by-id/… path (yours will differ — read them from ls /dev/v4l/by-id/) — raw /dev/videoN numbers swap when two cams are present. And the wrist cam enumerates as an "H264 USB Camera" but only offers MJPG as a capture format, so encode it like the C920 — -input_format h264 fails. Two 720p encodes run ~60% on the 6-core; drop the gripper to 640x480 to bank CPU for the control app.
Latency reality: a long-haul (e.g. intercontinental) link is hundreds of ms round trip. Use the video to watch and supervise; drive the arm with commands that run on the Jetson — don't close a real-time loop across the ocean. Reached by the arm-jetson Tailscale name, nothing is exposed publicly.
Phase 4 · survive a reboot
Make everything come back by itself
A power blip or reboot must recover with nobody touching it. Each piece is a service. (Verified: both come back after a cold reboot, untouched.)
8
Auto-bring-up CAN as can_piper
Finds the adapter by driver, renames it, sets 1 Mbps — resilient to enumeration order.
# /etc/systemd/system/piper-can.service
[Unit]
Description=Bring up PiPER USB-CAN as can_piper @ 1 Mbps
After=systemd-udev-settle.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/piper-can-up.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
$ sudo systemctl enable --now piper-can.service
$ ip -br link show can_piper # -> UP
9
Camera (and later, arm) as services
MediaMTX restarts on failure. The arm service waits for its control program.
Deliberately not auto-enabling the arm. An arm that powers itself into torque on boot is a hazard. It stays limp until your control program connects and runs its one reset_arm() — then holds and takes commands.
10
Keep it awake and let it power back on
No sleeping, clean comeback after a power cut.
A small UPS on site rides out brief outages and prevents unclean shutdowns that could corrupt the SD card.
Phase 5 · before you leave
The leave-it acceptance test
One real test proves the whole thing: reboot it cold and confirm it recovers with nobody helping.
11
Cold-reboot and walk away
From your laptop, ideally already off her network.
If it survives a cold reboot on the hotspot test, you're done — that's exactly the failure it'll face after a power blink at the site while you're away.
For an on-site helper — if it stops responding
Physical checks only. Two minutes. No terminal needed.
Lights on? Check the Jetson has a power light and the arm is powered.
Power-cycle the Jetson. Unplug its power, wait 30 seconds, plug it back in. Everything restarts on its own in a couple of minutes.
Check the cables. Ethernet into the router, the USB-to-CAN and camera plugged into the Jetson, the arm's own power on.
Still stuck? Message the operator — they can get in remotely once it's back on the network.
You're deployment-ready once all boxes are tickedPhase 1 and Phase 5 are the ones that decide whether this works remotely.