Demo: Pick and Place
The robot reaches to a fixed pickup zone, closes its hand around a light object, lifts it, moves to a separate place zone, and releases it. This is the same category of task — sense, reach, grasp, transport, release — behind pick-and-place work in real manufacturing and warehouse robotics.
The pickup and place positions in this version are fixed, tested poses rather than fully general object localization. This teaches the manipulation sequence — approach, grasp, lift, transport, release — without pretending the robot can pick up arbitrary objects anywhere on the table.
What students learn
Students learn how a manipulation task breaks into stages, why lift height matters before a horizontal move, and how grasp and release are just hand-pose commands like any other.
Hardware used
- Shoulder, elbow, and wrist servos
- Hand and finger servos
- Optional RealSense camera for zone detection
- Motion node
Concepts covered
- Approach and grasp poses
- Lift-before-move sequencing
- Hand open/close as a pose command
- Transport between two fixed poses
- Behavior sequencing
Run command
Starter code
Each stage of the pick-and-place sequence is its own function, so students can test approach, grasp, or place independently before running the whole thing.
"""
Demo: Pick and Place
Purpose:
Pick up a light object from a fixed pickup zone and place it in a
fixed place zone.
Important:
Pickup and place positions are tested, fixed poses in this version,
not general-purpose object localization.
"""
from time import sleep
from swayform.motion import MotionClient
LIFT_HOLD_SECONDS = 0.6
TRANSPORT_HOLD_SECONDS = 0.8
PICKUP_APPROACH = {"shoulder_pitch": 30, "shoulder_roll": 5, "elbow_pitch": 55, "wrist_yaw": 0}
PICKUP_GRASP = {"shoulder_pitch": 34, "shoulder_roll": 5, "elbow_pitch": 62, "wrist_yaw": 0}
LIFT_POSE = {"shoulder_pitch": 10, "shoulder_roll": 5, "elbow_pitch": 40, "wrist_yaw": 0}
PLACE_APPROACH = {"shoulder_pitch": 20, "shoulder_roll": -25, "elbow_pitch": 55, "wrist_yaw": 0}
def approach_object(motion: MotionClient) -> None:
"""Move over the pickup zone before descending to grasp."""
motion.move_joint_group("right_arm", PICKUP_APPROACH)
sleep(0.5)
def grasp_object(motion: MotionClient) -> None:
"""Descend to the object and close the hand."""
motion.move_joint_group("right_arm", PICKUP_GRASP)
sleep(0.4)
motion.set_hand_pose("right_hand", "gentle_close")
sleep(LIFT_HOLD_SECONDS)
def lift_and_transport(motion: MotionClient) -> None:
"""Lift clear of the table before moving sideways to the place zone."""
motion.move_joint_group("right_arm", LIFT_POSE)
sleep(LIFT_HOLD_SECONDS)
motion.move_joint_group("right_arm", PLACE_APPROACH)
sleep(TRANSPORT_HOLD_SECONDS)
def release_object(motion: MotionClient) -> None:
"""Open the hand to release the object in the place zone."""
motion.set_hand_pose("right_hand", "open")
sleep(0.4)
def main() -> None:
motion = MotionClient()
motion.safe_pose("idle")
try:
motion.lock_behavior("pick_and_place")
approach_object(motion)
grasp_object(motion)
lift_and_transport(motion)
release_object(motion)
finally:
motion.safe_pose("idle")
motion.unlock_behavior("pick_and_place")
if __name__ == "__main__":
main()
Code walkthrough
set_hand_pose is the same call used in other demos. Grasping is just a hand pose, not a special mechanism.Try changing this
- Change the place zone to the other side of the robot.
- Add a second object and a second place zone.
- Slow down the lift for a heavier object.
- Add a RealSense check that the pickup zone is occupied before starting.
Use only light, easy-to-grip objects. Do not test grasp poses on fingers or hands — the hand should only ever close around a tested tabletop object.
After Pick and Place, try Lab 04: Head Tracking Basics.