Apollo 10.0
自动驾驶开放平台
odometry_parser.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
19
20namespace apollo {
21namespace cyber {
22
23void OdometryParser::imuCallback(std::shared_ptr<RosImuMsg> msg) {
24#ifdef ENABLE_ROS_MSG
25 imu_received_.store(true);
26 auto current_time = msg->header.stamp.sec + msg->header.stamp.nanosec / 1e9;
27 double dt = current_time - last_time_;
28 last_time_ = current_time;
29
30 F_(0, 3) = dt;
31 F_(1, 4) = dt;
32 F_(2, 5) = dt;
33
34 X_ = F_ * X_;
35 P_ = F_ * P_ * F_.transpose() + Q_;
36
37 X_(3) += msg->linear_acceleration.x * dt;
38 X_(4) += msg->linear_acceleration.y * dt;
39 X_(5) += msg->linear_acceleration.z * dt;
40
41 double euler_angles[3];
42
43 quaternion_[0] = msg->orientation.x;
44 quaternion_[1] = msg->orientation.y;
45 quaternion_[2] = msg->orientation.z;
46 quaternion_[3] = msg->orientation.w;
47
48 QuaternionToEuler(quaternion_, euler_angles);
49 auto roll = euler_angles[0];
50 auto pitch = euler_angles[1];
51 auto yaw = euler_angles[2];
52
53 X_(6) = roll;
54 X_(7) = pitch;
55 X_(8) = yaw;
56#endif
57}
58
59void OdometryParser::gpsCallback(std::shared_ptr<RosNavMsg> msg) {
60#ifdef ENABLE_ROS_MSG
61 gps_received_.store(true);
62 constexpr double DEG_TO_RAD_LOCAL = M_PI / 180.0;
63 Eigen::VectorXd Z(9);
64
65 double lon = msg->longitude;
66 double lat = msg->latitude;
67 double px = lon * DEG_TO_RAD_LOCAL;
68 double py = lat * DEG_TO_RAD_LOCAL;
69
70 if (utm_target_ == NULL) {
71 std::string proj4_text;
72 int zone = static_cast<int>(std::ceil((lon + 180.0) / 6.0));
73 proj4_text = "+proj=utm +zone=" + std::to_string(zone) +
74 " +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs";
75 utm_target_ = pj_init_plus(proj4_text.c_str());
76 }
77 pj_transform(wgs84pj_source_, utm_target_, 1, 1, &px, &py, NULL);
78
79 Z << px, py, msg->altitude, 0, 0, 0, 0, 0, 0;
80
81 Eigen::MatrixXd y = Z - H_ * X_;
82 Eigen::MatrixXd S = H_ * P_ * H_.transpose() + R_;
83 Eigen::MatrixXd K = P_ * H_.transpose() * S.inverse();
84 X_ = X_ + K * y;
85 P_ = (Eigen::MatrixXd::Identity(9, 9) - K * H_) * P_;
86#endif
87}
88
90#ifdef ENABLE_ROS_MSG
91 if (!gps_received_.load() || !imu_received_.load()) {
92 return;
93 }
94 RosOdomMsg odom_msg;
95 odom_msg.header.stamp = ros_node_->get_clock()->now();
96
97 odom_msg.pose.pose.position.x = X_(0);
98 odom_msg.pose.pose.position.y = X_(1);
99 odom_msg.pose.pose.position.z = X_(2);
100
101 odom_msg.pose.pose.orientation.x = quaternion_[0];
102 odom_msg.pose.pose.orientation.y = quaternion_[1];
103 odom_msg.pose.pose.orientation.z = quaternion_[2];
104 odom_msg.pose.pose.orientation.w = quaternion_[3];
105
106 odom_msg.twist.twist.linear.x = X_(3);
107 odom_msg.twist.twist.linear.y = X_(4);
108 odom_msg.twist.twist.linear.z = X_(5);
109
110 for (int i = 0; i < 6; ++i) {
111 for (int j = 0; j < 6; ++j) {
112 if (i < 3 && j < 3) {
113 odom_msg.pose.covariance[i * 6 + j] = P_(i, j);
114 } else if (i >= 3 && j >= 3) {
115 odom_msg.pose.covariance[i * 6 + j] = P_(i + 3, j + 3);
116 }
117 }
118 }
119
120 for (int i = 0; i < 3; ++i) {
121 for (int j = 0; j < 3; ++j) {
122 odom_msg.twist.covariance[i * 6 + j] = P_(i + 3, j + 3);
123 }
124 }
125
126 odom_pub_->publish(odom_msg);
127 imu_received_.store(false);
128 imu_received_.store(false);
129#endif
130}
131
134 // do nothing
135 return true;
136}
137
138} // namespace cyber
139} // namespace apollo
140
void gpsCallback(std::shared_ptr< RosNavMsg > msg)
virtual bool ConvertMsg(InputTypes< RosWrapMsgPtr > &, OutputTypes< OutputWrapMsgPtr > &)
convert the message between ros and apollo
void imuCallback(std::shared_ptr< RosImuMsg > msg)
void QuaternionToEuler(const double quaternion[4], double att[3])
class register implement
Definition arena_queue.h:37