saltylab-firmware/phone/INSTALL_MOTOR_TEST.md
sl-firmware e4116dffc0 feat: Remove ELRS arm requirement for autonomous operation (Issue #512)
Enable Jetson autonomous arming while keeping RC as optional override.

Changes:
- RC kill switch (CH5 OFF) now triggers emergency stop instead of disarm
  → Allows Jetson-armed robots to remain armed when RC disconnects
  → Maintains kill switch safety for emergency situations

- RC disarm only triggers on explicit CH5 falling edge (RC still alive)
  → RC disconnect doesn't disarm Jetson-controlled missions
  → RC failsafe timer (500ms) handles signal loss separately

- Jetson arming via CDC 'A' command works independently of RC state
  → Robots can operate fully autonomous without RC transmitter
  → Heartbeat timeout (500ms) prevents runaway if Jetson crashes

Safety maintained:
- Arming hold timer: 500ms (prevents accidental arm)
- Tilt limit: ±10° level required
- IMU calibration: Required before any arm attempt
- Remote E-stop: Blocks all arming
- RC failsafe: 500ms signal loss = disarm
- Jetson timeout: 500ms heartbeat = zero motors

Command protocol (unchanged):
- Jetson: A=arm, D=disarm, E=estop, Z=clear estop
- RC: CH5 switch (optional override)
- Heartbeat: H command every ≤500ms
- Drive: C<speed>,<steer> every ≤200ms

See AUTONOMOUS_ARMING.md for complete protocol and testing checklist.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 11:45:12 -05:00

4.8 KiB

Motor Test Joystick Installation (Issue #513)

Quick setup guide for installing motor_test_joystick.py on Termux.

Prerequisites

  • Android phone with Termux installed
  • Python 3.9+ (installed via termux-bootstrap.sh)
  • ROS2 Humble OR Jetson bridge running on networked Jetson Orin

Installation

1. Copy script to phone

Option A: Via USB (adb)

# On your computer
adb push phone/motor_test_joystick.py /data/data/com.termux/files/home/

# Or just place in ~/saltylab-firmware/phone/ if building locally

Option B: Via git clone in Termux

# In Termux
cd ~
git clone https://gitea.vayrette.com/seb/saltylab-firmware.git
cd saltylab-firmware

2. Make executable

# In Termux
chmod +x ~/saltylab-firmware/phone/motor_test_joystick.py

3. Verify dependencies

For ROS2 backend (requires ros_core on Jetson):

# Check if ROS2 is available
python3 -c "import rclpy; print('✓ ROS2 available')" 2>/dev/null || echo "✗ ROS2 not available (use --backend websocket)"

For WebSocket backend (fallback, no dependencies):

python3 -c "import json, socket; print('✓ WebSocket dependencies available')"

Quick Test

1. Start on phone (Termux)

Option A: ROS2 mode (requires Jetson ros_core running)

python3 ~/saltylab-firmware/phone/motor_test_joystick.py

Option B: WebSocket mode (if Jetson IP is 192.168.1.100)

python3 ~/saltylab-firmware/phone/motor_test_joystick.py \
  --backend websocket \
  --host 192.168.1.100

2. Verify on Jetson

Monitor /cmd_vel topic:

# On Jetson
ros2 topic echo /cmd_vel

You should see Twist messages (linear.x, angular.z) when moving the joystick.

3. Safety test

  1. Move joystick forward (W key)
  2. Watch /cmd_vel values change
  3. Press spacebar (E-stop)
  4. Verify velocities go to 0.0
  5. Press Q to quit
  6. Verify "Velocities sent to zero" message

Setup Automation

Auto-launch from Termux:Boot

  1. Install Termux:Boot from F-Droid

  2. Create startup script:

    mkdir -p ~/.termux/boot
    cat > ~/.termux/boot/start_motor_test.sh << 'EOF'
    #!/bin/bash
    # Start motor test joystick in background
    cd ~/saltylab-firmware/phone
    python3 motor_test_joystick.py --backend websocket --host 192.168.1.100 &
    EOF
    chmod +x ~/.termux/boot/start_motor_test.sh
    
  3. Next boot: app will start automatically

Manual session management

# Start in background
nohup python3 ~/saltylab-firmware/phone/motor_test_joystick.py > ~/motor_test.log 2>&1 &
echo $! > ~/motor_test.pid

# Stop later
kill $(cat ~/motor_test.pid)

# View logs
tail -f ~/motor_test.log

Configuration

Adjust velocity limits

Conservative (default):

python3 motor_test_joystick.py  # 0.1 m/s, 0.3 rad/s

Moderate:

python3 motor_test_joystick.py --linear-max 0.3 --angular-max 0.8

Aggressive:

python3 motor_test_joystick.py --linear-max 0.5 --angular-max 1.5

Change Jetson address

For static IP:

python3 motor_test_joystick.py --backend websocket --host 192.168.1.100

For hostname (requires mDNS):

python3 motor_test_joystick.py --backend websocket --host saltybot.local

For different port:

python3 motor_test_joystick.py --backend websocket --host 192.168.1.100 --port 8080

Troubleshooting

"ModuleNotFoundError: No module named 'curses'"

Curses should be built-in with Python. If missing:

# Unlikely needed, but just in case:
python3 -m pip install windows-curses  # Windows only
# On Android/Termux, it's included

"ROS2 module not found" (expected if no ros_core)

Solution: Use WebSocket backend

python3 motor_test_joystick.py --backend websocket --host <jetson-ip>

Terminal display issues

  • Make terminal larger (pinch-zoom)
  • Reset terminal: reset
  • Clear artifacts: clear
  • Try external keyboard (more reliable than touch)

No motor response

  1. Check Jetson ros_core is running:

    # On Jetson
    ps aux | grep -E "ros|dcps" | grep -v grep
    
  2. Check motor bridge is subscribed to /cmd_vel:

    # On Jetson
    ros2 topic echo /cmd_vel  # Should see messages from phone
    
  3. Verify phone can reach Jetson:

    # In Termux
    ping <jetson-ip>
    nc -zv <jetson-ip> 9090  # For WebSocket mode
    
  4. Check phone ROS_DOMAIN_ID matches Jetson (if using ROS2):

    # Should match: export ROS_DOMAIN_ID=0 (default)
    

Uninstall

# Remove script
rm ~/saltylab-firmware/phone/motor_test_joystick.py

# Remove auto-launch
rm ~/.termux/boot/start_motor_test.sh

# Stop running process (if active)
pkill -f motor_test_joystick

Support

For issues, refer to: