6#include <angles/angles.h>
8#include <boost/range/adaptor/reversed.hpp>
15 : paramServer_(ros::NodeHandle(
"~/odom_tracker"))
22 ros::NodeHandle nh(
"~/odom_tracker");
24 ROS_WARN(
"Initializing Odometry Tracker");
26 if (!nh.getParam(
"odom_frame", this->odomFrame_))
28 ROS_INFO_STREAM(
"[OdomTracker] odomFrame:" << this->
odomFrame_);
30 ROS_INFO_STREAM(
"[OdomTracker] odomFrame overwritten by ros parameter:" << this->
odomFrame_);
61 robotBasePathPub_ = std::make_shared<realtime_tools::RealtimePublisher<nav_msgs::Path>>(nh,
"odom_tracker_path", 1);
63 std::make_shared<realtime_tools::RealtimePublisher<nav_msgs::Path>>(nh,
"odom_tracker_stacked_path", 1);
77 std::lock_guard<std::mutex> lock(
m_mutex_);
78 ROS_INFO(
"[OdomTracker] setting working mode to: %d", (uint8_t)workingMode);
91 std::lock_guard<std::mutex> lock(
m_mutex_);
99 ROS_INFO(
"odom_tracker m_mutex acquire");
100 std::lock_guard<std::mutex> lock(
m_mutex_);
101 ROS_INFO(
"PUSH_PATH PATH EXITING");
107 if(newPathTagName ==
"")
116 ROS_INFO(
"PUSH_PATH PATH EXITING");
118 ROS_INFO(
"odom_tracker m_mutex release");
124 ROS_INFO(
"odom_tracker m_mutex acquire");
125 std::lock_guard<std::mutex> lock(
m_mutex_);
127 ROS_INFO(
"POP PATH ENTRY");
130 if (!keepPreviousPath)
142 ROS_INFO(
"POP PATH Iteration ");
146 ROS_INFO(
"POP PATH EXITING");
148 ROS_INFO(
"odom_tracker m_mutex release");
154 ROS_INFO(
"--- odom tracker state ---");
155 ROS_INFO(
" - stacked paths count: %ld",
pathStack_.size());
158 for (
auto &p :
pathStack_ | boost::adaptors::reversed)
160 ROS_INFO_STREAM(
" - p " << i <<
"[" << p.path.header.stamp <<
"][" << p.pathTagName <<
"], size: " << p.path.poses.size());
168 std::lock_guard<std::mutex> lock(
m_mutex_);
178 std::lock_guard<std::mutex> lock(
m_mutex_);
179 ROS_INFO_STREAM(
"[OdomTracker] set current path starting point: " << pose);
193 std::lock_guard<std::mutex> lock(
m_mutex_);
194 ROS_INFO_STREAM(
"[OdomTracker] set current path starting point: " << pose);
195 geometry_msgs::PoseStamped posestamped;
196 posestamped.header.frame_id = this->
odomFrame_;
197 posestamped.header.stamp = ros::Time::now();
198 posestamped.pose = pose;
213 std::lock_guard<std::mutex> lock(
m_mutex_);
231 msg.header.stamp = timestamp;
241 msg.header.stamp = timestamp;
266 geometry_msgs::PoseStamped base_pose;
268 base_pose.pose = odom.pose.pose;
269 base_pose.header = odom.header;
272 bool acceptBackward =
false;
273 bool clearingError =
false;
274 bool finished =
false;
282 acceptBackward =
false;
288 const geometry_msgs::Point &carrotPoint = carrotPose.position;
289 double carrotAngle = tf::getYaw(carrotPose.orientation);
291 auto &currePose = base_pose.pose;
292 const geometry_msgs::Point &currePoint = currePose.position;
293 double currentAngle = tf::getYaw(currePose.orientation);
295 double lastpointdist =
p2pDistance(carrotPoint, currePoint);
296 double goalAngleOffset = fabs(angles::shortest_angular_distance(carrotAngle, currentAngle));
302 ROS_DEBUG_STREAM(
"[OdomTracker] clearing (accepted: " << acceptBackward <<
") linerr: " << lastpointdist
303 <<
", anglerr: " << goalAngleOffset);
314 else if (clearingError)
317 ROS_WARN(
"[OdomTracker] Incorrect odom clearing motion.");
326 return acceptBackward;
336 geometry_msgs::PoseStamped base_pose;
338 base_pose.pose = odom.pose.pose;
339 base_pose.header = odom.header;
342 bool enqueueOdomMessage =
false;
347 enqueueOdomMessage =
true;
352 const geometry_msgs::Point &prevPoint = prevPose.position;
353 double prevAngle = tf::getYaw(prevPose.orientation);
355 const geometry_msgs::Point &currePoint = base_pose.pose.position;
356 double currentAngle = tf::getYaw(base_pose.pose.orientation);
359 double goalAngleOffset = fabs(angles::shortest_angular_distance(prevAngle, currentAngle));
365 enqueueOdomMessage =
true;
370 enqueueOdomMessage =
false;
374 if (enqueueOdomMessage)
379 return enqueueOdomMessage;
389 ROS_INFO(
"[OdomTracker] reconfigure Request");
406 std::lock_guard<std::mutex> lock(
m_mutex_);
nav_msgs::Path aggregatedStackPathMsg_
double recordAngularDistanceThreshold_
Meters.
virtual void processOdometryMessage(const nav_msgs::Odometry &odom)
odom callback: Updates the path - this must be called periodically for each odometry message.
double clearAngularDistanceThreshold_
rads
std::vector< StackedPathEntry > pathStack_
void popPath(int pathCount=1, bool keepPreviousPath=false)
dynamic_reconfigure::Server< move_base_z_client_plugin::OdomTrackerConfig >::CallbackType f
double recordPointDistanceThreshold_
How much distance there is between two points of the path.
void setPublishMessages(bool value)
std::shared_ptr< realtime_tools::RealtimePublisher< nav_msgs::Path > > robotBasePathPub_
nav_msgs::Path baseTrajectory_
Processed path for the mouth of the reel.
std::string currentPathTagName_
double clearPointDistanceThreshold_
rads
virtual bool updateRecordPath(const nav_msgs::Odometry &odom)
void updateAggregatedStackPath()
std::shared_ptr< realtime_tools::RealtimePublisher< nav_msgs::Path > > robotBasePathStackedPub_
dynamic_reconfigure::Server< move_base_z_client_plugin::OdomTrackerConfig > paramServer_
virtual void rtPublishPaths(ros::Time timestamp)
OdomTracker(std::string odomtopicName="/odom", std::string odomFrame="odom")
void setStartPoint(const geometry_msgs::PoseStamped &pose)
void pushPath(std::string newPathTagName="")
virtual bool updateClearPath(const nav_msgs::Odometry &odom)
void reconfigCB(move_base_z_client_plugin::OdomTrackerConfig &config, uint32_t level)
void setWorkingMode(WorkingMode workingMode)
bool subscribeToOdometryTopic_
double p2pDistance(const geometry_msgs::Point &p1, const geometry_msgs::Point &p2)