|
64 | 64 | #include "config_reader/config_reader.h"
|
65 | 65 | #include "visualization/visualization.h"
|
66 | 66 |
|
| 67 | +// TaijingTODO: filter out useless headers |
| 68 | +#include "cobot_msgs/CobotOdometryMsg.h" |
| 69 | +#include "cobot_msgs/CobotLocalizationMsg.h" |
| 70 | + |
67 | 71 | using Eigen::Affine2d;
|
68 | 72 | using Eigen::Affine2f;
|
69 | 73 | using Eigen::Matrix2d;
|
@@ -180,11 +184,9 @@ int debug_level_ = -1;
|
180 | 184 | // ROS publisher to publish visualization messages.
|
181 | 185 | ros::Publisher visualization_publisher_;
|
182 | 186 |
|
183 |
| -// ROS publisher to publish the latest robot localization w/ amrl_msgs. |
184 |
| -ros::Publisher localization_publisher_amrl_; |
185 |
| - |
186 |
| -// ROS publisher to publish the latest robot localization w/ ros geometry_msgs. |
187 |
| -ros::Publisher localization_publisher_ros_; |
| 187 | +// ROS publisher to publish the latest robot localization estimate to |
| 188 | +// Cobot/Localization |
| 189 | +ros::Publisher localization_publisher_; |
188 | 190 |
|
189 | 191 | // Parameters and settings for Non-Markov Localization.
|
190 | 192 | NonMarkovLocalization::LocalizationOptions localization_options_;
|
@@ -216,6 +218,20 @@ bool save_ltfs_ = false;
|
216 | 218 | // Suppress stdout.
|
217 | 219 | bool quiet_ = false;
|
218 | 220 |
|
| 221 | +// Inline helpers |
| 222 | +inline double GetTimeSec() |
| 223 | +{ |
| 224 | +#ifdef Apertos |
| 225 | + struct SystemTime time; |
| 226 | + GetSystemTime(&time); |
| 227 | + return ((double)time.seconds + time.useconds * (1.0E-6)); |
| 228 | +#else |
| 229 | + timespec ts; |
| 230 | + clock_gettime(CLOCK_REALTIME, &ts); |
| 231 | + return (double(ts.tv_sec) + double(ts.tv_nsec) * (1.0E-9)); |
| 232 | +#endif |
| 233 | +} |
| 234 | + |
219 | 235 | // Accept noise-free odometry, and apply noise by mimicing encoders of a
|
220 | 236 | // four=-wheel omnidirectional robot.
|
221 | 237 | void ApplyNoiseModel(
|
@@ -278,20 +294,25 @@ geometry_msgs::PoseStamped ConvertAMRLmsgToROSmsg(const amrl_msgs::Localization2
|
278 | 294 | void PublishLocation(
|
279 | 295 | const string &map_name, const float x, const float y, const float angle)
|
280 | 296 | {
|
281 |
| - localization_msg_.header.stamp = ros::Time::now(); |
| 297 | + cobot_msgs::CobotLocalizationMsg localization_msg_; |
| 298 | + localization_msg_.timeStamp = GetTimeSec(); |
282 | 299 | localization_msg_.map = map_name;
|
283 |
| - localization_msg_.pose.x = x; |
284 |
| - localization_msg_.pose.y = y; |
285 |
| - localization_msg_.pose.theta = angle; |
286 |
| - localization_publisher_amrl_.publish(localization_msg_); |
287 |
| - localization_publisher_ros_.publish(ConvertAMRLmsgToROSmsg(localization_msg_)); |
| 300 | + localization_msg_.x = x; |
| 301 | + localization_msg_.y = y; |
| 302 | + localization_msg_.angle = angle; |
| 303 | + localization_publisher_.publish(localization_msg_); |
288 | 304 | }
|
289 | 305 |
|
290 | 306 | void PublishLocation()
|
291 | 307 | {
|
292 |
| - Pose2Df pose = localization_->GetLatestPose(); |
293 |
| - const string map = localization_->GetCurrentMapName(); |
294 |
| - PublishLocation(map, pose.translation.x(), pose.translation.y(), pose.angle); |
| 308 | + Pose2Df latest_pose = localization_->GetLatestPose(); |
| 309 | + cobot_msgs::CobotLocalizationMsg localization_msg_; |
| 310 | + localization_msg_.timeStamp = GetTimeSec(); |
| 311 | + localization_msg_.map = localization_->GetCurrentMapName(); |
| 312 | + localization_msg_.x = latest_pose.translation.x(); |
| 313 | + localization_msg_.y = latest_pose.translation.y(); |
| 314 | + localization_msg_.angle = latest_pose.angle; |
| 315 | + localization_publisher_.publish(localization_msg_); |
295 | 316 | }
|
296 | 317 |
|
297 | 318 | void PublishTrace()
|
@@ -827,36 +848,34 @@ bool LoadOdometryMessage(const rosbag::MessageInstance &message,
|
827 | 848 | Vector2f *relative_location,
|
828 | 849 | float *relative_angle)
|
829 | 850 | {
|
830 |
| - nav_msgs::OdometryPtr odometry_message = |
831 |
| - message.instantiate<nav_msgs::Odometry>(); |
| 851 | + // [NOTE] The original enml repo uses nav_msgs::OdometryPtr |
| 852 | + // For cobot, we switch it to cobot_msgs::CobotOdometryMsgPtr |
| 853 | + cobot_msgs::CobotOdometryMsgPtr odometry_message = |
| 854 | + message.instantiate<cobot_msgs::CobotOdometryMsg>(); |
832 | 855 | const string topic_name = message.getTopic();
|
833 |
| - if (odometry_message != NULL && |
834 |
| - message.getTopic() == CONFIG_odom_topic) |
| 856 | + if (odometry_message != NULL && message.getTopic() == CONFIG_odom_topic) |
835 | 857 | {
|
836 |
| - if (debug_level_ > 2) |
| 858 | + if (false && debug_level_ > 2) |
837 | 859 | {
|
838 | 860 | printf("Odometry Msg, t:%.2f\n", message.getTime().toSec());
|
839 | 861 | fflush(stdout);
|
840 | 862 | }
|
841 |
| - const Vector2f odometry_message_location( |
842 |
| - odometry_message->pose.pose.position.x, |
843 |
| - odometry_message->pose.pose.position.y); |
844 |
| - *relative_location = kOdometryTranslationScale * (Rotation2Df(-odometry_angle) * |
845 |
| - (odometry_message_location - odometry_location)); |
846 |
| - const float odometry_message_angle = |
847 |
| - 2.0 * atan2(odometry_message->pose.pose.orientation.z, |
848 |
| - odometry_message->pose.pose.orientation.w); |
849 |
| - *relative_angle = kOdometryRotationScale * |
850 |
| - AngleDiff(odometry_message_angle, odometry_angle); |
851 | 863 | if (test_set_index_ >= 0 || statistical_test_index_ >= 0)
|
852 | 864 | {
|
853 |
| - relative_location->x() += |
854 |
| - rand_.Gaussian(0, odometry_additive_noise_ * relative_location->x()); |
855 |
| - relative_location->y() += |
856 |
| - rand_.Gaussian(0, odometry_additive_noise_ * relative_location->y()); |
857 |
| - (*relative_angle) += |
858 |
| - rand_.Gaussian(0, odometry_additive_noise_ * (*relative_angle)); |
| 865 | + odometry_message->dx += |
| 866 | + rand_.Gaussian(0, odometry_additive_noise_ * odometry_message->dx); |
| 867 | + odometry_message->dy += |
| 868 | + rand_.Gaussian(0, odometry_additive_noise_ * odometry_message->dy); |
| 869 | + odometry_message->dr += |
| 870 | + rand_.Gaussian(0, odometry_additive_noise_ * odometry_message->dr); |
859 | 871 | }
|
| 872 | + // Accumulate odometry to update robot pose estimate. |
| 873 | + const Vector2f delta(odometry_message->dx, odometry_message->dy); |
| 874 | + *relative_location = *relative_location + |
| 875 | + kOdometryTranslationScale * (Rotation2Df(*relative_angle) * |
| 876 | + delta); |
| 877 | + *relative_angle = *relative_angle + |
| 878 | + kOdometryRotationScale * odometry_message->dr; |
860 | 879 | return true;
|
861 | 880 | }
|
862 | 881 |
|
@@ -1515,23 +1534,43 @@ void StandardOdometryCallback(const nav_msgs::Odometry &last_odometry_msg,
|
1515 | 1534 | PublishLocation();
|
1516 | 1535 | }
|
1517 | 1536 |
|
1518 |
| -void OdometryCallback(const nav_msgs::Odometry &msg) |
| 1537 | +// void OdometryCallback(const nav_msgs::Odometry &msg) |
| 1538 | +// { |
| 1539 | +// static nav_msgs::Odometry last_msg_; |
| 1540 | +// static const float kMaxDist = 2.0; |
| 1541 | +// static Vector2f last_pos(0, 0); |
| 1542 | +// const Vector2f new_pos(msg.pose.pose.position.x, msg.pose.pose.position.y); |
| 1543 | +// if ((new_pos - last_pos).squaredNorm() < Sq(kMaxDist)) |
| 1544 | +// { |
| 1545 | +// StandardOdometryCallback(last_msg_, msg); |
| 1546 | +// } |
| 1547 | +// else if (debug_level_ > 0) |
| 1548 | +// { |
| 1549 | +// printf("\nWARNING: Large odometry change (%.3f) ignored!\n\n", |
| 1550 | +// (new_pos - last_pos).norm()); |
| 1551 | +// } |
| 1552 | +// last_pos = new_pos; |
| 1553 | +// last_msg_ = msg; |
| 1554 | +// } |
| 1555 | + |
| 1556 | +void OdometryCallback(const cobot_msgs::CobotOdometryMsg &odometry_msg) |
1519 | 1557 | {
|
1520 |
| - static nav_msgs::Odometry last_msg_; |
1521 |
| - static const float kMaxDist = 2.0; |
1522 |
| - static Vector2f last_pos(0, 0); |
1523 |
| - const Vector2f new_pos(msg.pose.pose.position.x, msg.pose.pose.position.y); |
1524 |
| - if ((new_pos - last_pos).squaredNorm() < Sq(kMaxDist)) |
| 1558 | + if ((Sq(odometry_msg.dx) + Sq(odometry_msg.dy)) > kSqMaxOdometryDeltaLoc || |
| 1559 | + fabs(odometry_msg.dr) > kMaxOdometryDeltaAngle) |
1525 | 1560 | {
|
1526 |
| - StandardOdometryCallback(last_msg_, msg); |
| 1561 | + printf("EnML Odometry out of bounds: x:%7.3f y:%7.3f a:%7.3f\u00b0\n", |
| 1562 | + odometry_msg.dx, odometry_msg.dy, DegToRad(odometry_msg.dr)); |
| 1563 | + return; |
1527 | 1564 | }
|
1528 |
| - else if (debug_level_ > 0) |
| 1565 | + if (debug_level_ > 2) |
1529 | 1566 | {
|
1530 |
| - printf("\nWARNING: Large odometry change (%.3f) ignored!\n\n", |
1531 |
| - (new_pos - last_pos).norm()); |
| 1567 | + printf("Odometry, t=%f\n", odometry_msg.header.stamp.toSec()); |
1532 | 1568 | }
|
1533 |
| - last_pos = new_pos; |
1534 |
| - last_msg_ = msg; |
| 1569 | + localization_->OdometryUpdate( |
| 1570 | + kOdometryTranslationScale * odometry_msg.dx, |
| 1571 | + kOdometryTranslationScale * odometry_msg.dy, |
| 1572 | + kOdometryRotationScale * odometry_msg.dr); |
| 1573 | + PublishLocation(); |
1535 | 1574 | }
|
1536 | 1575 |
|
1537 | 1576 | void LaserCallback(const sensor_msgs::LaserScan &laser_message)
|
@@ -2041,8 +2080,6 @@ void InitializeCallback(const amrl_msgs::Localization2DMsg &msg)
|
2041 | 2080 | }
|
2042 | 2081 | localization_->Initialize(
|
2043 | 2082 | Pose2Df(msg.pose.theta, Vector2f(msg.pose.x, msg.pose.y)), msg.map);
|
2044 |
| - localization_publisher_amrl_.publish(msg); |
2045 |
| - localization_publisher_ros_.publish(ConvertAMRLmsgToROSmsg(msg)); |
2046 | 2083 |
|
2047 | 2084 | if (false)
|
2048 | 2085 | {
|
@@ -2212,12 +2249,9 @@ int main(int argc, char **argv)
|
2212 | 2249 | ros::init(argc, argv, node_name, ros::init_options::NoSigintHandler);
|
2213 | 2250 | ros::NodeHandle ros_node;
|
2214 | 2251 | InitializeMessages();
|
2215 |
| - localization_publisher_amrl_ = |
2216 |
| - ros_node.advertise<amrl_msgs::Localization2DMsg>( |
2217 |
| - "localization", 1, true); |
2218 |
| - localization_publisher_ros_ = |
2219 |
| - ros_node.advertise<geometry_msgs::PoseStamped>( |
2220 |
| - "localization_ros", 1, true); |
| 2252 | + localization_publisher_ = |
| 2253 | + ros_node.advertise<cobot_msgs::CobotLocalizationMsg>( |
| 2254 | + "Cobot/Localization", 1, true); |
2221 | 2255 | {
|
2222 | 2256 | visualization_publisher_ =
|
2223 | 2257 | ros_node.advertise<amrl_msgs::VisualizationMsg>(
|
|
0 commit comments