|
31 | 31 |
|
32 | 32 | from geometry_msgs.msg import (PointStamped, PoseStamped, |
33 | 33 | PoseWithCovarianceStamped, Vector3Stamped) |
| 34 | +import numpy as np |
34 | 35 | import PyKDL |
35 | 36 | import tf2_ros |
36 | 37 |
|
@@ -62,6 +63,95 @@ def transform_to_kdl(t): |
62 | 63 | t.transform.translation.y, |
63 | 64 | t.transform.translation.z)) |
64 | 65 |
|
| 66 | +def transform_covariance(cov_in, transform): |
| 67 | + # Converting the Quaternion to a Rotation Matrix first |
| 68 | + # Taken from: https://automaticaddison.com/how-to-convert-a-quaternion-to-a-rotation-matrix/ |
| 69 | + q0 = transform.transform.rotation.w |
| 70 | + q1 = transform.transform.rotation.x |
| 71 | + q2 = transform.transform.rotation.y |
| 72 | + q3 = transform.transform.rotation.z |
| 73 | + |
| 74 | + # First row of the rotation matrix |
| 75 | + r00 = 2 * (q0 * q0 + q1 * q1) - 1 |
| 76 | + r01 = 2 * (q1 * q2 - q0 * q3) |
| 77 | + r02 = 2 * (q1 * q3 + q0 * q2) |
| 78 | + |
| 79 | + # Second row of the rotation matrix |
| 80 | + r10 = 2 * (q1 * q2 + q0 * q3) |
| 81 | + r11 = 2 * (q0 * q0 + q2 * q2) - 1 |
| 82 | + r12 = 2 * (q2 * q3 - q0 * q1) |
| 83 | + |
| 84 | + # Third row of the rotation matrix |
| 85 | + r20 = 2 * (q1 * q3 - q0 * q2) |
| 86 | + r21 = 2 * (q2 * q3 + q0 * q1) |
| 87 | + r22 = 2 * (q0 * q0 + q3 * q3) - 1 |
| 88 | + |
| 89 | + # Code reference: https://github.com/ros2/geometry2/pull/430 |
| 90 | + # Mathematical Reference: |
| 91 | + # A. L. Garcia, “Linear Transformations of Random Vectors,” in Probability, |
| 92 | + # Statistics, and Random Processes For Electrical Engineering, 3rd ed., |
| 93 | + # Pearson Prentice Hall, 2008, pp. 320–322. |
| 94 | + |
| 95 | + R = np.array([[r00, r01, r02], |
| 96 | + [r10, r11, r12], |
| 97 | + [r20, r21, r22]]) |
| 98 | + |
| 99 | + R_transpose = np.transpose(R) |
| 100 | + |
| 101 | + cov_11 = np.array([cov_in[:3], cov_in[6:9], cov_in[12:15]]) |
| 102 | + cov_12 = np.array([cov_in[3:6], cov_in[9:12], cov_in[15:18]]) |
| 103 | + cov_21 = np.array([cov_in[18:21], cov_in[24:27], cov_in[30:33]]) |
| 104 | + cov_22 = np.array([cov_in[21:24], cov_in[27:30], cov_in[33:]]) |
| 105 | + |
| 106 | + # And we perform the transform |
| 107 | + result_11 = R @ cov_11 @ R_transpose |
| 108 | + result_12 = R @ cov_12 @ R_transpose |
| 109 | + result_21 = R @ cov_21 @ R_transpose |
| 110 | + result_22 = R @ cov_22 @ R_transpose |
| 111 | + |
| 112 | + cov_out = PoseWithCovarianceStamped() |
| 113 | + |
| 114 | + cov_out.pose.covariance[0] = result_11[0][0] |
| 115 | + cov_out.pose.covariance[1] = result_11[0][1] |
| 116 | + cov_out.pose.covariance[2] = result_11[0][2] |
| 117 | + cov_out.pose.covariance[6] = result_11[1][0] |
| 118 | + cov_out.pose.covariance[7] = result_11[1][1] |
| 119 | + cov_out.pose.covariance[8] = result_11[1][2] |
| 120 | + cov_out.pose.covariance[12] = result_11[2][0] |
| 121 | + cov_out.pose.covariance[13] = result_11[2][1] |
| 122 | + cov_out.pose.covariance[14] = result_11[2][2] |
| 123 | + |
| 124 | + cov_out.pose.covariance[3] = result_12[0][0] |
| 125 | + cov_out.pose.covariance[4] = result_12[0][1] |
| 126 | + cov_out.pose.covariance[5] = result_12[0][2] |
| 127 | + cov_out.pose.covariance[9] = result_12[1][0] |
| 128 | + cov_out.pose.covariance[10] = result_12[1][1] |
| 129 | + cov_out.pose.covariance[11] = result_12[1][2] |
| 130 | + cov_out.pose.covariance[15] = result_12[2][0] |
| 131 | + cov_out.pose.covariance[16] = result_12[2][1] |
| 132 | + cov_out.pose.covariance[17] = result_12[2][2] |
| 133 | + |
| 134 | + cov_out.pose.covariance[18] = result_21[0][0] |
| 135 | + cov_out.pose.covariance[19] = result_21[0][1] |
| 136 | + cov_out.pose.covariance[20] = result_21[0][2] |
| 137 | + cov_out.pose.covariance[24] = result_21[1][0] |
| 138 | + cov_out.pose.covariance[25] = result_21[1][1] |
| 139 | + cov_out.pose.covariance[26] = result_21[1][2] |
| 140 | + cov_out.pose.covariance[30] = result_21[2][0] |
| 141 | + cov_out.pose.covariance[31] = result_21[2][1] |
| 142 | + cov_out.pose.covariance[32] = result_21[2][2] |
| 143 | + |
| 144 | + cov_out.pose.covariance[21] = result_22[0][0] |
| 145 | + cov_out.pose.covariance[22] = result_22[0][1] |
| 146 | + cov_out.pose.covariance[23] = result_22[0][2] |
| 147 | + cov_out.pose.covariance[27] = result_22[1][0] |
| 148 | + cov_out.pose.covariance[28] = result_22[1][1] |
| 149 | + cov_out.pose.covariance[29] = result_22[1][2] |
| 150 | + cov_out.pose.covariance[33] = result_22[2][0] |
| 151 | + cov_out.pose.covariance[34] = result_22[2][1] |
| 152 | + cov_out.pose.covariance[35] = result_22[2][2] |
| 153 | + |
| 154 | + return cov_out.pose.covariance |
65 | 155 |
|
66 | 156 | # PointStamped |
67 | 157 | def do_transform_point(point, transform): |
@@ -140,7 +230,7 @@ def do_transform_pose_with_covariance_stamped(pose, transform): |
140 | 230 | res.pose.pose.orientation.y, |
141 | 231 | res.pose.pose.orientation.z, |
142 | 232 | res.pose.pose.orientation.w) = f.M.GetQuaternion() |
143 | | - res.pose.covariance = pose.pose.covariance |
| 233 | + res.pose.covariance = transform_covariance(pose.pose.covariance, transform) |
144 | 234 | res.header = transform.header |
145 | 235 | return res |
146 | 236 |
|
|
0 commit comments