Skip to main content

Robot Mover: Basic Movement Control

This tutorial demonstrates basic robot movement using velocity commands over rosbridge. You'll learn how to publish geometry_msgs/Twist messages to control a ground robot.

Overview

The robot mover script:

  • Connects to rosbridge (via TensorFleet proxy or direct)
  • Publishes velocity commands on /cmd_vel_raw
  • Executes a movement sequence: forward, backward, turn left, turn right, stop

Prerequisites

  • Active TensorFleet VM with robot simulation
  • Simulation View open in VS Code sidebar
  • Dependencies installed (see Overview)

Running the Script

bun robot:mover
# or
bun src/robot_mover.js

Expected Output

Connecting to rosbridge...
roslib connection established successfully.
Advertising Twist publisher on '/cmd_vel_raw' ...
Phase: forward (duration 3s, lin=0.2, ang=0)
Phase: stop after forward (duration 1s, lin=0, ang=0)
Phase: backward (duration 3s, lin=-0.2, ang=0)
Phase: stop after backward (duration 1s, lin=0, ang=0)
Phase: turn left (duration 2s, lin=0, ang=0.5)
Phase: stop after left turn (duration 1s, lin=0, ang=0)
Phase: turn right (duration 2s, lin=0, ang=-0.5)
Phase: final stop (duration 1s, lin=0, ang=0)
Movement sequence complete.
Connection closed.

How It Works

Connection Setup

require("dotenv").config();
const ROSLIB = require("roslib");
const { connectToRobot } = require("./lib/robotic_utils");

async function main() {
const ros = await connectToRobot();
console.log("roslib connection established successfully.");
// ... movement code
}

The connectToRobot() / connect_to_robot() helper automatically:

  • Uses TensorFleet proxy if TENSORFLEET_BASE_URL and TENSORFLEET_JWT are set
  • Falls back to direct rosbridge connection otherwise

Creating Velocity Messages

function makeTwist(linearX, angularZ) {
return new ROSLIB.Message({
linear: { x: linearX, y: 0.0, z: 0.0 },
angular: { x: 0.0, y: 0.0, z: angularZ }
});
}

The Twist message has two vectors:

  • linear: Forward/backward (x), left/right (y), up/down (z)
  • angular: Roll (x), pitch (y), yaw (z)

For ground robots, we typically only use linear.x and angular.z.

Publishing Velocity Commands

const CMD_VEL_TOPIC = "/cmd_vel_raw";

const cmdVel = new ROSLIB.Topic({
ros,
name: CMD_VEL_TOPIC,
messageType: "geometry_msgs/Twist"
});

// Publish for a duration
function publishFor(ros, topic, ms, linearX, angularZ, label) {
return new Promise((resolve) => {
const intervalMs = 50;
const endTime = Date.now() + ms;
const msg = makeTwist(linearX, angularZ);

console.log(`Phase: ${label} (duration ${ms / 1000}s)`);

const timer = setInterval(() => {
if (!ros.isConnected || Date.now() >= endTime) {
clearInterval(timer);
resolve();
return;
}
topic.publish(msg);
}, intervalMs);
});
}

Key points:

  • Publish at ~20 Hz (every 50ms) for smooth control
  • Check connection status before publishing
  • Stop publishing when duration is reached

Movement Sequence

async function runMovement(ros) {
const cmdVel = new ROSLIB.Topic({
ros,
name: CMD_VEL_TOPIC,
messageType: "geometry_msgs/Twist"
});

try {
// Drive forward
await publishFor(ros, cmdVel, 3000, LINEAR_SPEED, 0.0, "forward");
await publishFor(ros, cmdVel, 1000, 0.0, 0.0, "stop");

// Drive backward
await publishFor(ros, cmdVel, 3000, -LINEAR_SPEED, 0.0, "backward");
await publishFor(ros, cmdVel, 1000, 0.0, 0.0, "stop");

// Turn left
await publishFor(ros, cmdVel, 2000, 0.0, ANGULAR_SPEED, "turn left");
await publishFor(ros, cmdVel, 1000, 0.0, 0.0, "stop");

// Turn right
await publishFor(ros, cmdVel, 2000, 0.0, -ANGULAR_SPEED, "turn right");
await publishFor(ros, cmdVel, 1000, 0.0, 0.0, "final stop");

console.log("Movement sequence complete.");
} finally {
cmdVel.unadvertise();
}
}

Configuration

Adjust speeds via environment variables or config file:

VariableDefaultDescription
CMD_VEL_TOPIC/cmd_vel_rawVelocity command topic
LINEAR_SPEED0.2Forward/backward speed (m/s)
ANGULAR_SPEED0.5Turning speed (rad/s)

Velocity Reference

Movementlinear.xangular.z
Forward+0.20
Backward-0.20
Turn Left0+0.5
Turn Right0-0.5
Forward + Turn+0.2±0.3
Stop00

Common Issues

IssueCauseSolution
Robot doesn't moveWrong topicCheck CMD_VEL_TOPIC matches your robot
Movement is jerkyPublish rate too lowEnsure 20 Hz publish rate
Connection failsVM not runningStart VM from TensorFleet status bar
Robot moves wrong directionFrame conventionCheck robot's velocity frame

Next Steps


The robot mover demonstrates the fundamental pattern for commanding robot movement. This same approach scales to more complex behaviors.