11import sys
2+ import typing
23
34from compas import json_load
45import compas .geometry
56from compas_fab .backends import RosClient
7+ from compas_fab .backends .ros .messages import ROSmsg
68import compas_rrc as rrc
9+ from clay_3dp_print import PrintLayer
710
811# IP = "192.168.8.30" # cook
912IP = "localhost"
1013
1114WOBJ = "wobj_pallet_markers"
1215TOOL = "t_erratic_t25"
1316
14- DRY_RUN = False
15-
1617SPEED = 75
1718SPEED_PRINT = 50
1819
20+ EXTRUSION_FACTOR_DO = "ao_printPtSpd"
21+
22+ # negative means move towards the sky
23+ Z_ADJUSTMENT = - 3
24+
1925
20- def get_set_extruder (state : int ):
21- return rrc .SetDigital ( "do_extrudeRelSpd" , state )
26+ def get_set_extruder (speed_factor : float ):
27+ return rrc .SetAnalog ( EXTRUSION_FACTOR_DO , speed_factor )
2228
2329
24- def get_start_extrude ():
25- if not DRY_RUN :
26- return get_set_extruder (1 )
30+ def get_start_extrude (speed_factor = 1 ):
31+ return get_set_extruder (speed_factor )
2732
2833
2934def get_stop_extrude ():
30- if not DRY_RUN :
31- return get_set_extruder (0 )
35+ return get_set_extruder (0 )
3236
3337
34- def construct_cmds (frames , travel ) :
35- last_was_t = True
38+ def construct_cmds (layers : list [ PrintLayer ]) -> typing . Generator [ ROSmsg ] :
39+ first_print_frame = layers [ 0 ]. pop ( 0 )
3640
37- cmds = []
38- for i , (lframes , ltravel ) in enumerate (zip (frames , travel )):
39- lcmds = []
41+ first_print_frame .translate_frame_in_local_Z (Z_ADJUSTMENT )
4042
41- lcmds .append (rrc .PrintText (f"Layer { i } " ))
43+ yield rrc .MoveToFrame (
44+ first_print_frame , SPEED , rrc .Zone .FINE , motion_type = rrc .Motion .JOINT
45+ )
4246
43- x , y , z = lframes [0 ].point
47+ for i , layer in enumerate (layers ):
48+ yield rrc .PrintText (f"Layer { i } " )
49+
50+ x , y , z = layer [0 ].point
4451 first_pt_str = f"{ x :.2f} ,{ y :.2f} ,{ z :.2f} "
4552
46- lcmds . append ( rrc .PrintText (f"First frame: { first_pt_str } " ) )
53+ yield rrc .PrintText (f"First frame: { first_pt_str } " )
4754
48- for f , t in zip (lframes , ltravel , strict = True ):
49- if not DRY_RUN :
50- if not t and last_was_t :
51- lcmds .append (get_start_extrude ())
55+ for print_frame in layer :
56+ yield get_set_extruder (print_frame .extrusion_factor )
5257
53- if t and not last_was_t :
54- lcmds .append (get_stop_extrude ())
58+ print_frame .translate_frame_in_local_Z (Z_ADJUSTMENT )
5559
56- lcmds .append (
57- rrc .MoveToFrame (
58- f ,
59- SPEED if t else SPEED_PRINT ,
60- rrc .Zone .Z1 ,
61- motion_type = rrc .Motion .LINEAR ,
62- )
63- )
64- last_was_t = t
60+ if print_frame .is_travel ():
61+ # TODO: Add retraction
62+ pass
6563
66- cmds .append (lcmds )
67- return cmds
64+ yield rrc .MoveToFrame (
65+ print_frame ,
66+ SPEED if print_frame .is_travel () else SPEED_PRINT ,
67+ rrc .Zone .Z1 ,
68+ motion_type = rrc .Motion .LINEAR ,
69+ feedback_level = rrc .FeedbackLevel .DONE ,
70+ )
6871
6972
70- def robot_program (
71- frames : list [ list [ compas . geometry . Frame ]], travel : list [ list [ bool ]] | None
73+ def process_with_batches (
74+ abb : rrc . AbbClient , cmd_generator : typing . Generator [ ROSmsg ], batch_size : int = 100
7275):
76+ futures = []
77+ commands_sent = 0
78+
79+ # Send the first batch
80+ for _ in range (batch_size ):
81+ try :
82+ cmd = next (cmd_generator )
83+
84+ feedback = abb .send (cmd )
85+
86+ if feedback :
87+ futures .append (feedback )
88+
89+ commands_sent += 1
90+ except StopIteration :
91+ break
92+
93+ while futures :
94+ completed = []
95+ for f in futures :
96+ try :
97+ f .result (timeout = 3 )
98+ completed .append (f )
99+ except rrc .TimeoutException :
100+ continue
101+
102+ # Remove completed futures
103+ for f in completed :
104+ futures .remove (f )
105+
106+ # Add more commands to maintain the buffer
107+ for _ in range (len (completed )):
108+ try :
109+ cmd = next (cmd_generator )
110+ futures .append (abb .send (cmd ))
111+ commands_sent += 1
112+ except StopIteration :
113+ break
114+
115+
116+ def robot_program (layers : list [PrintLayer ]):
117+ breakpoint ()
73118 # Define robot joints
74119 robot_joints_start_position = robot_joints_end_position = [100 , 20 , 25 , 5 , - 40 , - 10 ]
75120
@@ -81,19 +126,7 @@ def robot_program(
81126 override = 100 # Unit [%]
82127 max_tcp = 250 # Unit [mm/s]
83128
84- z_adjustment_mm = - 3 # negative means raise up printbed
85-
86- if z_adjustment_mm != 0 :
87- for layer in frames :
88- for frame in layer :
89- v = frame .normal .copy ()
90- v .scale (z_adjustment_mm )
91- frame .point .translate (v )
92-
93- first_frame = frames [0 ].pop (0 )
94- _ = travel [0 ].pop (0 )
95-
96- cmds = construct_cmds (frames , travel )
129+ cmd_generator = construct_cmds (layers )
97130
98131 with RosClient (host = IP , port = 9090 ) as ros :
99132 abb = rrc .AbbClient (ros , "/rob1" )
@@ -102,8 +135,7 @@ def robot_program(
102135 abb .send (rrc .SetAcceleration (acc , ramp ))
103136 abb .send (rrc .SetMaxSpeed (override , max_tcp ))
104137
105- if not DRY_RUN :
106- abb .send_and_wait (get_stop_extrude ()) # reset signal
138+ abb .send (get_stop_extrude ()) # reset signal
107139
108140 abb .send (rrc .SetTool (TOOL ))
109141 abb .send (rrc .SetWorkObject (WOBJ ))
@@ -117,21 +149,13 @@ def robot_program(
117149 abb .send (rrc .Stop ())
118150
119151 # Move robot to start position
120- abb .send_and_wait (
152+ abb .send (
121153 rrc .MoveToJoints (
122154 robot_joints_start_position , external_axis_dummy , SPEED , rrc .Zone .FINE
123155 )
124156 )
125157
126- abb .send (rrc .MoveToFrame (first_frame , SPEED , rrc .Zone .FINE ))
127-
128- for lcmds in cmds :
129- abb .send_and_wait (lcmds .pop (0 ))
130- for c in lcmds :
131- abb .send (c )
132-
133- if not DRY_RUN :
134- abb .send_and_wait ((get_stop_extrude ()))
158+ process_with_batches (abb , cmd_generator )
135159
136160 # Move robot to end position
137161 abb .send (
@@ -144,24 +168,31 @@ def robot_program(
144168 abb .send_and_wait (rrc .PrintText ("Print finished." ))
145169
146170
171+ def load_json_from_arg1 ():
172+ filepath = sys .argv [1 ]
173+ data = json_load (filepath )
174+ frames = data ["frames" ]
175+ extrusion_factors = data ["travel" ]
176+
177+ # put all in one "layer"
178+ if isinstance (frames [0 ], compas .geometry .Frame ):
179+ if len (extrusion_factors ) == len (frames ) - 1 :
180+ # TODO: Fix me
181+ extrusion_factors .append (True )
182+
183+ frames = [frames ]
184+ extrusion_factors = [extrusion_factors ]
185+
186+ return [
187+ PrintLayer .from_frames_and_factors (f , ef )
188+ for f , ef in zip (frames , extrusion_factors , strict = True )
189+ ]
190+
191+
147192def main ():
148193 if len (sys .argv ) > 1 :
149- filepath = sys .argv [1 ]
150- data = json_load (filepath )
151- frames = data ["frames" ]
152- travel = data ["travel" ]
153-
154- # put all in one "layer"
155- if isinstance (frames [0 ], compas .geometry .Frame ):
156- frames = [frames ]
157- travel = [travel ]
158-
159- print (len (frames ))
160- print (len (travel ))
161- print (len (frames [0 ]))
162- print (len (travel [0 ]))
163-
164- robot_program (frames , travel )
194+ print_layers = load_json_from_arg1 ()
195+ robot_program (print_layers )
165196 else :
166197 print ("Usage: clay_3dp_print <filepath>" )
167198
0 commit comments