Skip to Content
BonicBot A2DevelopmentPython ProgrammingLesson 24 - Arm, Gripper & Neck Servos

Lesson 24 - Arm, Gripper & Neck Servos

Learning Objective

  • Command articulated left and right arm joint angles using move_left_arm() and move_right_arm().
  • Control end-effector grippers using open_grippers(), close_grippers(), and set_grippers().
  • Control head pan/tilt orientation using set_neck(), look_left(), look_right(), and look_center().

Introduction

Articulated robots use servos to move limbs, actuate grippers, and point sensors. The bonicbot_bridge SDK provides high-level shortcuts for commanding left/right arms, grippers, and neck joint positions.

This lesson covers joint positioning methods for arms, end-effectors, and neck servos.


Code

servo_commands.py
import time from bonicbot_bridge import BonicBot with BonicBot(host="192.168.29.52") as bot: print("1. Centering neck and opening grippers...") bot.look_center() time.sleep(2.0) print("2. Panning neck left and right...") bot.look_left() time.sleep(2.0) bot.look_center() time.sleep(2) bot.look_right() time.sleep(2.0) bot.look_center() time.sleep(2) print("3. Moving left and right arms to 45° shoulder / 30° elbow pose...") bot.move_left_arm(shoulder=65.0, elbow=40.0, wait=True) time.sleep(2) bot.move_right_arm(shoulder=65.0, elbow=40.0, wait=True) time.sleep(2) bot.open_grippers() time.sleep(2) print("4. Closing grippers...") bot.close_grippers() time.sleep(1.0) print("5. Resetting all servos to neutral 0° positions...") bot.reset_servos()

Expected Output

Click to see expected output

Visual Output

Terminal Output

🤖 Connected to BonicBot at 192.168.29.52:9090 1. Centering neck and opening grippers... 2. Panning neck left and right... 3. Moving left and right arms to 45° shoulder / 30° elbow pose... 4. Closing grippers... 5. Resetting all servos to neutral 0° positions... 🔌 Disconnected from BonicBot

🔧 Under the Hood

How arm methods convert degrees in servo.py

ServoController.move_left_arm() converts shoulder and elbow angles from degrees to radians via math.radians(), constructs a ROS 2 sensor_msgs/JointState payload, and publishes to /joint_states.


Student Challenge

Challenge 1 — Python Only

Write a helper function deg_to_rad_dict(degrees_dict) that takes a dictionary of joint angles in degrees and returns a new dictionary with angles converted to radians.

Click to see solution

deg_rad.py
import math def deg_to_rad_dict(degrees_dict): return {joint: math.radians(deg) for joint, deg in degrees_dict.items()} input_deg = {"neck_yaw": 45.0, "left_elbow": 30.0} print("Converted radians:", deg_to_rad_dict(input_deg))

Challenge 2 — Robot

Program a “wave” routine: raise right shoulder to 90°, move elbow between 20° and 50° twice, then call bot.reset_servos().

Click to see solution

wave_routine.py
import time from bonicbot_bridge import BonicBot with BonicBot(host="192.168.0.188") as bot: print("Raising right arm...") bot.move_right_arm(shoulder=90.0, elbow=20.0, wait=True) for _ in range(2): bot.move_right_arm(shoulder=90.0, elbow=50.0, wait=True) time.sleep(0.3) bot.move_right_arm(shoulder=90.0, elbow=20.0, wait=True) time.sleep(0.3) bot.reset_servos()

Quick Reference

MethodDescription
bot.move_left_arm(shoulder, elbow, wait)Set left arm joint angles in degrees
bot.move_right_arm(shoulder, elbow, wait)Set right arm joint angles in degrees
bot.set_servos(angles_dict)Command multiple joint angles via dict
bot.reset_servos()Reset all servos to 0° neutral positions

Reflection Questions

Why is the wait=True parameter useful when commanding multi-joint arm trajectories?

What happens if you pass joint angle values in radians instead of degrees to move_left_arm()?

Last updated on