10 #include <mrpt/core/lock_helper.h> 11 #include <mrpt/obs/CObservation3DRangeScan.h> 12 #include <mrpt/obs/CObservationIMU.h> 13 #include <mrpt/obs/CObservationPointCloud.h> 14 #include <mrpt/system/CTicTac.h> 15 #include <mrpt/system/filesystem.h> 16 #include <mrpt/system/os.h> 19 #if PACKAGE_ROS_VERSION == 1 23 #include <geometry_msgs/Polygon.h> 24 #include <geometry_msgs/PoseArray.h> 25 #include <geometry_msgs/PoseWithCovarianceStamped.h> 26 #include <mrpt/ros1bridge/image.h> 27 #include <mrpt/ros1bridge/imu.h> 28 #include <mrpt/ros1bridge/laser_scan.h> 29 #include <mrpt/ros1bridge/map.h> 30 #include <mrpt/ros1bridge/point_cloud2.h> 31 #include <mrpt/ros1bridge/pose.h> 32 #include <nav_msgs/GetMap.h> 33 #include <nav_msgs/MapMetaData.h> 34 #include <nav_msgs/Odometry.h> 35 #include <sensor_msgs/Image.h> 36 #include <sensor_msgs/Imu.h> 37 #include <sensor_msgs/LaserScan.h> 38 #include <sensor_msgs/PointCloud2.h> 48 #include <mrpt/ros2bridge/image.h> 49 #include <mrpt/ros2bridge/imu.h> 50 #include <mrpt/ros2bridge/laser_scan.h> 51 #include <mrpt/ros2bridge/map.h> 52 #include <mrpt/ros2bridge/point_cloud2.h> 53 #include <mrpt/ros2bridge/pose.h> 55 #include <nav_msgs/msg/map_meta_data.hpp> 56 #include <nav_msgs/msg/odometry.hpp> 57 #include <nav_msgs/srv/get_map.hpp> 58 #include <sensor_msgs/msg/image.hpp> 59 #include <sensor_msgs/msg/imu.hpp> 60 #include <sensor_msgs/msg/laser_scan.hpp> 61 #include <sensor_msgs/msg/point_cloud2.hpp> 64 #if defined(MVSIM_HAS_TF2_GEOMETRY_MSGS_HPP) 65 #include <tf2_geometry_msgs/tf2_geometry_msgs.hpp> 81 #if PACKAGE_ROS_VERSION == 1 82 namespace mrpt2ros = mrpt::ros1bridge;
84 namespace mrpt2ros = mrpt::ros2bridge;
87 #if PACKAGE_ROS_VERSION == 1 88 #define ROS12_INFO(...) ROS_INFO(__VA_ARGS__) 89 #define ROS12_ERROR(...) ROS_ERROR(__VA_ARGS__) 91 #define ROS12_INFO(...) RCLCPP_INFO(n_->get_logger(), __VA_ARGS__) 92 #define ROS12_ERROR(...) RCLCPP_ERROR(n_->get_logger(), __VA_ARGS__) 99 #if PACKAGE_ROS_VERSION == 1 106 #if PACKAGE_ROS_VERSION == 2 107 clock_ = n_->get_clock();
108 ts_.attachClock(clock_);
111 n_->declare_parameter<std::string>(
"world_file",
"default.world.xml");
112 n_->declare_parameter<
double>(
"simul_rate", 100);
113 n_->declare_parameter<
double>(
"base_watchdog_timeout", 0.2);
116 base_watchdog_timeout_ = std::chrono::milliseconds(
117 1000 * n_->get_parameter_or(
"base_watchdog_timeout", t, 0.2));
121 n_->declare_parameter<
double>(
"realtime_factor", realtime_factor_);
123 gui_refresh_period_ms_ = n_->declare_parameter<
double>(
124 "gui_refresh_period", gui_refresh_period_ms_);
126 headless_ = n_->declare_parameter<
bool>(
"headless", headless_);
128 period_ms_publish_tf_ = n_->declare_parameter<
double>(
129 "period_ms_publish_tf", period_ms_publish_tf_);
131 do_fake_localization_ = n_->declare_parameter<
bool>(
132 "do_fake_localization", do_fake_localization_);
134 publisher_history_len_ = n_->declare_parameter<
int>(
135 "publisher_history_len", publisher_history_len_);
138 if (
true == n_->get_parameter_or(
"use_sim_time",
false))
141 "At present, MVSIM can only work with use_sim_time=false");
146 thread_params_.obj =
this;
151 #if PACKAGE_ROS_VERSION == 1 154 pub_map_ros_ = n_.advertise<nav_msgs::OccupancyGrid>(
155 "simul_map", 1 ,
true );
156 pub_map_metadata_ = n_.advertise<nav_msgs::MapMetaData>(
157 "simul_map_metadata", 1 ,
true );
159 rclcpp::QoS qosLatched(rclcpp::KeepLast(10));
160 qosLatched.durability(
161 rmw_qos_durability_policy_t::RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL);
163 pub_map_ros_ = n_->create_publisher<nav_msgs::msg::OccupancyGrid>(
164 "simul_map", qosLatched);
165 pub_map_metadata_ = n_->create_publisher<nav_msgs::msg::MapMetaData>(
166 "simul_map_metadata", qosLatched);
169 #if PACKAGE_ROS_VERSION == 1 171 base_last_cmd_.fromSec(0.0);
174 base_last_cmd_ = rclcpp::Time(0);
178 #if PACKAGE_ROS_VERSION == 1 180 if (!localn_.getParam(
"base_watchdog_timeout", t)) t = 0.2;
181 base_watchdog_timeout_.fromSec(t);
182 localn_.param(
"realtime_factor", realtime_factor_, 1.0);
184 "gui_refresh_period", gui_refresh_period_ms_, gui_refresh_period_ms_);
185 localn_.param(
"headless", headless_, headless_);
187 "period_ms_publish_tf", period_ms_publish_tf_, period_ms_publish_tf_);
189 "do_fake_localization", do_fake_localization_, do_fake_localization_);
194 if (
true == localn_.param(
"use_sim_time",
false))
197 "At present, MVSIM can only work with use_sim_time=false");
201 mvsim_world_->registerCallbackOnObservation(
204 const mrpt::obs::CObservation::Ptr& obs) {
207 mrpt::system::CTimeLoggerEntry tle(
208 profiler_,
"lambda_onNewObservation");
211 const mrpt::obs::CObservation::Ptr obsCopy = obs;
212 auto fut = ros_publisher_workers_.enqueue([
this, vehPtr,
216 onNewObservation(*vehPtr, obsCopy);
218 catch (
const std::exception& e)
221 "[MVSimNode] Error processing observation with label " 223 obsCopy ? obsCopy->sensorLabel.c_str() :
"(nullptr)",
232 ROS12_INFO(
"[MVSimNode] launch_mvsim_server()");
240 if (argPort.isSet())
server->listenningPort(argPort.getValue());
242 mrpt::typemeta::TEnumType<mrpt::system::VerbosityLevel>::name2value(
243 argVerbosity.getValue()));
251 ROS12_INFO(
"[MVSimNode] Loading world file: %s", world_xml_file.c_str());
253 ASSERT_FILE_EXISTS_(world_xml_file);
257 mvsim_world_->load_from_XML(fil_xml.data(), world_xml_file);
259 ROS12_INFO(
"[MVSimNode] World file load done.");
286 std::cout <<
"[MVSimNode::terminateSimulation] All done." << std::endl;
289 #if PACKAGE_ROS_VERSION == 1 294 void MVSimNode::configCallback(
295 mvsim::mvsimNodeConfig& config, [[maybe_unused]] uint32_t level)
300 ROS_INFO(
"MVSimNode::configCallback() called.");
310 using namespace mvsim;
311 using namespace std::string_literals;
326 if (incr_time < mvsim_world_->get_simul_timestep())
return;
346 std::string txt2gui_tmp;
364 txt2gui_tmp += mrpt::format(
365 "Selected vehicle: %u/%u\n",
367 static_cast<unsigned>(vehs.size()));
371 auto it_veh = vehs.begin();
375 txt2gui_tmp +=
"gt. vel: "s +
376 it_veh->second->getVelocityLocal().asString();
381 it_veh->second->getVelocityLocalOdoEstimate().asString();
387 it_veh->second->getControllerInterface();
412 using namespace mvsim;
429 std::this_thread::sleep_for(
434 obj->
mvsim_world_->internalGraphicsLoopTasksForSimulation();
436 std::this_thread::sleep_for(
437 std::chrono::microseconds(static_cast<size_t>(
442 std::this_thread::sleep_for(
447 catch (
const std::exception& e)
449 std::cerr <<
"[MVSimNode::thread_update_GUI] Exception:\n" << e.what();
466 dynamic_cast<mvsim::OccupancyGridMap*>(&obj);
472 if (cachedGrid != grid)
475 mrpt2ros::toROS(grid->getOccGrid(), ros_map);
478 #if PACKAGE_ROS_VERSION == 1 479 static size_t loop_count = 0;
481 ros_map.header.seq = loop_count++;
483 ros_map.header.stamp =
clock_->now();
484 ros_map.header.frame_id =
"map";
487 #if PACKAGE_ROS_VERSION == 1 494 pubMap.publish(ros_map);
495 pubMapMeta.publish(ros_map.info);
504 #if PACKAGE_ROS_VERSION == 2 507 static mrpt::system::CTicTac lastMapPublished;
508 if (lastMapPublished.Tac() > 2.0)
514 lastMapPublished.Tic();
527 for (
auto it = vehs.begin(); it != vehs.end(); ++it, ++idx)
540 #if PACKAGE_ROS_VERSION == 1 547 const std::string& frame_id,
const std::string& child_frame_id,
549 #
if PACKAGE_ROS_VERSION == 1
552 const rclcpp::Time& stamp
557 tx.header.frame_id = frame_id;
558 tx.child_frame_id = child_frame_id;
559 tx.header.stamp = stamp;
569 #if PACKAGE_ROS_VERSION == 1 574 using std::placeholders::_1;
576 pubsubs.
sub_cmd_vel =
n_->create_subscription<geometry_msgs::msg::Twist>(
578 [
this, veh](
const geometry_msgs::msg::Twist::ConstSharedPtr& msg) {
583 #if PACKAGE_ROS_VERSION == 1 585 pubsubs.
pub_odom =
n_.advertise<nav_msgs::Odometry>(
593 pubsubs.
pub_odom =
n_->create_publisher<nav_msgs::msg::Odometry>(
602 #if PACKAGE_ROS_VERSION == 1 604 n_.advertise<visualization_msgs::MarkerArray>(
605 vehVarName(
"chassis_markers", *veh), 5,
true );
607 rclcpp::QoS qosLatched(rclcpp::KeepLast(5));
608 qosLatched.durability(rmw_qos_durability_policy_t::
609 RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL);
612 n_->create_publisher<visualization_msgs::msg::MarkerArray>(
613 vehVarName(
"chassis_markers", *veh), qosLatched);
622 auto& chassis_shape_msg = msg_shapes.markers[0];
624 chassis_shape_msg.pose =
625 mrpt2ros::toROS_Pose(mrpt::poses::CPose3D::Identity());
627 #if PACKAGE_ROS_VERSION == 1 628 chassis_shape_msg.action = visualization_msgs::Marker::MODIFY;
629 chassis_shape_msg.type = visualization_msgs::Marker::LINE_STRIP;
631 chassis_shape_msg.action = visualization_msgs::msg::Marker::MODIFY;
632 chassis_shape_msg.type = visualization_msgs::msg::Marker::LINE_STRIP;
635 chassis_shape_msg.header.frame_id =
vehVarName(
"base_link", *veh);
636 chassis_shape_msg.ns =
"mvsim.chassis_shape";
638 chassis_shape_msg.scale.x = 0.05;
639 chassis_shape_msg.scale.y = 0.05;
640 chassis_shape_msg.scale.z = 0.02;
641 chassis_shape_msg.points.resize(poly.size() + 1);
642 for (
size_t i = 0; i <= poly.size(); i++)
644 size_t k = i % poly.size();
645 chassis_shape_msg.points[i].x = poly[k].x;
646 chassis_shape_msg.points[i].y = poly[k].y;
647 chassis_shape_msg.points[i].z = 0;
649 chassis_shape_msg.color.a = 0.9;
650 chassis_shape_msg.color.r = 0.9;
651 chassis_shape_msg.color.g = 0.9;
652 chassis_shape_msg.color.b = 0.9;
653 chassis_shape_msg.frame_locked =
true;
658 auto& wheel_shape_msg = msg_shapes.markers[1 + i];
664 wheel_shape_msg = msg_shapes.markers[0];
666 chassis_shape_msg.ns = mrpt::format(
667 "mvsim.chassis_shape.wheel%u", static_cast<unsigned int>(i));
668 wheel_shape_msg.points.resize(5);
669 wheel_shape_msg.points[0].x = lx;
670 wheel_shape_msg.points[0].y = ly;
671 wheel_shape_msg.points[0].z = 0;
672 wheel_shape_msg.points[1].x = lx;
673 wheel_shape_msg.points[1].y = -ly;
674 wheel_shape_msg.points[1].z = 0;
675 wheel_shape_msg.points[2].x = -lx;
676 wheel_shape_msg.points[2].y = -ly;
677 wheel_shape_msg.points[2].z = 0;
678 wheel_shape_msg.points[3].x = -lx;
679 wheel_shape_msg.points[3].y = ly;
680 wheel_shape_msg.points[3].z = 0;
681 wheel_shape_msg.points[4] = wheel_shape_msg.points[0];
683 wheel_shape_msg.color.r = w.
color.R / 255.0f;
684 wheel_shape_msg.color.g = w.
color.G / 255.0f;
685 wheel_shape_msg.color.b = w.
color.B / 255.0f;
686 wheel_shape_msg.color.a = 1.0f;
689 wheel_shape_msg.pose = mrpt2ros::toROS_Pose(w.
pose());
693 #if PACKAGE_ROS_VERSION == 1 702 #if PACKAGE_ROS_VERSION == 1 704 vehVarName(
"chassis_polygon", *veh), 1,
true );
706 geometry_msgs::Polygon poly_msg;
708 rclcpp::QoS qosLatched(rclcpp::KeepLast(1));
709 qosLatched.durability(rmw_qos_durability_policy_t::
710 RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL);
713 n_->create_publisher<geometry_msgs::msg::Polygon>(
714 vehVarName(
"chassis_polygon", *veh), qosLatched);
716 geometry_msgs::msg::Polygon poly_msg;
720 poly_msg.points.resize(poly.size());
721 for (
size_t i = 0; i < poly.size(); i++)
723 poly_msg.points[i].x = poly[i].x;
724 poly_msg.points[i].y = poly[i].y;
725 poly_msg.points[i].z = 0;
727 #if PACKAGE_ROS_VERSION == 1 736 #if PACKAGE_ROS_VERSION == 1 739 n_.advertise<geometry_msgs::PoseWithCovarianceStamped>(
747 n_->create_publisher<geometry_msgs::msg::PoseWithCovarianceStamped>(
751 n_->create_publisher<geometry_msgs::msg::PoseArray>(
763 #
if PACKAGE_ROS_VERSION == 1
764 const geometry_msgs::Twist::ConstPtr& cmd,
766 const geometry_msgs::msg::Twist::ConstSharedPtr& cmd,
773 {cmd->linear.x, cmd->linear.y, cmd->angular.z});
775 if (!ctrlAcceptTwist)
777 #if PACKAGE_ROS_VERSION == 1 780 "*Warning* Vehicle's controller ['%s'] refuses Twist commands!",
781 veh->getName().c_str());
783 RCLCPP_WARN_THROTTLE(
784 n_->get_logger(), *
n_->get_clock(), 1.0,
785 "*Warning* Vehicle's controller ['%s'] refuses Twist commands!",
786 veh->getName().c_str());
796 using namespace mvsim;
800 #if PACKAGE_ROS_VERSION == 1 803 if (!rclcpp::ok())
return;
808 #if PACKAGE_ROS_VERSION == 1 817 #if PACKAGE_ROS_VERSION == 2 832 for (
auto it = vehs.begin(); it != vehs.end(); ++it, ++i)
836 const std::string sOdomName =
vehVarName(
"odom", *veh);
837 const std::string sBaseLinkFrame =
vehVarName(
"base_link", *veh);
841 const mrpt::math::TPose3D& gh_veh_pose = veh->getPose();
843 const auto& gh_veh_vel = veh->getTwist();
846 #if PACKAGE_ROS_VERSION == 1 847 nav_msgs::Odometry gtOdoMsg;
849 nav_msgs::msg::Odometry gtOdoMsg;
852 gtOdoMsg.pose.pose = mrpt2ros::toROS_Pose(gh_veh_pose);
854 gtOdoMsg.twist.twist.linear.x = gh_veh_vel.vx;
855 gtOdoMsg.twist.twist.linear.y = gh_veh_vel.vy;
856 gtOdoMsg.twist.twist.linear.z = 0;
857 gtOdoMsg.twist.twist.angular.z = gh_veh_vel.omega;
859 gtOdoMsg.header.stamp =
myNow();
860 gtOdoMsg.header.frame_id = sOdomName;
861 gtOdoMsg.child_frame_id = sBaseLinkFrame;
863 #if PACKAGE_ROS_VERSION == 1 870 #if PACKAGE_ROS_VERSION == 1 871 geometry_msgs::PoseWithCovarianceStamped currentPos;
872 geometry_msgs::PoseArray particleCloud;
874 geometry_msgs::msg::PoseWithCovarianceStamped currentPos;
875 geometry_msgs::msg::PoseArray particleCloud;
880 particleCloud.header.stamp =
myNow();
881 particleCloud.header.frame_id =
"map";
882 particleCloud.poses.resize(1);
883 particleCloud.poses[0] = gtOdoMsg.pose.pose;
884 #if PACKAGE_ROS_VERSION == 1 895 currentPos.header = gtOdoMsg.header;
896 currentPos.pose.pose = gtOdoMsg.pose.pose;
897 #if PACKAGE_ROS_VERSION == 1 907 tx.header.frame_id =
"map";
908 tx.child_frame_id = sOdomName;
909 tx.header.stamp =
myNow();
925 msg_shapes.markers.size(), (1 + veh->getNumWheels()));
929 for (
size_t j = 0; j < veh->getNumWheels(); j++)
932 auto& wheel_shape_msg = msg_shapes.markers[1 + j];
936 wheel_shape_msg.
pose = mrpt2ros::toROS_Pose(w.
pose());
941 #if PACKAGE_ROS_VERSION == 1 951 const mrpt::math::TPose3D odo_pose = gh_veh_pose;
955 tx.header.frame_id = sOdomName;
956 tx.child_frame_id = sBaseLinkFrame;
957 tx.header.stamp =
myNow();
959 tf2::toMsg(mrpt2ros::toROS_tfTransform(odo_pose));
965 #if PACKAGE_ROS_VERSION == 1 966 nav_msgs::Odometry odoMsg;
968 nav_msgs::msg::Odometry odoMsg;
970 odoMsg.pose.pose = mrpt2ros::toROS_Pose(odo_pose);
973 odoMsg.header.stamp =
myNow();
974 odoMsg.header.frame_id = sOdomName;
975 odoMsg.child_frame_id = sBaseLinkFrame;
978 #if PACKAGE_ROS_VERSION == 1 995 mrpt::system::CTimeLoggerEntry tle(
profiler_,
"onNewObservation");
997 using mrpt::obs::CObservation2DRangeScan;
1000 #if PACKAGE_ROS_VERSION == 1 1003 if (!rclcpp::ok())
return;
1007 ASSERT_(!obs->sensorLabel.empty());
1010 if (!vehPtr)
return;
1011 const auto& veh = *vehPtr;
1016 if (
const auto* o2DLidar =
1017 dynamic_cast<const CObservation2DRangeScan*>(obs.get());
1022 else if (
const auto* oImage =
1023 dynamic_cast<const mrpt::obs::CObservationImage*>(obs.get());
1028 else if (
const auto* oRGBD =
1029 dynamic_cast<const mrpt::obs::CObservation3DRangeScan*>(
1035 else if (
const auto* oPC =
1036 dynamic_cast<const mrpt::obs::CObservationPointCloud*>(
1042 else if (
const auto* oIMU =
1043 dynamic_cast<const mrpt::obs::CObservationIMU*>(obs.get());
1051 #if PACKAGE_ROS_VERSION == 1 1053 1.0,
"Do not know how to publish this observation to ROS: '" 1055 <<
"', class: " << obs->GetRuntimeClass()->className);
1057 RCLCPP_WARN_STREAM_THROTTLE(
1058 n_->get_logger(), *
n_->get_clock(), 1.0,
1059 "Do not know how to publish this observation to ROS: '" 1061 <<
"', class: " << obs->GetRuntimeClass()->className);
1072 using namespace std::string_literals;
1080 return veh.
getName() + std::string(
"/") + sVarName;
1086 const mrpt::obs::CObservation2DRangeScan& obs)
1092 const bool is_1st_pub =
1098 #if PACKAGE_ROS_VERSION == 1 1099 pub =
n_.advertise<sensor_msgs::LaserScan>(
1102 pub =
n_->create_publisher<sensor_msgs::msg::LaserScan>(
1108 #if PACKAGE_ROS_VERSION == 2 1109 rclcpp::Publisher<sensor_msgs::msg::LaserScan>::SharedPtr pubLidar =
1110 std::dynamic_pointer_cast<
1111 rclcpp::Publisher<sensor_msgs::msg::LaserScan>>(pub);
1115 const std::string sSensorFrameId =
vehVarName(obs.sensorLabel, veh);
1118 mrpt::poses::CPose3D sensorPose;
1119 obs.getSensorPose(sensorPose);
1121 tf2::Transform transform = mrpt2ros::toROS_tfTransform(sensorPose);
1125 tfStmp.child_frame_id = sSensorFrameId;
1126 tfStmp.header.frame_id =
vehVarName(
"base_link", veh);
1127 tfStmp.header.stamp =
myNow();
1133 #if PACKAGE_ROS_VERSION == 1 1134 geometry_msgs::Pose msg_pose_laser;
1135 sensor_msgs::LaserScan msg_laser;
1137 geometry_msgs::msg::Pose msg_pose_laser;
1138 sensor_msgs::msg::LaserScan msg_laser;
1140 mrpt2ros::toROS(obs, msg_laser, msg_pose_laser);
1143 msg_laser.header.stamp =
myNow();
1144 msg_laser.header.frame_id = sSensorFrameId;
1146 #if PACKAGE_ROS_VERSION == 1 1147 pub.publish(msg_laser);
1149 pubLidar->publish(msg_laser);
1161 const bool is_1st_pub =
1167 #if PACKAGE_ROS_VERSION == 1 1168 pub =
n_.advertise<sensor_msgs::Imu>(
1171 pub =
n_->create_publisher<sensor_msgs::msg::Imu>(
1178 #if PACKAGE_ROS_VERSION == 2 1179 rclcpp::Publisher<sensor_msgs::msg::Imu>::SharedPtr pubImu =
1180 std::dynamic_pointer_cast<rclcpp::Publisher<sensor_msgs::msg::Imu>>(
1185 const std::string sSensorFrameId =
vehVarName(obs.sensorLabel, veh);
1188 mrpt::poses::CPose3D sensorPose;
1189 obs.getSensorPose(sensorPose);
1191 tf2::Transform transform = mrpt2ros::toROS_tfTransform(sensorPose);
1195 tfStmp.child_frame_id = sSensorFrameId;
1196 tfStmp.header.frame_id =
vehVarName(
"base_link", veh);
1197 tfStmp.header.stamp =
myNow();
1203 #if PACKAGE_ROS_VERSION == 1 1204 sensor_msgs::Imu msg_imu;
1205 geometry_msgs::Pose msg_pose_imu;
1206 std_msgs::Header msg_header;
1208 sensor_msgs::msg::Imu msg_imu;
1209 std_msgs::msg::Header msg_header;
1212 msg_header.stamp =
myNow();
1213 msg_header.frame_id = sSensorFrameId;
1215 mrpt2ros::toROS(obs, msg_header, msg_imu);
1217 #if PACKAGE_ROS_VERSION == 1 1218 pub.publish(msg_imu);
1220 pubImu->publish(msg_imu);
1232 const bool is_1st_pub =
1238 #if PACKAGE_ROS_VERSION == 1 1248 #if PACKAGE_ROS_VERSION == 2 1249 rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr pubImg =
1250 std::dynamic_pointer_cast<rclcpp::Publisher<sensor_msgs::msg::Image>>(
1255 const std::string sSensorFrameId =
vehVarName(obs.sensorLabel, veh);
1258 mrpt::poses::CPose3D sensorPose;
1259 obs.getSensorPose(sensorPose);
1261 tf2::Transform transform = mrpt2ros::toROS_tfTransform(sensorPose);
1265 tfStmp.child_frame_id = sSensorFrameId;
1266 tfStmp.header.frame_id =
vehVarName(
"base_link", veh);
1267 tfStmp.header.stamp =
myNow();
1273 #if PACKAGE_ROS_VERSION == 1 1275 std_msgs::Header msg_header;
1278 std_msgs::msg::Header msg_header;
1280 msg_header.stamp =
myNow();
1281 msg_header.frame_id = sSensorFrameId;
1283 msg_img = mrpt2ros::toROS(obs.image, msg_header);
1285 #if PACKAGE_ROS_VERSION == 1 1286 pub.publish(msg_img);
1288 pubImg->publish(msg_img);
1295 const mrpt::obs::CObservation3DRangeScan& obs)
1297 using namespace std::string_literals;
1302 const auto lbPoints = obs.sensorLabel +
"_points"s;
1303 const auto lbImage = obs.sensorLabel +
"_image"s;
1306 const bool is_1st_pub =
1314 #if PACKAGE_ROS_VERSION == 1 1315 pubPts =
n_.advertise<sensor_msgs::PointCloud2>(
1322 pubPts =
n_->create_publisher<sensor_msgs::msg::PointCloud2>(
1328 #if PACKAGE_ROS_VERSION == 2 1329 rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr pubPoints =
1330 std::dynamic_pointer_cast<
1331 rclcpp::Publisher<sensor_msgs::msg::PointCloud2>>(pubPts);
1334 rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr pubImage =
1335 std::dynamic_pointer_cast<rclcpp::Publisher<sensor_msgs::msg::Image>>(
1340 const std::string sSensorFrameId_image =
vehVarName(lbImage, veh);
1341 const std::string sSensorFrameId_points =
vehVarName(lbPoints, veh);
1343 const auto now =
myNow();
1347 if (obs.hasIntensityImage)
1350 mrpt::poses::CPose3D sensorPose =
1351 obs.sensorPose + obs.relativePoseIntensityWRTDepth;
1353 tf2::Transform transform = mrpt2ros::toROS_tfTransform(sensorPose);
1357 tfStmp.child_frame_id = sSensorFrameId_image;
1358 tfStmp.header.frame_id =
vehVarName(
"base_link", veh);
1359 tfStmp.header.stamp = now;
1365 #if PACKAGE_ROS_VERSION == 1 1367 std_msgs::Header msg_header;
1370 std_msgs::msg::Header msg_header;
1372 msg_header.stamp = now;
1373 msg_header.frame_id = sSensorFrameId_image;
1375 msg_img = mrpt2ros::toROS(obs.intensityImage, msg_header);
1377 #if PACKAGE_ROS_VERSION == 1 1378 pubImg.publish(msg_img);
1380 pubImage->publish(msg_img);
1387 if (obs.hasRangeImage)
1390 mrpt::poses::CPose3D sensorPose = obs.sensorPose;
1392 tf2::Transform transform = mrpt2ros::toROS_tfTransform(sensorPose);
1396 tfStmp.child_frame_id = sSensorFrameId_points;
1397 tfStmp.header.frame_id =
vehVarName(
"base_link", veh);
1398 tfStmp.header.stamp = now;
1404 #if PACKAGE_ROS_VERSION == 1 1405 sensor_msgs::PointCloud2 msg_pts;
1406 std_msgs::Header msg_header;
1408 sensor_msgs::msg::PointCloud2 msg_pts;
1409 std_msgs::msg::Header msg_header;
1411 msg_header.stamp = now;
1412 msg_header.frame_id = sSensorFrameId_points;
1414 mrpt::obs::T3DPointsProjectionParams pp;
1415 pp.takeIntoAccountSensorPoseOnRobot =
false;
1417 mrpt::maps::CSimplePointsMap pts;
1418 const_cast<mrpt::obs::CObservation3DRangeScan&
>(obs).unprojectInto(
1421 mrpt2ros::toROS(pts, msg_header, msg_pts);
1423 #if PACKAGE_ROS_VERSION == 1 1424 pubPts.publish(msg_pts);
1426 pubPoints->publish(msg_pts);
1435 using namespace std::string_literals;
1440 const auto lbPoints = obs.sensorLabel +
"_points"s;
1443 const bool is_1st_pub =
1450 #if PACKAGE_ROS_VERSION == 1 1451 pubPts =
n_.advertise<sensor_msgs::PointCloud2>(
1454 pubPts =
n_->create_publisher<sensor_msgs::msg::PointCloud2>(
1460 #if PACKAGE_ROS_VERSION == 2 1461 rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr pubPoints =
1462 std::dynamic_pointer_cast<
1463 rclcpp::Publisher<sensor_msgs::msg::PointCloud2>>(pubPts);
1467 const std::string sSensorFrameId_points =
vehVarName(lbPoints, veh);
1469 const auto now =
myNow();
1475 mrpt::poses::CPose3D sensorPose = obs.sensorPose;
1477 tf2::Transform transform = mrpt2ros::toROS_tfTransform(sensorPose);
1481 tfStmp.child_frame_id = sSensorFrameId_points;
1482 tfStmp.header.frame_id =
vehVarName(
"base_link", veh);
1483 tfStmp.header.stamp = now;
1489 #if PACKAGE_ROS_VERSION == 1 1490 sensor_msgs::PointCloud2 msg_pts;
1491 std_msgs::Header msg_header;
1493 sensor_msgs::msg::PointCloud2 msg_pts;
1494 std_msgs::msg::Header msg_header;
1496 msg_header.stamp = now;
1497 msg_header.frame_id = sSensorFrameId_points;
1499 mrpt::obs::T3DPointsProjectionParams pp;
1500 pp.takeIntoAccountSensorPoseOnRobot =
false;
1502 if (
auto* sPts = dynamic_cast<const mrpt::maps::CSimplePointsMap*>(
1503 obs.pointcloud.get());
1506 mrpt2ros::toROS(*sPts, msg_header, msg_pts);
1508 else if (
auto* xyzi = dynamic_cast<const mrpt::maps::CPointsMapXYZI*>(
1509 obs.pointcloud.get());
1512 mrpt2ros::toROS(*xyzi, msg_header, msg_pts);
1517 "Do not know how to handle this variant of CPointsMap");
1520 #if PACKAGE_ROS_VERSION == 1 1521 pubPts.publish(msg_pts);
1523 pubPoints->publish(msg_pts);
size_t getVehicleIndex() const
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2 &size, const ImVec2 &uv0=ImVec2(0, 0), const ImVec2 &uv1=ImVec2(1, 1), const ImVec4 &tint_col=ImVec4(1, 1, 1, 1), const ImVec4 &border_col=ImVec4(0, 0, 0, 0))
mvsim::World::TGUIKeyEvent gui_key_events_
static void thread_update_GUI(TThreadParams &thread_params)
rclcpp::Subscription< geometry_msgs::msg::Twist >::SharedPtr sub_cmd_vel
Subscribers vehicle's "cmd_vel" topic.
tf2_ros::StaticTransformBroadcaster static_tf_br_
rclcpp::Publisher< nav_msgs::msg::Odometry >::SharedPtr pub_odom
Publisher of "odom" topic.
#define ROS_WARN_STREAM_THROTTLE(period, args)
const Wheel & getWheelInfo(const size_t idx) const
Represents data loaded from a file.
visualization_msgs::msg::MarkerArray chassis_shape_msg
mrpt::system::CTicTac realtime_tictac_
std::shared_ptr< mvsim::World > mvsim_world_
virtual bool setTwistCommand([[maybe_unused]] const mrpt::math::TTwist2D &t)
rclcpp::Node::SharedPtr n_
rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr pub_chassis_markers
"<VEH>/chassis_markers"
void launch_mvsim_server()
nav_msgs::msg::MapMetaData Msg_MapMetaData
geometry_msgs::TransformStamped t
mrpt::math::TPose3D pose() const
mrpt::system::CTimeLogger profiler_
void publishVehicles(mvsim::VehicleBase &veh)
rclcpp::Publisher< nav_msgs::msg::OccupancyGrid >::SharedPtr pub_map_ros_
used for simul_map publication
nav_msgs::msg::OccupancyGrid Msg_OccupancyGrid
TGUIKeyEvent keyevent
Keystrokes in the window are returned here.
const mrpt::math::TPolygon2D & getChassisShape() const
rclcpp::Publisher< geometry_msgs::msg::PoseArray >::SharedPtr pub_particlecloud
bool world_init_ok_
will be true after a success call to loadWorldModel()
void loadWorldModel(const std::string &world_xml_file)
void onROSMsgCmdVel(const geometry_msgs::msg::Twist::ConstSharedPtr &cmd, mvsim::VehicleBase *veh)
void spin()
Process pending msgs, run real-time simulation, etc.
double period_ms_publish_tf_
void onNewObservation(const mvsim::Simulable &veh, const mrpt::obs::CObservation::Ptr &obs)
int gui_refresh_period_ms_
rclcpp::Clock::SharedPtr clock_
MVSimNode(rclcpp::Node::SharedPtr &n)
int publisher_history_len_
(Default=0.1) Time tolerance for published TFs
#define ROS_WARN_THROTTLE(period,...)
void sendStaticTF(const std::string &frame_id, const std::string &child_frame_id, const tf2::Transform &tx, const rclcpp::Time &stamp)
std::shared_ptr< VehicleBase > Ptr
std::string msg_lines
Messages to show.
std::string vehVarName(const std::string &sVarName, const mvsim::VehicleBase &veh) const
std::mutex pubsub_vehicles_mtx_
rclcpp::Publisher< geometry_msgs::msg::Polygon >::SharedPtr pub_chassis_shape
"<VEH>/chassis_shape"
mrpt::system::CTicTac tim_teleop_refresh_
const std::string & getName() const
double period_ms_teleop_refresh_
void publishWorldElements(mvsim::WorldElementBase &obj)
TThreadParams thread_params_
void terminateSimulation()
bool do_fake_localization_
mrpt::system::CTicTac tim_publish_tf_
std::map< std::string, rclcpp::PublisherBase::SharedPtr > pub_sensors
Map <sensor_label> => publisher.
rclcpp::Publisher< nav_msgs::msg::Odometry >::SharedPtr pub_ground_truth
"base_pose_ground_truth" topic
void initPubSubs(TPubSubPerVehicle &out_pubsubs, mvsim::VehicleBase *veh)
rclcpp::Publisher< nav_msgs::msg::MapMetaData >::SharedPtr pub_map_metadata_
geometry_msgs::msg::TransformStamped Msg_TransformStamped
rclcpp::Time myNow() const
std::string append_gui_lines
mrpt::WorkerThreadsPool ros_publisher_workers_
std::shared_ptr< mvsim::Server > server
void notifyROSWorldIsUpdated()
std::shared_ptr< mvsim::Server > mvsim_server_
rclcpp::Publisher< geometry_msgs::msg::PoseWithCovarianceStamped >::SharedPtr pub_amcl_pose
"fake_localization" pubs:
virtual void teleop_interface([[maybe_unused]] const TeleopInput &in, [[maybe_unused]] TeleopOutput &out)
void internalOn(const mvsim::VehicleBase &veh, const mrpt::obs::CObservation2DRangeScan &obs)
const tf2::Transform tfIdentity_
Unit transform (const, once)
size_t getNumWheels() const
size_t teleop_idx_veh_
for teleoperation from the GUI (selects the focused" vehicle)
tf2_ros::TransformBroadcaster tf_br_
Use to send data to TF.
int keycode
0=no Key. Otherwise, ASCII code.
std::vector< TPubSubPerVehicle > pubsub_vehicles_
double realtime_factor_
(Defaul=1.0) >1: speed-up, <1: slow-down