hand_eye_calibration.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 import glob
3 import os
4 import unittest
5 
6 import ensenso_camera.ros2 as ros2py
7 
8 from ensenso_camera_test.helper import Pose
9 import ensenso_camera_test.ros2_testing as ros2py_testing
10 
11 CalibrateHandEye = ros2py.import_action("ensenso_camera_msgs", "CalibrateHandEye")
12 
13 DATA_SET_DIRECTORY = ros2py_testing.get_test_data_path("hand_eye_calibration/")
14 
15 ROBOT_BASE_FRAME = "robot_base"
16 ROBOT_WRIST_FRAME = "robot_wrist"
17 
18 # The indices of the data set frames that do not contain any visible patterns.
19 FRAMES_WITHOUT_PATTERNS = [2, 3]
20 
21 
22 class TestHandEyeCalibration(unittest.TestCase):
23  def setUp(self):
24  self.node = ros2py.create_node("test_hand_eye_calibration")
25  self.tf_broadcaster = ros2py_testing.create_tf_broadcaster(self.node)
26  self.calibration_client = ros2py.create_action_client(self.node, "calibrate_hand_eye", CalibrateHandEye)
27  success = ros2py.wait_for_server(
28  self.node, self.calibration_client, timeout_sec=ros2py_testing.TEST_TIMEOUT, exit=False
29  )
30  self.assertTrue(success, msg="Timeout reached for servers.")
31 
32  def assert_goal_response(self, response, goal):
33  result = response.get_result()
34  self.assertTrue(response.successful())
35  self.assertEqual(result.error.code, 0)
36  self.assertEqual(result.command, goal.command)
37 
38  def send_calibration_goal(self, goal, feedback_callback=None):
39  response = ros2py.send_action_goal(self.node, self.calibration_client, goal, feedback_callback)
40  self.assert_goal_response(response, goal)
41  return response
42 
43  def _broadcast_tf(self, pose, child_frame, parent_frame):
44  timestamp = self.node.get_clock().now()
45  ros2py_testing.send_tf_transform(self.tf_broadcaster, pose, timestamp, child_frame, parent_frame)
46 
48  response = self.send_calibration_goal(CalibrateHandEye.Goal(command=CalibrateHandEye.Goal.RESET))
49 
50  result = response.get_result()
51  self.assertEqual(result.command, CalibrateHandEye.Goal.RESET)
52  self.assertEqual(result.error_message, "")
53  self.assertEqual(result.error.code, 0)
54 
55  link_files = sorted(glob.glob(os.path.join(DATA_SET_DIRECTORY, "links/links*")))
56  self.assertEqual(len(link_files), 22)
57  for i, link_file in enumerate(link_files):
58  current_robot_pose = Pose.from_json(link_file)
59 
60  self._broadcast_tf(current_robot_pose, ROBOT_WRIST_FRAME, ROBOT_BASE_FRAME)
61  response = self.send_calibration_goal(CalibrateHandEye.Goal(command=CalibrateHandEye.Goal.CAPTURE_PATTERN))
62 
63  result = response.get_result()
64  self.assertEqual(result.command, CalibrateHandEye.Goal.CAPTURE_PATTERN)
65  self.assertEqual(result.error_message, "")
66  self.assertEqual(result.error.code, 0)
67 
68  if not result.found_pattern:
69  self.assertIn(i, FRAMES_WITHOUT_PATTERNS)
70  else:
71  self.assertEqual(result.pattern.thickness, 0.001)
72  self.assertEqual(result.pattern.grid_spacing, 0.01875)
73  self.assertEqual(result.pattern.grid_size_x, 7)
74  self.assertEqual(result.pattern.grid_size_y, 7)
75  self.assertEqual(len(result.pattern.left_points), 49)
76  self.assertEqual(len(result.pattern.right_points), 49)
77 
78  robot_pose = Pose.from_message(result.robot_pose)
79  self.assertTrue(robot_pose.equals(current_robot_pose))
80 
81  pattern_pose = Pose.from_message(result.pattern_pose)
82  self.assertTrue(all([x != 0 for x in pattern_pose.position]))
83 
84  self.last_feedback = None
85 
86  @ros2py_testing.feedback_callback
87  def on_feedback(feedback):
88  self.last_feedback = feedback
89 
90  goal = CalibrateHandEye.Goal(command=CalibrateHandEye.Goal.START_CALIBRATION)
91  response = self.send_calibration_goal(goal, feedback_callback=on_feedback)
92 
93  self.assertIsNotNone(self.last_feedback)
94  self.assertNotEqual(self.last_feedback.number_of_iterations, 0)
95  self.assertNotEqual(self.last_feedback.residual, 0)
96 
97  result = response.get_result()
98  self.assertEqual(result.command, CalibrateHandEye.Goal.START_CALIBRATION)
99  self.assertEqual(result.error_message, "")
100  self.assertEqual(result.error.code, 0)
101 
102  self.assertNotEqual(result.calibration_time, 0)
103  self.assertNotEqual(result.number_of_iterations, 0)
104  self.assertNotEqual(result.residual, 0)
105 
106  final_link = Pose.from_json(os.path.join(DATA_SET_DIRECTORY, "final_link.json")).inverse()
107  final_pattern_pose = Pose.from_json(os.path.join(DATA_SET_DIRECTORY, "final_pattern_pose.json"))
108  self.assertTrue(final_link.equals(Pose.from_message(result.link)))
109  self.assertTrue(final_pattern_pose.equals(Pose.from_message(result.pattern_pose)))
110 
111 
112 def main():
113  ros2py_testing.run_ros1_test("test_hand_eye_calibration", TestHandEyeCalibration)
114 
115 
116 if __name__ == "__main__":
117  main()
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration.setUp
def setUp(self)
Definition: hand_eye_calibration.py:23
ensenso_camera_test.helper
Definition: helper.py:1
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration.tf_broadcaster
tf_broadcaster
Definition: hand_eye_calibration.py:25
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration.assert_goal_response
def assert_goal_response(self, response, goal)
Definition: hand_eye_calibration.py:32
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration.send_calibration_goal
def send_calibration_goal(self, goal, feedback_callback=None)
Definition: hand_eye_calibration.py:38
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration.last_feedback
last_feedback
Definition: hand_eye_calibration.py:84
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration.calibration_client
calibration_client
Definition: hand_eye_calibration.py:26
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration.node
node
Definition: hand_eye_calibration.py:24
ensenso_camera_test.hand_eye_calibration.main
def main()
Definition: hand_eye_calibration.py:112
ensenso_camera_test.ros2_testing
Definition: ros2_testing.py:1
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration.test_hand_eye_calibration
def test_hand_eye_calibration(self)
Definition: hand_eye_calibration.py:47
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration
Definition: hand_eye_calibration.py:22
ensenso_camera_test.hand_eye_calibration.TestHandEyeCalibration._broadcast_tf
def _broadcast_tf(self, pose, child_frame, parent_frame)
Definition: hand_eye_calibration.py:43


ensenso_camera_test
Author(s): Ensenso
autogenerated on Wed Apr 2 2025 02:37:52