34 #include <boost/interprocess/sync/scoped_lock.hpp> 35 #include <geometry_msgs/PoseArray.h> 42 #include <mrpt_bridge/beacon.h> 44 #include <mrpt/version.h> 45 #include <mrpt/obs/CObservationBeaconRanges.h> 48 #include <mrpt/version.h> 50 #if MRPT_VERSION >= 0x199 51 #include <mrpt/system/COutputLogger.h> 62 #include <mrpt/maps/COccupancyGridMap2D.h> 65 int main(
int argc,
char** argv)
79 first_map_received_(false),
103 std::vector<std::string> sources;
107 "*Fatal*: At least one sensor source must be provided in " 108 "~sensor_sources (e.g. \"scan\" or \"beacon\")");
110 for (
size_t i = 0; i < sources.size(); i++)
112 if (sources[i].
find(
"scan") != std::string::npos)
117 else if (sources[i].
find(
"beacon") != std::string::npos)
131 #if MRPT_VERSION >= 0x199 145 nh_.
advertise<nav_msgs::MapMetaData>(
"map_metadata", 1,
true);
150 nh_.
advertise<geometry_msgs::PoseArray>(
"particlecloud", 1,
true);
153 "mrpt_pose", 2,
true);
164 #
if MRPT_VERSION >= 0x199
182 const std::string& source_frame,
const ros::Time& time,
189 target_frame, source_frame, time, timeout, polling_sleep_duration);
191 target_frame, source_frame, time, transform);
196 "Failed to get transform target_frame (%s) to source_frame (%s): " 198 target_frame.c_str(), source_frame.c_str(), e.what());
213 auto laser = CObservation2DRangeScan::Create();
223 if(
param()->update_sensor_pose) {
231 auto sf = CSensoryFrame::Create();
232 CObservationOdometry::Ptr odometry;
235 CObservation::Ptr
obs = CObservation::Ptr(laser);
251 auto beacon = CObservationBeaconRanges::Create();
260 if(
param()->update_sensor_pose) {
269 auto sf = CSensoryFrame::Create();
270 CObservationOdometry::Ptr odometry;
273 CObservation::Ptr
obs = CObservation::Ptr(beacon);
281 const geometry_msgs::PoseWithCovarianceStamped& _msg)
295 static std::string base_frame_id =
297 static std::string global_frame_id =
304 global_frame_id, _msg.header.frame_id,
ros::Time(0.0),
307 global_frame_id, _msg.header.frame_id,
ros::Time(0.0),
323 map_to_obs_tf.
getRotation(), map_to_obs_pose.orientation);
324 geometry_msgs::PoseWithCovarianceStamped obs_pose_world;
325 obs_pose_world.header.stamp = _msg.header.stamp;
326 obs_pose_world.header.frame_id = global_frame_id;
330 for (
unsigned int i = 0; i < obs_pose_world.pose.covariance.size(); ++i)
332 if (i / 6 == i % 6 && obs_pose_world.pose.covariance[i] <= 0.0)
333 obs_pose_world.pose.covariance[i] =
334 std::numeric_limits<double>().infinity();
338 auto feature = CObservationRobotPose::Create();
340 feature->sensorLabel = _msg.header.frame_id;
344 auto sf = CSensoryFrame::Create();
345 CObservationOdometry::Ptr odometry;
348 CObservation::Ptr
obs = CObservation::Ptr(
feature);
357 std::string base_frame_id =
359 std::string odom_frame_id =
363 poseOdom, odom_frame_id, base_frame_id, _msg_header.stamp,
366 _odometry = CObservationOdometry::Create();
367 _odometry->sensorLabel = odom_frame_id;
368 _odometry->hasEncodersInfo =
false;
369 _odometry->hasVelocities =
false;
370 _odometry->odometry.x() = poseOdom.
x();
371 _odometry->odometry.y() = poseOdom.
y();
372 _odometry->odometry.phi() = poseOdom.
yaw();
378 int wait_counter = 0;
381 if (
param()->use_map_topic)
385 ROS_INFO(
"Subscribed to map topic.");
389 ROS_INFO(
"waiting for map callback..");
394 if (wait_counter != wait_limit)
402 nav_msgs::GetMap srv;
405 ROS_INFO(
"waiting for map service!");
410 if (wait_counter != wait_limit)
441 std::string base_frame_id =
444 base_frame_id, _frame_id,
ros::Time(0), transform);
447 pose.
x() = translation.
x();
448 pose.
y() = translation.
y();
449 pose.z() = translation.
z();
452 for (
int c = 0;
c < 3;
c++)
466 const geometry_msgs::PoseWithCovarianceStamped& _msg)
480 bool moving = std::abs(_msg.twist.twist.linear.x) > 1e-3 ||
481 std::abs(_msg.twist.twist.linear.y) > 1e-3 ||
482 std::abs(_msg.twist.twist.linear.z) > 1e-3 ||
483 std::abs(_msg.twist.twist.angular.x) > 1e-3 ||
484 std::abs(_msg.twist.twist.angular.y) > 1e-3 ||
485 std::abs(_msg.twist.twist.angular.z) > 1e-3;
486 if (
param()->update_while_stopped || moving)
501 #if MRPT_VERSION >= 0x199 511 nav_msgs::GetMap::Request& req, nav_msgs::GetMap::Response&
res)
513 ROS_INFO(
"mapCallback: service requested!\n");
521 resp_.map.header.frame_id =
538 geometry_msgs::PoseArray poseArray;
539 poseArray.header.frame_id =
560 static std::string base_frame_id =
562 static std::string odom_frame_id =
564 static std::string global_frame_id =
583 param()->no_update_tolerance)
586 param()->no_inputs_tolerance)
590 "No observations received for %.2fs (tolerance %.2fs); are " 591 "robot sensors working?",
593 param()->no_inputs_tolerance);
599 "No filter updates for %.2fs (tolerance %.2fs); probably " 600 "robot stopped for a while",
602 param()->no_update_tolerance);
613 base_frame_id, odom_frame_id, time_last_update,
ros::Duration(0.1));
615 base_frame_id, odom_frame_id, time_last_update, odom_on_base_tf);
620 2.0,
"Transform from base frame (%s) to odom frame (%s) failed: %s",
621 base_frame_id.c_str(), odom_frame_id.c_str(), e.what());
624 "Ensure that your mobile base driver is broadcasting %s -> %s tf",
625 odom_frame_id.c_str(), base_frame_id.c_str());
635 base_on_map_tf * odom_on_base_tf, transform_expiration, global_frame_id,
646 #if MRPT_VERSION >= 0x199 654 geometry_msgs::PoseWithCovarianceStamped
p;
669 for (
int i = 0; i < 3; i++)
671 for (
int j = 0; j < 3; j++)
675 if (i == 2 || j == 2)
677 ros_i = i == 2 ? 5 : i;
678 ros_j = j == 2 ? 5 : j;
680 p.pose.covariance[ros_i * 6 + ros_j] = cov(i, j);
691 std::map<std::string, ros::console::levels::Level> loggers;
693 if (loggers.find(
"ros.roscpp") != loggers.end())
694 pdf_.setVerbosityLevel(
695 static_cast<VerbosityLevel>(loggers[
"ros.roscpp"]));
696 if (loggers.find(
"ros.mrpt_localization") != loggers.end())
697 pdf_.setVerbosityLevel(
698 static_cast<VerbosityLevel>(loggers[
"ros.mrpt_localization"]));
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
CMultiMetricMap metric_map_
map
void callbackRobotPose(const geometry_msgs::PoseWithCovarianceStamped &)
#define ROS_WARN_THROTTLE(rate,...)
ros::ServiceClient client_map_
void publish(const boost::shared_ptr< M > &message) const
void compose(const geometry_msgs::Pose &a, const geometry_msgs::Pose &b, geometry_msgs::Pose &out)
void publishTF()
Publish map -> odom tf; as the filter provides map -> base, we multiply it by base -> odom...
#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())
ros::Subscriber sub_init_pose_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool call(MReq &req, MRes &res)
ROSCONSOLE_DECL bool get_loggers(std::map< std::string, levels::Level > &loggers)
virtual bool waitForMap()
ros::Time time_last_input_
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
size_t particlesCount() const MRPT_OVERRIDE
void publishPose()
Publish the current pose of the robot.
GLuint GLenum GLenum transform
ros::Publisher pub_particles_
void observation(CSensoryFrame::Ptr _sf, CObservationOdometry::Ptr _odometry)
void getMean(CPose2D &mean_pose) const MRPT_OVERRIDE
ros::Publisher pub_metadata_
TFSIMD_FORCE_INLINE const Vector3 & getRow(int i) const
std::string resolve(const std::string &prefix, const std::string &frame_name)
TFSIMD_FORCE_INLINE const tfScalar & x() const
void updateSensorPose(std::string frame_id)
TFSIMD_FORCE_INLINE const tfScalar & z() const
CPose2D getParticlePose(size_t i) const
std::map< std::string, mrpt::poses::CPose3D > beacon_poses_
void odometryForCallback(CObservationOdometry::Ptr &, const std_msgs::Header &)
void callbackOdometry(const nav_msgs::Odometry &)
#define ROS_ASSERT_MSG(cond,...)
mrpt::slam::CMonteCarloLocalization2D pdf_
the filter
static void quaternionTFToMsg(const Quaternion &bt, geometry_msgs::Quaternion &msg)
mrpt::poses::CPosePDFGaussian initial_pose_
initial posed used in initializeFilter()
TFSIMD_FORCE_INLINE const tfScalar & y() const
tf::TransformListener tf_listener_
bool waitForTransform(mrpt::poses::CPose3D &des, const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration &timeout, const ros::Duration &polling_sleep_duration=ros::Duration(0.01))
std::vector< ros::Subscriber > sub_sensors_
ros::Subscriber sub_odometry_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void getCovarianceAndMean(mrpt::math::CMatrixDouble33 &cov, CPose2D &mean_point) const MRPT_OVERRIDE
PFLocalizationNode(ros::NodeHandle &n)
#define ROS_WARN_STREAM(args)
void callbackLaser(const sensor_msgs::LaserScan &)
void callbackBeacon(const mrpt_msgs::ObservationRangeBeacon &)
void convert(const ros::Time &src, mrpt::system::TTimeStamp &des)
bool mapCallback(nav_msgs::GetMap::Request &req, nav_msgs::GetMap::Response &res)
tf::TransformBroadcaster tf_broadcaster_
double transform_tolerance
const_iterator find(const KEY &key) const
unsigned long long loop_count_
uint32_t getNumSubscribers() const
#define ROS_INFO_STREAM(args)
int main(int argc, char **argv)
void show3DDebug(CSensoryFrame::Ptr _observations)
nav_msgs::GetMap::Response resp_
void update(const unsigned long &loop_count)
GLdouble GLdouble GLdouble r
ros::ServiceServer service_map_
virtual ~PFLocalizationNode()
std::map< std::string, mrpt::poses::CPose3D > laser_poses_
ProxyFilterContainerByClass< mrpt::maps::COccupancyGridMap2DPtr, TListMaps > m_gridMaps
void updateMap(const nav_msgs::OccupancyGrid &)
mrpt::system::TTimeStamp time_last_update_
time of the last update
void callbackInitialpose(const geometry_msgs::PoseWithCovarianceStamped &)
ROSCPP_DECL void spinOnce()
void BASE_IMPEXP tokenize(const std::string &inString, const std::string &inDelimiters, std::deque< std::string > &outTokens, bool skipBlankTokens=true) MRPT_NO_THROWS
void callbackMap(const nav_msgs::OccupancyGrid &)
void setRotationMatrix(const mrpt::math::CMatrixDouble33 &ROT)
static void pointTFToMsg(const Point &bt_v, geometry_msgs::Point &msg_v)