Dual Joystick
FREETwo-stick control for driving and steering
When to reach for it
Dual Joystick suits teleop needing separate translation and rotation: Differential for skid-steer, Omni for holonomic strafe, Drone M1 and Drone M2 for quadcopter throttle plus attitude. For one axis, Single Joystick does the job at half the footprint.
Worked example: differential drive on /cmd_vel
Topic /cmd_vel, message type geometry_msgs/msg/Twist, Robot Type Differential: left stick drives, right stick turns. Set Max Linear Speed and Max Angular Speed to the robot's real m/s and rad/s max, not the normalized 1.0 default, so a stick push can't outrun the base. Publish Rate (Hz) (Pro) defaults to 10 Hz: push toward 50-100 Hz for a tight loop, or down to 5, not 10, over a bad link. Release the stick and it doesn't wait for the next tick: a zero Twist flushes immediately, so a stalled JS thread can't leave it coasting on stale velocity.
Watch out for
- Twist carries six axes; most robots listen on two or three. The wrong Robot Type silently publishes components the robot ignores: it looks like nothing happened.
- Compact Mode Stick decides which stick survives below two-sticks-wide. Pick Left (Move) and rotation freezes at its last value, not zero, on collapse.
- Publish Rate (Hz), Velocity Curve, Dead Zone, and Haptic Feedback are Pro-only: free tier is stuck at 10 Hz regardless of link or loop.
Configuration fields
The topic this widget publishes to. While connected, tap to pick from the topics the robot advertises.
Applied to linear.x/y/z axes. 1.0 = normalized (-1 to 1). Enter robot max m/s for REP-103 (TurtleBot3 = 0.22, Spot trot = 1.6).
Applied to angular.x/y/z axes. 1.0 = normalized (-1 to 1). Enter robot max rad/s (TurtleBot3 = 2.84, indoor = 1.0-1.5).
Remap which Twist field this axis controls (inversion + axis-off included here)
Remap which Twist field this axis controls (inversion + axis-off included here)
Remap which Twist field this axis controls (inversion + axis-off included here)
Remap which Twist field this axis controls (inversion + axis-off included here)
Pro unlocks a "Custom" robot type that reveals the per-axis editor below, so you can remap any stick direction to any Twist field.
How fast the joystick streams Twist messages.
WITH PRODefault is 10 Hz. Robots running tighter control loops (50 to 100 Hz) feel smoother at higher rates; bandwidth-constrained links can drop to 5 Hz to save throughput. Throttle here, before the bridge has to work.
Response curve for stick-to-speed mapping.
WITH PROLinear is direct (good for arcade-style driving). Quadratic and Cubic give finer control near zero, so your last 10% of stick travel does most of the work, ideal for precision teleoperation. Exponential is the opposite: tiny movements stay tiny, big movements explode.
Movements within this radius from center are sent as zero (a stop), not dropped. Past the radius, output ramps from zero and is shaped by the Velocity Curve. Shown as a ring in the preview.
0 to 0.3, step 0.01WITH PROCompensates for stick drift and prevents accidental nudges from a thumb resting on the touchscreen.
Vibration intensity on center snap.
WITH PROA subtle pulse when the stick recenters lets you feel "released" without looking at the screen. Helpful in stressful operation when your eyes are on the robot, not the phone.
If the widget gets resized too narrow to show both sticks side-by-side, only the chosen one stays visible. The other axes still publish using the last known value.