26 m_mutex = PTHREAD_MUTEX_INITIALIZER;
35 std::string footprint_source;
36 if(!
nh_.
hasParam(
"footprint_source"))
ROS_WARN(
"Checking default location (/local_costmap_node/costmap) for initial footprint parameter.");
37 nh_.
param(
"footprint_source", footprint_source, std::string(
"/local_costmap_node/costmap"));
45 ROS_WARN(
"You have set more than 4 points as robot_footprint, cob_footprint_observer can deal only with rectangular footprints so far!");
49 ROS_WARN(
"No epsilon value specified. Changes in footprint smaller than epsilon are neglected. Using default [0.01m]!");
53 if(!
nh_.
hasParam(
"frames_to_check"))
ROS_WARN(
"No frames to check for footprint observer. Only using initial footprint!");
56 if(!
nh_.
hasParam(
"robot_base_frame"))
ROS_WARN(
"No parameter robot_base_frame on parameter server. Using default [/base_link].");
70 geometry_msgs::PolygonStamped footprint_poly;
81 resp.footprint = footprint_poly;
82 resp.success.data =
true;
89 std::vector<geometry_msgs::Point> footprint;
90 geometry_msgs::Point pt;
93 std::string padding_param, footprint_param;
94 if(!node.
searchParam(
"footprint_padding", padding_param))
97 node.
param(padding_param, padding, 0.01);
101 std::string footprint_string;
102 std::vector<std::string> footstring_list;
103 if(node.
searchParam(
"footprint", footprint_param)){
104 node.
getParam(footprint_param, footprint_list);
106 footprint_string = std::string(footprint_list);
109 if(footprint_string ==
"[]" || footprint_string ==
"")
112 boost::erase_all(footprint_string,
" ");
114 boost::char_separator<char> sep(
"[]");
115 boost::tokenizer<boost::char_separator<char> > tokens(footprint_string, sep);
116 footstring_list = std::vector<std::string>(tokens.begin(), tokens.end());
121 ROS_FATAL(
"The footprint must be specified as list of lists on the parameter server, %s was specified as %s",
122 footprint_param.c_str(), std::string(footprint_list).c_str());
123 throw std::runtime_error(
"The footprint must be specified as list of lists on the parameter server with at least 3 points eg: [[x1, y1], [x2, y2], ..., [xn, yn]]");
127 for(
int i = 0; i < footprint_list.
size(); ++i){
131 ROS_FATAL(
"The footprint must be specified as list of lists on the parameter server eg: [[x1, y1], [x2, y2], ..., [xn, yn]], but this spec is not of that form");
132 throw std::runtime_error(
"The footprint must be specified as list of lists on the parameter server eg: [[x1, y1], [x2, y2], ..., [xn, yn]], but this spec is not of that form");
137 ROS_FATAL(
"Values in the footprint specification must be numbers");
138 throw std::runtime_error(
"Values in the footprint specification must be numbers");
141 pt.x +=
sign(pt.x) * padding;
145 ROS_FATAL(
"Values in the footprint specification must be numbers");
146 throw std::runtime_error(
"Values in the footprint specification must be numbers");
149 pt.y +=
sign(pt.y) * padding;
151 footprint.push_back(pt);
154 std::ostringstream oss;
156 BOOST_FOREACH(geometry_msgs::Point p, footprint) {
158 oss <<
"[[" << p.x <<
"," << p.y <<
"]";
162 oss <<
",[" << p.x <<
"," << p.y <<
"]";
166 node.
setParam(footprint_param, oss.str().c_str());
167 node.
setParam(
"footprint", oss.str().c_str());
172 std::vector<geometry_msgs::Point> footprint_spec;
173 bool valid_foot =
true;
174 BOOST_FOREACH(std::string t, footstring_list) {
176 boost::erase_all(t,
" ");
177 boost::char_separator<char> pt_sep(
",");
178 boost::tokenizer<boost::char_separator<char> > pt_tokens(t, pt_sep);
179 std::vector<std::string> point(pt_tokens.begin(), pt_tokens.end());
181 if(point.size() != 2) {
182 ROS_WARN(
"Each point must have exactly 2 coordinates");
187 std::vector<double>tmp_pt;
188 BOOST_FOREACH(std::string p, point) {
189 std::istringstream iss(p);
192 tmp_pt.push_back(temp);
195 ROS_WARN(
"Each coordinate must convert to a double.");
203 geometry_msgs::Point pt;
207 footprint_spec.push_back(pt);
211 footprint = footprint_spec;
212 node.
setParam(
"footprint", footprint_string);
215 ROS_FATAL(
"This footprint is not vaid it must be specified as a list of lists with at least 3 points, you specified %s", footprint_string.c_str());
216 throw std::runtime_error(
"The footprint must be specified as list of lists on the parameter server with at least 3 points eg: [[x1, y1], [x2, y2], ..., [xn, yn]]");
223 for(
unsigned int i=0; i<footprint.size(); i++) {
229 ROS_DEBUG(
"Extracted rectangular footprint for cob_footprint_observer: Front: %f, Rear %f, Left: %f, Right %f",
233 ROS_WARN(
"Footprint has no physical dimension!");
249 std::stringstream ss;
252 double x_rear, x_front, y_left, y_right;
258 bool missing_frame_exists =
false;
268 if(frame_position.
x() > x_front) x_front = frame_position.
x();
269 if(frame_position.
x() < x_rear) x_rear = frame_position.
x();
270 if(frame_position.
y() > y_left) y_left = frame_position.
y();
271 if(frame_position.
y() < y_right) y_right = frame_position.
y();
275 missing_frame_exists =
true;
276 ROS_WARN(
"Footprint Observer: Transformation for %s not available! Frame %s not considered in adjusted footprint!",
277 frame.c_str(), frame.c_str());
280 if (missing_frame_exists)
295 pthread_mutex_unlock(&
m_mutex);
298 geometry_msgs::Point point;
299 std::vector<geometry_msgs::Point> points;
304 points.push_back(point);
306 points.push_back(point);
308 points.push_back(point);
310 points.push_back(point);
314 pthread_mutex_unlock(&
m_mutex);
326 geometry_msgs::PolygonStamped footprint_poly;
344 if(x >= 0.0
f)
return 1.0f;
350 int main(
int argc,
char** argv)
353 ros::init(argc,argv,
"footprint_observer");
360 while(footprintObserver.
nh_.
ok()){
void publish(const boost::shared_ptr< M > &message) const
bool deleteParam(const std::string &key) const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
Type const & getType() const
TFSIMD_FORCE_INLINE const tfScalar & y() const
TFSIMD_FORCE_INLINE const tfScalar & x() const
bool searchParam(const std::string &key, std::string &result) const
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
TFSIMD_FORCE_INLINE const tfScalar & y() const
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool getParam(const std::string &key, std::string &s) const
bool hasParam(const std::string &key) const
ROSCPP_DECL void spinOnce()
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const