Skip to Content
BonicBot A2DevelopmentPython ProgrammingLesson 20 - 3-Axis Velocity Control

Lesson 20 - 3-Axis Velocity Control

Learning Objective

  • Publish custom 3-axis velocity vectors using bot.move(linear_x, linear_y, angular_z).
  • Combine linear translation and angular rotation to create smooth curved trajectories.
  • Understand how velocity vectors map to ROS 2 /cmd_vel (geometry_msgs/Twist) topics.

Introduction

Directional shortcuts like move_forward drive in straight lines. However, complex mobile robot motion (such as navigating smooth curves or executing spiral trajectories) requires specifying simultaneous linear translation and angular rotation.

This lesson covers driving with bot.move(linear_x, linear_y, angular_z).


Code

velocity_vectors.py
import time from bonicbot_bridge import BonicBot with BonicBot(host="192.168.29.52") as bot: print("1. Driving forward in a smooth arc to the left...") # linear_x = 0.3 m/s forward, angular_z = 0.4 rad/s counter-clockwise bot.move(linear_x=1, linear_y=0.0, angular_z=55) time.sleep(2.5) print("2. Driving backward while curving right...") # linear_x = -0.2 m/s backward, angular_z = -0.3 rad/s clockwise bot.move(linear_x=-1.5, linear_y=0.0, angular_z=-55) time.sleep(2.0) print("3. Pure in-place rotation...") bot.move(linear_x=0.0, linear_y=0.0, angular_z=360) time.sleep(1.5) print("4. Halting robot...") bot.stop()

[!NOTE] Before running the code, make sure to replace "192.168.29.52" with your BonicBot’s actual IP address.


Expected Output

Click to see expected output

Visual Output

Terminal Output

🤖 Connected to BonicBot at 192.168.29.52:9090 1. Driving forward in a smooth arc to the left... 2. Driving backward while curving right... 3. Pure in-place rotation... 4. Halting robot... 🔌 Disconnected from BonicBot

🔧 Under the Hood

How move() constructs ROS 2 Twist messages

MotionController.move() packs vector components into a geometry_msgs/Twist JSON payload:

msg = { "linear": {"x": linear_x, "y": linear_y, "z": 0.0}, "angular": {"x": 0.0, "y": 0.0, "z": angular_z} }

It publishes this message directly to the /cmd_vel ROS 2 topic.


Student Challenge

Challenge 1 — Python Only

Write a function generate_arc_cmd(radius_meters, linear_speed) that computes the required angular_z turn rate for a given turn radius radius_meters and linear_speed.

Click to see solution

arc_math.py
def generate_arc_cmd(radius_meters, linear_speed): # angular_speed = linear_speed / radius angular_z = linear_speed / radius_meters return {"linear_x": linear_speed, "angular_z": angular_z} cmd = generate_arc_cmd(radius_meters=1.5, linear_speed=0.3) print("Arc velocity vector:", cmd)

Challenge 2 — Robot

Drive the robot in an “S-curve” pattern: 2 seconds curving left (linear_x=0.3, angular_z=0.4), followed immediately by 2 seconds curving right (linear_x=0.3, angular_z=-0.4), then stop.

Click to see solution

s_curve.py
import time from bonicbot_bridge import BonicBot with BonicBot(host="192.168.0.188") as bot: print("Executing left curve...") bot.move(linear_x=0.3, angular_z=0.4) time.sleep(2.0) print("Executing right curve...") bot.move(linear_x=0.3, angular_z=-0.4) time.sleep(2.0) bot.stop()

Quick Reference

ParameterTypeUnitDescription
linear_xfloatm/sForward (+) or Backward (-) translation speed
linear_yfloatm/sLateral translation speed (0 for differential drive)
angular_zfloatrad/sCounter-clockwise (+) or Clockwise (-) rotation

Reflection Questions

What happens to a differential drive robot if you specify linear_y != 0 in bot.move()?

How does varying linear_x while keeping angular_z constant change the turning radius of the robot?

Last updated on