@moescet/simple-teleop
v0.1.0
Published
Simple teleoperation capability for remote robot control with keyboard
Downloads
104
Maintainers
Readme
Simple Teleoperation Capability
A lightweight remote teleoperation capability for the Transitive Robotics framework that enables keyboard control of a simulated robot with real-time position and velocity feedback.
Features
- Keyboard Control: Use arrow keys to control robot movement
- ↑/↓ for forward/backward motion
- ←/→ for left/right turning
- Real-time Feedback: Live display of robot position (x, y, θ) and velocities
- Smooth Movement: 50Hz physics simulation for smooth, non-jagged motion
- Zero Latency: Direct MQTT communication between web UI and robot
- No ROS Required: Pure Node.js implementation
- Self-hosted: Runs on your own Transitive instance
Architecture
This capability consists of three components:
Robot Component (
robot/) - Node.js simulator with 2D physics- Maintains robot state (position and velocity)
- Runs physics simulation at 50Hz
- Publishes state updates at 10Hz
- Receives velocity commands via MQTT
Web Component (
web/) - React-based UI with keyboard control- Captures arrow key events
- Publishes velocity commands
- Displays real-time robot state
- Visual feedback for active keys
Cloud Component (
cloud/) - Optional monitoring/logging- Logs commands and state updates
- Can be extended for analytics
Installation
Prerequisites
- Node.js >= 14.0.0
- Self-hosted Transitive Robotics instance
- npm or yarn package manager
Setup
Clone or create the capability package:
cd /path/to/your/capabilities mkdir -p @local/simple-teleop cd @local/simple-teleopCopy all files into the directory with this structure:
@local/simple-teleop/ ├── package.json ├── README.md ├── robot/ │ ├── package.json │ └── index.js ├── web/ │ ├── package.json │ └── index.jsx └── cloud/ ├── package.json └── index.jsInstall dependencies for each component:
# Robot component cd robot && npm install && cd .. # Web component cd web && npm install && cd .. # Cloud component cd cloud && npm install && cd ..Register the capability with your Transitive instance:
transitive-cli capability add @local/simple-teleop
Quick Start
1. Start the Robot Simulator
cd robot
node index.jsYou should see output like:
[simple-teleop-robot] Initializing robot simulator
[simple-teleop-robot] Robot simulator initialized and running
[simple-teleop-robot] Physics update rate: 50 Hz
[simple-teleop-robot] State publish rate: 10 Hz2. Start the Cloud Component (Optional)
In a new terminal:
cd cloud
node index.js3. Access the Web UI
Open your Transitive web interface and navigate to the Simple Teleoperation capability. You should see:
- Connection status (Connected/Disconnected)
- Robot state display showing position and velocity
- Keyboard control visual indicators
- Speed settings
4. Control the Robot
Click anywhere in the web UI to focus it, then use arrow keys:
- ↑ - Move forward
- ↓ - Move backward
- ← - Turn left (counter-clockwise)
- → - Turn right (clockwise)
The robot will move smoothly, and you'll see real-time updates of:
- Position: x, y (in meters), θ (in degrees)
- Velocity: linear (m/s), angular (rad/s)
Testing the Simulator
Test 1: Forward Motion
- Press and hold ↑ for 2 seconds
- Release the key
- Expected result:
- Linear velocity shows 0.5 m/s while key is pressed
- Linear velocity returns to 0 when released
- Position x increases (assuming θ = 0°)
- Movement is smooth, not jerky
Test 2: Turning
- Press and hold ← for ~3 seconds
- Release the key
- Expected result:
- Angular velocity shows 1.0 rad/s while key is pressed
- θ increases from 0° toward 180° (counter-clockwise)
- Angular velocity returns to 0 when released
Test 3: Combined Movement
- Press and hold ↑ and ← together
- Hold for 5 seconds
- Release both keys
- Expected result:
- Robot moves in a circular arc to the left
- Both linear and angular velocities are non-zero
- Path is smooth and continuous
- Both velocities return to 0 when released
Test 4: Response Time
- Quickly tap ↑ (very brief press)
- Expected result:
- Velocity command sent immediately on keydown
- Stop command (0,0) sent immediately on keyup
- No noticeable lag between key press and robot response
Understanding the Coordinate System
The robot operates in a 2D Cartesian coordinate system:
+Y (North)
^
|
|
-X <--+--> +X (East)
|
|
v
-Y (South)Position
- x, y: Position in meters from origin (0, 0)
- θ (theta): Heading angle in radians
- 0° = facing East (+X direction)
- 90° = facing North (+Y direction)
- 180° / -180° = facing West (-X direction)
- -90° = facing South (-Y direction)
Physics Model
The simulator uses simple 2D kinematics:
// Update rate: 50Hz (dt = 0.02 seconds)
theta += angular_velocity * dt
x += linear_velocity * cos(theta) * dt
y += linear_velocity * sin(theta) * dtDefault Speeds
- Linear velocity: 0.5 m/s (forward/backward)
- Angular velocity: 1.0 rad/s (≈ 57.3°/s rotation speed)
Communication Architecture
┌─────────────┐ MQTT ┌──────────────┐
│ Web UI │ ←------------------→ │ Robot │
│ (Browser) │ │ Simulator │
└─────────────┘ └──────────────┘
↓ ↓
└────────→ MQTTSync ←─────────────────┘
↓
┌─────────────┐
│ Cloud │
│ Component │
└─────────────┘MQTT Topics
${prefix}/cmd- Velocity commands from web to robot- Message:
{ linear: number, angular: number } - Published at 20Hz while keys are pressed
- Message:
${prefix}/state- Robot state from robot to web- Message:
{ position: {x, y, theta}, velocity: {linear, angular}, timestamp } - Published at 10Hz
- Message:
${prefix}/status- Heartbeat and status updates- Published every 1 second
Customization
Adjust Speeds
Edit web/index.jsx:
const DEFAULT_LINEAR_SPEED = 0.5; // Change to desired m/s
const DEFAULT_ANGULAR_SPEED = 1.0; // Change to desired rad/sAdjust Update Rates
Edit robot/index.js:
const PHYSICS_DT = 0.02; // Physics loop: 0.02 = 50Hz
const STATE_PUBLISH_INTERVAL = 100; // State publishing: 100ms = 10HzEdit web/index.jsx:
const COMMAND_PUBLISH_RATE = 50; // Command rate: 50ms = 20HzAdd More Controls
You can extend the keyboard controls in web/index.jsx:
- Add different speed modes
- Add boost functionality
- Add emergency stop button
- Add waypoint navigation
Troubleshooting
Robot not responding to commands
- Check MQTT connection status in web UI (should show "Connected")
- Verify robot component is running (
node robot/index.js) - Check browser console for errors
- Ensure web UI has focus (click on the page)
Jerky or laggy movement
- Check your network latency to MQTT broker
- Verify physics loop is running at 50Hz (check robot logs)
- Ensure no CPU throttling on robot machine
- Try reducing command publish rate in web component
Keys not working
- Click on the web UI to give it focus
- Check browser console for event listener errors
- Verify arrow keys aren't captured by browser shortcuts
- Try a different browser
State not updating
- Verify robot component is publishing state (check logs)
- Check MQTT connection in web UI
- Verify network connectivity to MQTT broker
- Check browser console for subscription errors
Development
Project Structure
@local/simple-teleop/
├── package.json # Capability metadata
├── README.md # This file
├── robot/
│ ├── package.json # Robot dependencies
│ └── index.js # Robot simulator with physics
├── web/
│ ├── package.json # Web dependencies
│ └── index.jsx # React UI component
└── cloud/
├── package.json # Cloud dependencies
└── index.js # Cloud monitoring componentAdding New Features
- Add sensors: Extend robot state in
robot/index.js - Add visualizations: Modify
web/index.jsxto display new data - Add logging: Extend
cloud/index.jsfor analytics - Add obstacles: Implement collision detection in robot physics
License
MIT
Support
For issues with:
- This capability: Check the troubleshooting section above
- Transitive framework: Refer to Transitive Robotics documentation
- MQTT connectivity: Check your Transitive instance configuration
