Lesson 24 - Arm, Gripper & Neck Servos
Learning Objective
- Command articulated left and right arm joint angles using
move_left_arm()andmove_right_arm(). - Control end-effector grippers using
open_grippers(),close_grippers(), andset_grippers(). - Control head pan/tilt orientation using
set_neck(),look_left(),look_right(), andlook_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
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
servo.pyServoController.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
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
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
Arm Commands
| Method | Description |
|---|---|
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()?