15 #include <nav_msgs/MapMetaData.h> 16 #include <nav_msgs/GetMap.h> 17 #include <geometry_msgs/PoseWithCovarianceStamped.h> 18 #include <geometry_msgs/PoseArray.h> 19 #include <geometry_msgs/Polygon.h> 20 #include <sensor_msgs/LaserScan.h> 22 #include <nav_msgs/Odometry.h> 30 : mvsim_world_(*this),
31 realtime_factor_(1.0),
32 gui_refresh_period_ms_(75),
34 m_do_fake_localization(true),
35 m_transform_tolerance(0.1),
39 m_tfIdentity(
tf::createIdentityQuaternion(),
tf::
Point(0, 0, 0)),
41 world_init_ok_(false),
42 m_period_ms_publish_tf(20),
43 m_period_ms_teleop_refresh(100),
55 "simul_map", 1 ,
true );
57 "simul_map_metadata", 1 ,
true );
82 ROS_INFO(
"[MVSimNode] Loading world file: %s", world_xml_file.c_str());
85 "[MVSimNode::loadWorldModel] File does not exist!: '%s'",
86 world_xml_file.c_str());
92 ROS_INFO(
"[MVSimNode] World file load done.");
118 ROS_INFO(
"MVSimNode::configCallback() called.");
127 using namespace mvsim;
160 std::string txt2gui_tmp;
179 "Selected vehicle: %u/%u\n",
181 static_cast<unsigned>(vehs.size()));
185 World::TListVehicles::const_iterator it_veh = vehs.begin();
190 const vec3& vel = it_veh->second->getVelocityLocal();
192 "gt. vel: lx=%7.03f, ly=%7.03f, w= %7.03fdeg/s\n",
193 vel.vals[0], vel.vals[1],
199 it_veh->second->getVelocityLocalOdoEstimate();
201 "odo vel: lx=%7.03f, ly=%7.03f, w= %7.03fdeg/s\n",
202 vel.vals[0], vel.vals[1],
210 it_veh->second->getControllerInterface();
233 using namespace mvsim;
250 std::this_thread::sleep_for(
268 if (dynamic_cast<mvsim::OccupancyGridMap*>(obj))
276 static size_t loop_count = 0;
278 ros_map.header.seq = loop_count++;
280 m_parent.m_pub_map_ros.publish(ros_map);
281 m_parent.m_pub_map_metadata.publish(ros_map.info);
301 for (mvsim::World::TListVehicles::iterator it = vehs.begin();
302 it != vehs.end(); ++it, ++idx)
313 const std::string& frame_id,
const std::string& child_frame_id,
316 geometry_msgs::TransformStamped tx;
317 tx.header.frame_id = frame_id;
318 tx.child_frame_id = child_frame_id;
319 tx.header.stamp = stamp;
339 vehVarName(
"base_pose_ground_truth", veh), 10);
345 vehVarName(
"chassis_markers", veh), 5,
true );
353 visualization_msgs::Marker& chassis_shape_msg = msg_shapes.markers[0];
355 chassis_shape_msg.action = visualization_msgs::Marker::MODIFY;
356 chassis_shape_msg.type = visualization_msgs::Marker::LINE_STRIP;
357 chassis_shape_msg.header.frame_id =
vehVarName(
"base_link", veh);
358 chassis_shape_msg.ns =
"mvsim.chassis_shape";
360 chassis_shape_msg.scale.x = 0.05;
361 chassis_shape_msg.scale.y = 0.05;
362 chassis_shape_msg.scale.z = 0.02;
363 chassis_shape_msg.points.resize(poly.size() + 1);
364 for (
size_t i = 0; i <= poly.size(); i++)
366 size_t k = i % poly.size();
367 chassis_shape_msg.points[i].x = poly[k].x;
368 chassis_shape_msg.points[i].y = poly[k].y;
369 chassis_shape_msg.points[i].z = 0;
371 chassis_shape_msg.color.a = 0.9;
372 chassis_shape_msg.color.r = 0.9;
373 chassis_shape_msg.color.g = 0.9;
374 chassis_shape_msg.color.b = 0.9;
375 chassis_shape_msg.frame_locked =
true;
380 visualization_msgs::Marker& wheel_shape_msg =
381 msg_shapes.markers[1 + i];
385 wheel_shape_msg = chassis_shape_msg;
387 "mvsim.chassis_shape.wheel%u", static_cast<unsigned int>(i));
388 wheel_shape_msg.points.resize(5);
389 wheel_shape_msg.points[0].x = lx;
390 wheel_shape_msg.points[0].y = ly;
391 wheel_shape_msg.points[0].z = 0;
392 wheel_shape_msg.points[1].x = lx;
393 wheel_shape_msg.points[1].y = -ly;
394 wheel_shape_msg.points[1].z = 0;
395 wheel_shape_msg.points[2].x = -lx;
396 wheel_shape_msg.points[2].y = -ly;
397 wheel_shape_msg.points[2].z = 0;
398 wheel_shape_msg.points[3].x = -lx;
399 wheel_shape_msg.points[3].y = ly;
400 wheel_shape_msg.points[3].z = 0;
401 wheel_shape_msg.points[4] = wheel_shape_msg.points[0];
403 wheel_shape_msg.color.r = w.
color.R / 255.0;
404 wheel_shape_msg.color.g = w.
color.G / 255.0;
405 wheel_shape_msg.color.b = w.
color.B / 255.0;
412 wheel_shape_msg.pose);
422 vehVarName(
"chassis_polygon", veh), 1,
true );
425 geometry_msgs::Polygon poly_msg;
427 poly_msg.points.resize(poly.size());
428 for (
size_t i = 0; i < poly.size(); i++)
430 poly_msg.points[i].x = poly[i].x;
431 poly_msg.points[i].y = poly[i].y;
432 poly_msg.points[i].z = 0;
441 m_n.
advertise<geometry_msgs::PoseWithCovarianceStamped>(
459 const bool ctrlAcceptTwist =
462 if (!ctrlAcceptTwist)
466 "*Warning* Vehicle's controller ['%s'] refuses Twist commands!",
474 using namespace mvsim;
492 for (World::TListVehicles::const_iterator it = vehs.begin();
493 it != vehs.end(); ++it, ++i)
497 const std::string sOdomName =
vehVarName(
"odom", veh);
498 const std::string sBaseLinkFrame =
vehVarName(
"base_link", veh);
503 const mvsim::vec3& gh_veh_vel =
507 nav_msgs::Odometry gtOdoMsg;
509 gtOdoMsg.pose.pose.position.x = gh_veh_pose.
x;
510 gtOdoMsg.pose.pose.position.y = gh_veh_pose.
y;
511 gtOdoMsg.pose.pose.position.z = gh_veh_pose.
z;
517 gtOdoMsg.pose.pose.orientation.x = quat.x();
518 gtOdoMsg.pose.pose.orientation.y = quat.y();
519 gtOdoMsg.pose.pose.orientation.z = quat.z();
520 gtOdoMsg.pose.pose.orientation.w = quat.w();
521 gtOdoMsg.twist.twist.linear.x = gh_veh_vel.vals[0];
522 gtOdoMsg.twist.twist.linear.y = gh_veh_vel.vals[1];
523 gtOdoMsg.twist.twist.linear.z = 0;
524 gtOdoMsg.twist.twist.angular.z = gh_veh_vel.vals[2];
527 gtOdoMsg.header.frame_id = sOdomName;
528 gtOdoMsg.child_frame_id = sBaseLinkFrame;
534 geometry_msgs::PoseWithCovarianceStamped currentPos;
535 geometry_msgs::PoseArray particleCloud;
539 .pub_particlecloud.getNumSubscribers() > 0)
542 particleCloud.header.frame_id =
"/map";
543 particleCloud.poses.resize(1);
544 particleCloud.poses[0] = gtOdoMsg.pose.pose;
553 currentPos.header = gtOdoMsg.header;
554 currentPos.pose.pose = gtOdoMsg.pose.pose;
561 "Save initial pose for each vehicle, set odometry " 579 visualization_msgs::MarkerArray& msg_shapes =
582 msg_shapes.markers.size() == (1 + veh->
getNumWheels()));
588 visualization_msgs::Marker& wheel_shape_msg =
589 msg_shapes.markers[1 + j];
597 wheel_shape_msg.pose);
624 nav_msgs::Odometry odoMsg;
626 odoMsg.pose.pose.position.x = odo_pose.
x;
627 odoMsg.pose.pose.position.y = odo_pose.
y;
628 odoMsg.pose.pose.position.z = odo_pose.
z;
633 odoMsg.pose.pose.orientation.x = quat.x();
634 odoMsg.pose.pose.orientation.y = quat.y();
635 odoMsg.pose.pose.orientation.z = quat.z();
636 odoMsg.pose.pose.orientation.w = quat.w();
640 odoMsg.header.frame_id = sOdomName;
641 odoMsg.child_frame_id = sBaseLinkFrame;
656 #
if MRPT_VERSION >= 0x130
659 const mrpt::slam::CObservation* obs
669 const bool is_1st_pub =
670 pubs.
pub_sensors.find(
obs->sensorLabel) == pubs.pub_sensors.end();
675 if (dynamic_cast<const CObservation2DRangeScan*>(
obs))
679 m_parent.vehVarName(
obs->sensorLabel, &veh), 10);
681 const CObservation2DRangeScan* o =
682 dynamic_cast<const CObservation2DRangeScan*
>(
obs);
683 const std::string sSensorFrameId =
684 m_parent.vehVarName(
obs->sensorLabel, &veh);
689 o->getSensorPose(pose_laser);
692 m_parent.m_tf_br.sendTransform(
694 transform, m_parent.m_sim_time,
695 m_parent.vehVarName(
"base_link", &veh),
707 msg_laser.header.stamp = m_parent.m_sim_time;
708 msg_laser.header.frame_id = sSensorFrameId;
727 return std::string(
"/") + sVarName;
731 return std::string(
"/") + veh->
getName() + std::string(
"/") + sVarName;
ros::Publisher pub_ground_truth
Publisher of "base_pose_ground_truth" topic.
ros::Publisher pub_amcl_pose
static void thread_update_GUI(TThreadParams &thread_params)
std::string vehVarName(const std::string &sVarName, const mvsim::VehicleBase *veh) const
void visit(mvsim::VehicleBase *obj)
const mrpt::maps::COccupancyGridMap2D & getOccGrid() const
mrpt::system::CTicTac m_tim_publish_tf
TF transforms & /*/odom topics (In ms)
double m_period_ms_teleop_refresh
void publish(const boost::shared_ptr< M > &message) const
Represents data loaded from a file.
ros::Subscriber sub_cmd_vel
Subscribers for each vehicle's "cmd_vel" topic.
virtual void teleop_interface(const TeleopInput &in, TeleopOutput &out)
const VehicleList & getListOfVehicles() const
#define ROS_DEBUG_THROTTLE(rate,...)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
mrpt::system::CTicTac realtime_tictac_
GLubyte GLubyte GLubyte GLubyte w
bool BASE_IMPEXP fileExists(const std::string &fileName)
void runVisitorOnWorldElements(const world_element_visitor_t &v)
ros::Time m_base_last_cmd
Last time we received a vel_cmd (for watchdog)
ros::Publisher m_pub_map_ros
void setEulerYPR(tfScalar eulerZ, tfScalar eulerY, tfScalar eulerX)
mrpt::math::TPose3D getPose() const
virtual void onNewObservation(const mvsim::VehicleBase &veh, const CObservation *obs)
rosgraph_msgs::Clock m_clockMsg
static tf::Quaternion createIdentityQuaternion()
mvsim::World::TGUIKeyEvent m_gui_key_events
"focused" vehicle)
GLuint GLenum GLenum transform
const mrpt::math::TPolygon2D & getChassisShape() const
MRPT_TODO("Modify ping to run on Windows + Test this")
mrpt::system::CTicTac m_tim_teleop_refresh
ros::Duration m_base_watchdog_timeout
TGUIKeyEvent keyevent
Keystrokes in the window are returned here.
const tf::Transform m_tfIdentity
Unit transform (const, created only once)
double get_simul_timestep() const
Simulation fixed-time interval for numerical integration.
void onROSMsgCmdVel(const geometry_msgs::Twist::ConstPtr &cmd, mvsim::VehicleBase *veh)
tf::TransformBroadcaster m_tf_br
Use to send data to TF.
size_t getNumWheels() const
void loadWorldModel(const std::string &world_xml_file)
void spin()
Process pending msgs, run real-time simulation, etc.
const std::string & getName() const
void configCallback(mvsim::mvsimNodeConfig &config, uint32_t level)
int gui_refresh_period_ms_
Default:25.
bool is_GUI_open() const
Forces closing the GUI window, if any.
Duration & fromSec(double t)
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
tf2_ros::StaticTransformBroadcaster m_static_tf_br
For sending STATIC tf.
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
size_t getVehicleIndex() const
#define ROS_ASSERT_MSG(cond,...)
double m_period_ms_publish_tf
loadWorldModel()
std::string msg_lines
Messages to show.
virtual ControllerBaseInterface * getControllerInterface()=0
ros::Publisher pub_chassis_shape
"<VEH>/chassis_shape"
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::NodeHandle & m_n
published TFs
const Wheel & getWheelInfo(const size_t idx) const
void sendStaticTF(const std::string &frame_id, const std::string &child_frame_id, const tf::Transform &tx, const ros::Time &stamp)
void load_from_XML(const std::string &xml_text, const std::string &fileNameForPath=std::string("."))
ros::Publisher pub_chassis_markers
"<VEH>/chassis_markers"
TThreadParams thread_params_
void setEuler(const tfScalar &yaw, const tfScalar &pitch, const tfScalar &roll)
TCLAP::CmdLine cmd("mvsim", ' ',"version", false)
virtual bool setTwistCommand(const double vx, const double wz)
void convert(const ros::Time &src, mrpt::system::TTimeStamp &des)
ros::Publisher pub_particlecloud
Publishers for "fake_localization" topics.
ros::Publisher pub_odom
Publisher of "odom" topic.
uint32_t getNumSubscribers() const
void runVisitorOnVehicles(const vehicle_visitor_t &v)
static void poseTFToMsg(const Pose &bt, geometry_msgs::Pose &msg)
void initPubSubs(TPubSubPerVehicle &out_pubsubs, mvsim::VehicleBase *veh)
const mrpt::math::TTwist2D & getVelocity() const
bool getParam(const std::string &key, std::string &s) const
ros::Publisher m_pub_clock
std::vector< TPubSubPerVehicle > m_pubsub_vehicles
std::string append_gui_lines
double RAD2DEG(const double x)
MVSimNode(ros::NodeHandle &n)
std::map< std::string, ros::Publisher > pub_sensors
Map <sensor_label> => publisher.
void run_simulation(double dt)
void notifyROSWorldIsUpdated()
bool m_show_gui
Default= true.
ros::Time m_sim_time
Current simulation time.
void update_GUI(TUpdateGUIParams *params=nullptr)
bool m_do_fake_localization
double get_simul_time() const
Simulation wall-clock time.
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
visualization_msgs::MarkerArray chassis_shape_msg
static void transformTFToMsg(const Transform &bt, geometry_msgs::Transform &msg)
int keycode
0=no Key. Otherwise, ASCII code.
double realtime_factor_
everything: vehicles, obstacles, etc.)
void close_GUI()
a previous call to update_GUI()
ros::Publisher m_pub_map_metadata
used for simul_map publication