@@ -30,9 +30,10 @@ def test_get_root_name(self):
3030 self .assertEqual (root_name , self .robot_handler .get_root_name ())
3131 print ("✅ Root name assertion passed" )
3232
33- def test_subtree (self ):
33+ def test_subtrees (self ):
3434 subtrees = self .robot_handler .get_subtrees ()
3535
36+ self .assertIsNotNone (subtrees , "Subtrees should not be None" )
3637 self .assertIsInstance (subtrees , np .ndarray , "Subtrees should be a list" )
3738 self .assertEqual (len (subtrees ), 7 )
3839 self .assertEqual (subtrees [0 ]["tip_link_name" ], "wheel_front_left_link" )
@@ -126,22 +127,130 @@ def test_compute_valid_workspace(self):
126127
127128
128129 # should be None because there is no selected joint id inside the object
129- valid_workspace = self .robot_handler .get_valid_workspace (range = 1 , resolution = 0.3 , masses = None , checked_frames = None )
130+ valid_configurations = self .robot_handler .get_valid_workspace (range = 1 , resolution = 0.3 , masses = None , checked_frames = None )
130131
131- self .assertIsInstance (valid_workspace , np .ndarray , "Valid workspace should be a numpy array" )
132- self .assertEqual (len (valid_workspace ), 0 , "Valid workspace length should be zero if there is no selected joint id" )
132+ self .assertIsInstance (valid_configurations , np .ndarray , "Valid workspace should be a numpy array" )
133+ self .assertEqual (len (valid_configurations ), 0 , "Valid workspace length should be zero if there is no selected joint id" )
133134
134135 # modify selected joint id to test valid workspace
135136 self .robot_handler .subtrees [5 ]["selected_joint_id" ] = 25
136- valid_workspace = self .robot_handler .get_valid_workspace (range = 1 , resolution = 0.3 , masses = None , checked_frames = None )
137+ valid_configurations = self .robot_handler .get_valid_workspace (range = 1 , resolution = 0.3 , masses = None , checked_frames = None )
137138
138- self .assertEqual (len (valid_workspace ), len (verified_configs ), "Valid workspace length should match the verified configurations length" )
139+ self .assertEqual (len (valid_configurations ), len (verified_configs ), "Valid workspace length should match the verified configurations length" )
139140
140141 print ("✅ Compute valid workspace assertion passed" )
141142
143+ def test_compute_maximum_payloads (self ):
144+ self .robot_handler .subtrees [5 ]["selected_joint_id" ] = 25
145+ valid_configurations = self .robot_handler .get_valid_workspace (range = 1 , resolution = 0.3 , masses = None , checked_frames = None )
146+
147+ max_payload = self .robot_handler .find_max_payload_binary_search (config = valid_configurations [0 ], payload_min = 0.0 , payload_max = 10.0 , resolution = 0.01 )
148+
149+ self .assertIsInstance (max_payload , float , "Max payload should be a float" )
150+ self .assertGreaterEqual (max_payload , 0.0 , "Max payload should be non-negative" )
151+ self .assertLessEqual (max_payload , 10.0 , "Max payload should be within the specified range" )
152+
153+ max_payload = self .robot_handler .find_max_payload_binary_search (config = valid_configurations [0 ], payload_min = 0.0 , payload_max = 0 , resolution = 0.01 )
154+ self .assertEqual (max_payload , 0.0 , "Max payload should be zero if payload_max is zero" )
155+
156+ configs_with_payloads = self .robot_handler .compute_maximum_payloads (valid_configurations )
157+
158+ self .assertIsInstance (configs_with_payloads , np .ndarray , "Configurations with payloads should be a numpy array" )
159+ self .assertIn ("max_payload" , configs_with_payloads [0 ], "Each configuration should have a max_payload key" )
160+ self .assertIsInstance (configs_with_payloads [0 ]["max_payload" ], float , "Max payload should be a float" )
161+
162+ print ("✅ Compute maximum payloads assertion passed" )
163+
164+ def test_compute_forward_dynamics_aba_method (self ):
165+ zero_config = self .robot_handler .get_zero_configuration ()
166+ zero_velocity = self .robot_handler .get_zero_velocity ()
167+ zero_acceleration = self .robot_handler .get_zero_acceleration ()
168+ tau = np .zeros (self .robot_handler .model .nv )
169+
170+ computed_acceleration = self .robot_handler .compute_forward_dynamics_aba_method (q = zero_config , qdot = zero_velocity , tau = tau )
142171
143-
172+ self .assertIsNotNone (computed_acceleration , "Computed acceleration should not be None" )
173+ self .assertIsInstance (computed_acceleration , np .ndarray , "Computed acceleration should be a numpy array" )
144174
175+ print ("✅ Compute forward dynamics ABA method assertion passed" )
176+
177+ def test_compute_jacobian (self ):
178+ zero_config = self .robot_handler .get_zero_configuration ()
179+ jacobian = self .robot_handler .compute_jacobian (q = zero_config , frame_name = "arm_left_3_link" )
180+
181+ self .assertIsNotNone (jacobian , "Jacobian should not be None" )
182+ self .assertIsInstance (jacobian , np .ndarray , "Jacobian should be a numpy array" )
183+ self .assertEqual (jacobian .shape , (6 , self .robot_handler .model .nv ), "Jacobian shape should be (6, nv)" )
184+
185+ print ("✅ Compute Jacobian assertion passed" )
186+
187+ def test_verify_member_tree (self ):
188+ flag = self .robot_handler .verify_member_tree (tree_id = 5 , joint_id = 25 )
189+
190+ self .assertTrue (flag , "Joint ID should be in the specified tree ID" )
191+ self .assertIsInstance (flag , bool , "Flag should be a boolean" )
192+
193+ flag = self .robot_handler .verify_member_tree (tree_id = 5 , joint_id = 2 )
194+
195+ self .assertFalse (flag , "Joint ID should not be in the specified tree ID" )
196+
197+ print ("✅ Verify member tree assertion passed" )
198+
199+ def test_get_links_from_tree (self ):
200+ link = self .robot_handler .get_links_from_tree (joint_ids = 25 )
201+ links = self .robot_handler .get_links_from_tree (joint_ids = [25 , 26 , 24 ])
202+
203+ self .assertIsInstance (links , np .ndarray , "Links should be a numpy array" )
204+ self .assertEqual (len (links ), 3 , "There should be 3 links in the subtree" )
205+
206+ self .assertIn ("arm_right_7_link" , link , "Link should be in the subtree" )
207+ self .assertIsNotNone (link , "Link should not be None" )
208+ self .assertIsInstance (link , np .ndarray , "Link should be a numpy array" )
209+
210+ print ("✅ Get links from tree assertion passed" )
211+
212+ def test_get_maximum_torques (self ):
213+ #modify selected joint id to test valid workspace
214+ self .robot_handler .subtrees [5 ]["selected_joint_id" ] = 25
215+ valid_configurations = self .robot_handler .get_valid_workspace (range = 1 , resolution = 0.3 , masses = None , checked_frames = None )
216+
217+ max_torques = self .robot_handler .get_maximum_torques (valid_configurations )
218+
219+ self .assertIsNotNone (max_torques , "Max torques should not be None" )
220+ self .assertIsInstance (max_torques , np .ndarray , "Max torques should be a numpy array" )
221+
222+ # get selected subtrees only
223+ selected_subtrees = [subtree for subtree in self .robot_handler .get_subtrees () if subtree ["selected_joint_id" ] is not None ]
224+
225+ self .assertEqual (len (max_torques ), len (selected_subtrees ), "Max torques length should match the number of selected subtrees" )
226+ self .assertIn ("max_values" , max_torques [0 ], "Each max torque entry should have a max_values key" )
227+ self .assertEqual (max_torques [0 ]["tree_id" ], selected_subtrees [0 ]["tree_id" ], "Tree ID should match the selected subtree's tree ID" )
228+
229+ print ("✅ Get maximum torques assertion passed" )
230+
231+ def test_get_maximum_payloads (self ):
232+ #modify selected joint id to test valid workspace
233+ self .robot_handler .subtrees [5 ]["selected_joint_id" ] = 25
234+ valid_configurations = self .robot_handler .get_valid_workspace (range = 1 , resolution = 0.3 , masses = None , checked_frames = None )
235+ valid_configurations = self .robot_handler .compute_maximum_payloads (valid_configurations )
236+
237+ max_payloads = self .robot_handler .get_maximum_payloads (valid_configurations )
238+
239+ self .assertIsNotNone (max_payloads , "Max payloads should not be None" )
240+ self .assertIsInstance (max_payloads , np .ndarray , "Max payloads should be a numpy array" )
241+ self .assertGreater (len (max_payloads ), 0 , "Max payloads length should be greater than zero" )
242+ self .assertIn ("max_payload" , max_payloads [0 ], "Each max payload entry should have a max_payload key" )
243+ self .assertIsInstance (max_payloads [0 ]["max_payload" ], float , "Max payload values should be a float" )
244+
245+ # get selected subtrees only
246+ selected_subtrees = [subtree for subtree in self .robot_handler .get_subtrees () if subtree ["selected_joint_id" ] is not None ]
247+
248+ self .assertEqual (len (max_payloads ), len (selected_subtrees ), "Max payloads length should match the number of selected subtrees" )
249+ self .assertEqual (max_payloads [0 ]["tree_id" ], selected_subtrees [0 ]["tree_id" ], "Tree ID should match the selected subtree's tree ID" )
250+
251+ print ("✅ Get maximum payloads assertion passed" )
252+
253+
145254
146255
147256if __name__ == "__main__" :
0 commit comments