2 from __future__
import print_function
6 from copy
import deepcopy
12 from vision_msgs.msg
import Detection2D, Detection2DArray, ObjectHypothesisWithPose
13 from geometry_msgs.msg
import TransformStamped, Vector3Stamped, Vector3, Quaternion
14 from fiducial_msgs.msg
import FiducialTransformArray, FiducialTransform
15 from sensor_msgs.msg
import CameraInfo
16 from gazebo_msgs.msg
import ModelStates
17 from tf2_geometry_msgs
import do_transform_vector3
18 from tf.transformations
import quaternion_from_euler, euler_from_quaternion, quaternion_multiply, quaternion_conjugate
26 t = TransformStamped()
27 t.transform.rotation = quat
29 return do_transform_vector3(v, t).vector
33 invq = quaternion_conjugate([quat.x, quat.y, quat.z, quat.w])
34 return Quaternion(invq[0], invq[1], invq[2], invq[3])
38 q1 = [quat1.x, quat1.y, quat1.z, quat1.w]
39 q2 = [quat2.x, quat2.y, quat2.z, quat2.w]
40 out = quaternion_multiply(q1, q2)
41 return Quaternion(out[0], out[1], out[2], out[3])
45 """Represents the Fiducial Markers properties.""" 50 self.
rotation = Quaternion(rot.x, rot.y, rot.z, rot.w)
53 return "fiducial_%d (%f, %f, %f)" % (self.
id, self.translation.x, self.translation.y, self.translation.z)
57 """Publishes detected Fiducial Markers.""" 60 rospy.init_node(
'aruco_gazebo', anonymous=
False)
61 self.
buffer = tf2_ros.Buffer(rospy.Time(30))
72 "/fiducial_transforms", Detection2DArray, queue_size=5)
75 "/fiducial_transforms", FiducialTransformArray, queue_size=5)
84 "base_footprint", self.
camera_frame, rospy.Time.now(), rospy.Duration(5.0))
85 except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException):
86 rospy.logfatal(
"Could not get camera transform.")
87 rospy.signal_shutdown(
"Could not get camera transform.")
92 self.camera_info_sub.unregister()
94 fov_h = math.atan(msg.K[2] / msg.K[0]) * 2
95 fov_v = math.atan(msg.K[5] / msg.K[4]) * 2
96 self.
conefov = math.sqrt(fov_h * fov_h + fov_v * fov_v)
103 for i
in range(len(msg.name)):
104 if "aruco" in msg.name[i]:
105 fid_id = int(msg.name[i].split(
"-")[1].split(
"_")[0])
106 self.candidates.append(
107 FiducialState(fid_id, msg.pose[i].position, msg.pose[i].orientation))
108 elif "magni" in msg.name[i]:
112 fidarray = FiducialTransformArray()
113 fidarray.header.stamp = rospy.Time.now()
114 vis = Detection2DArray()
115 vis.header.stamp = rospy.Time.now()
117 for fid
in fid_data_array:
120 oh = ObjectHypothesisWithPose()
122 oh.pose.pose.position.x = fid.translation.x
123 oh.pose.pose.position.y = fid.translation.y
124 oh.pose.pose.position.z = fid.translation.z
125 oh.pose.pose.orientation.w = fid.rotation.w
126 oh.pose.pose.orientation.x = fid.rotation.x
127 oh.pose.pose.orientation.y = fid.rotation.y
128 oh.pose.pose.orientation.z = fid.rotation.z
129 oh.score = math.exp(-2 * OBJECT_ERROR)
131 obj.results.append(oh)
132 vis.detections.append(obj)
134 data = FiducialTransform()
135 data.fiducial_id = fid.id
136 data.transform.translation = fid.translation
137 data.transform.rotation = fid.rotation
138 data.image_error = IMAGE_ERROR
139 data.object_error = OBJECT_ERROR
140 data.fiducial_area = FIDUCIAL_AREA
142 fidarray.transforms.append(data)
145 self.fid_pub.publish(vis)
147 self.fid_pub.publish(fidarray)
150 t = TransformStamped()
151 t.child_frame_id =
"fiducial_" + str(id)
152 t.header.frame_id =
"raspicam" 153 t.header.stamp = rospy.Time.now()
155 t.transform.translation.x = x
156 t.transform.translation.y = y
157 t.transform.translation.z = z
158 t.transform.rotation = rotation
160 self.broadcaster.sendTransform(t)
166 rospy.loginfo(
"Detected 0 markers")
170 rospy.logwarn(
"Robot pose not received!")
174 stat_cpos = self.static_cam_pose.transform.translation
175 stat_crot = self.static_cam_pose.transform.rotation
176 mag_pos = self.magnipose.position
177 mag_rot = self.magnipose.orientation
189 for fid
in fiducials:
190 x = fid.translation.x - cpos.x
191 y = fid.translation.y - cpos.y
192 z = fid.translation.z - cpos.z
195 vlen = math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
198 if vlen > 7.0
or vlen < 0.0:
202 if v.z / vlen < math.cos(self.
conefov * 0.5):
206 dist = FIDUCIAL_LEN * 0.65
214 src = np.array([[p[0].x, p[0].y, p[0].z], [p[1].x, p[1].y, p[1].z], [
215 p[2].x, p[2].y, p[2].z], [p[3].x, p[3].y, p[3].z]])
216 rvec = np.array([0, 0, 0], np.float)
217 tvec = np.array([0, 0, 0], np.float)
218 projMatrix = np.array([[self.cam_data.K[0], 0, self.cam_data.K[2]], [
219 0, self.cam_data.K[4], self.cam_data.K[5]], [0, 0, 1]])
220 image_points = cv2.projectPoints(
221 src, rvec, tvec, projMatrix,
None)[0]
225 for d
in image_points:
228 if dx < 0
or dy < 0
or self.cam_data.height < dy
or self.cam_data.width < dx:
235 (roll, pitch, yaw) = euler_from_quaternion(
236 [fid.rotation.x, fid.rotation.y, fid.rotation.z, fid.rotation.w])
237 rfinal = quaternion_from_euler(roll, pitch, yaw - math.radians(90))
238 r = Quaternion(rfinal[0], rfinal[1], rfinal[2], rfinal[3])
240 finalists.append(fid)
242 self.
transmit_TF(fid.id, v.x, v.y, v.z, fid.rotation)
244 rospy.loginfo(
"Detected %d markers" % len(finalists))
248 if __name__ ==
'__main__':
249 IMAGE_ERROR = rospy.get_param(
"~image_error", 0.001)
250 OBJECT_ERROR = rospy.get_param(
"~object_error", 0.001)
251 FIDUCIAL_AREA = rospy.get_param(
"~fiducial_area", 0.0196)
252 FIDUCIAL_LEN = rospy.get_param(
"~fiducial_len", 0.14)
253 VIS_MSGS = rospy.get_param(
"~vis_msgs",
False)
257 rate = rospy.Rate(ar.framerate)
258 while not rospy.is_shutdown():
262 except rospy.ROSInterruptException:
263 print(
"Script interrupted", file=sys.stderr)
def camera_info(self, msg)
def quaternionInverse(quat)
def publish_markers(self, fid_data_array)
def gazebo_poses(self, msg)
def quaternionMultiply(quat1, quat2)
def __init__(self, fid_id, pos, rot)
def transformVector(x, y, z, quat)
def transmit_TF(self, id, x, y, z, rotation)