44gripper through the palletizing task: a conveyor feeds boxes one at a time to a
55fixed pickup point, and the robot stacks them into an ordered grid on the pallet.
66
7- Coordination with the feeder (box_spawner.py) is a two-message handshake:
8- - the feeder publishes the box name on /box_ready when a box is stopped at the
9- pickup point, and then waits;
10- - this code picks and stacks the box, then publishes the name on /box_done,
11- which releases the next box.
7+ Coordination with the feeder (box_spawner.py) is a two-call handshake, fully
8+ wrapped by the HAL so this code never touches ROS directly:
9+ - HAL.WaitForBox() blocks until a box is stopped at the pickup point and
10+ returns its name;
11+ - HAL.BoxDone(name) reports the box is stacked, which releases the next box.
1212
1313IMPORTANT — coordinate frames and tuning
1414========================================
2424cup just touches the box. Everything marked `# TUNE` is a candidate to adjust.
2525"""
2626
27- import rclpy
28- from rclpy .node import Node
29- from std_msgs .msg import String
30-
3127import HAL_Harmonic as HAL
3228
3329# --- Geometry ---------------------------------------------------------------
@@ -101,34 +97,7 @@ def grid_cell(index):
10197 return x , y , z , layer , row , col
10298
10399
104- class FeederLink (Node ):
105- """Handshake node: receive /box_ready, acknowledge with /box_done."""
106-
107- def __init__ (self ):
108- super ().__init__ ("palletizing_solution" )
109- self ._ready_box = None
110- self ._processed_boxes = set ()
111- self .create_subscription (String , "/box_ready" , self ._on_ready , 10 )
112- self ._done_pub = self .create_publisher (String , "/box_done" , 10 )
113-
114- def _on_ready (self , msg ):
115- if msg .data not in self ._processed_boxes :
116- self ._ready_box = msg .data
117-
118- def wait_for_box (self ):
119- """Block until a box is announced at the pickup point; return its name."""
120- self ._ready_box = None
121- while rclpy .ok () and self ._ready_box is None :
122- rclpy .spin_once (self , timeout_sec = 0.1 )
123- self ._processed_boxes .add (self ._ready_box )
124- return self ._ready_box
125-
126- def box_done (self , name ):
127- """Tell the feeder the box has been palletized; release the next."""
128- self ._done_pub .publish (String (data = name ))
129-
130-
131- def pick (link ):
100+ def pick ():
132101 """Lower onto the box at the pickup point, grip, and lift clear."""
133102 bx = PICK_WORLD_X
134103 by = PICK_WORLD_Y
@@ -137,17 +106,17 @@ def pick(link):
137106
138107 # Swing gracefully from home to a safe high clearance point directly over the box
139108 HAL .MoveJoint ([bx , by , approach_z + 0.3 ], CUP_DOWN_YPR , SPEED , SETTLE )
140-
109+
141110 # Smooth, single vertical descent onto the box
142111 HAL .MoveLinear ([bx , by , grip_z ], CUP_DOWN_YPR , SPEED , SETTLE )
143-
112+
144113 HAL .SuctionSet (True , GRIP_PAUSE ) # vacuum on
145-
114+
146115 # Lift the box clear in a single motion
147116 HAL .MoveLinear ([bx , by , approach_z + 0.3 ], CUP_DOWN_YPR , SPEED , SETTLE )
148117
149118
150- def place (link , index ):
119+ def place (index ):
151120 """Carry the held box to grid cell `index` and release it."""
152121 wx , wy , wz , layer , row , col = grid_cell (index )
153122 # tool0 sits CUP_REACH + box height above the target box centre.
@@ -163,30 +132,26 @@ def place(link, index):
163132
164133
165134def main ():
166- # rclpy is already initialised by HAL; just add our coordination node.
167- link = FeederLink ()
168-
169135 # Natural 'up' home pose: [pan, lift, elbow, w1, w2, w3] in DEGREES
170136 # This keeps the arm safely clear of the workspace without awkward IK contortions.
171137 home_joints = [0.0 , - 90.0 , 0.0 , - 90.0 , 0.0 , 0.0 ]
172138 HAL .MoveAbsJ (home_joints , SPEED , SETTLE )
173139
174140 total = GRID_COLS * GRID_ROWS * GRID_LAYERS
175141 for index in range (total ):
176- name = link . wait_for_box ()
142+ name = HAL . WaitForBox ()
177143 if name is None :
178144 break
179145 print (f"box { name } ready -> placing as #{ index } " )
180-
181- pick (link )
182- place (link , index )
183- link . box_done (name )
184-
146+
147+ pick ()
148+ place (index )
149+ HAL . BoxDone (name )
150+
185151 # Return to home pose before waiting for the next box to ensure a clean sweep
186152 HAL .MoveAbsJ (home_joints , SPEED , SETTLE )
187153
188154 print ("palletizing complete" )
189- link .destroy_node ()
190155
191156
192157if __name__ == "__main__" :
0 commit comments