local_multi_robot_controller_node.cpp
Go to the documentation of this file.
1 #include <ros/ros.h>
4 #include <string>
5 #include <algorithm>
6 
7 #define NSEC_2_SECS(A) ((float)A / 1000000000.0)
8 
9 int main(int argc, char **argv)
10 {
11  if (argc >= 2)
12  {
13  ros::init(argc, argv, "controller");
15 
17  return 0;
18  }
19  else
20  {
21  ROS_INFO("Please specifie name \nrosrun simple_velocity_controller velocity_controller [name]");
22  }
23 }
24 
25 namespace velocity_controller
26 {
28  n_param_("~"),
29  robot_names_(std::vector<std::string>({"robot0"}))
30 {
31  n_param_.param("nr_of_robots", nr_of_robots_, 0);
32  n_param_.param<std::string>("robot_prefix", robot_prefix_, "robot_");
33  std::string robot_names_string = "";
34  n_param_.param("robot_names_str", robot_names_string, robot_names_string);
35  if((nr_of_robots_ == 0) && robot_names_string.empty()) {
36  ROS_ERROR("The parameters nr_of_robots or robot_names_string need to be defined");
37  }
38  if((nr_of_robots_ > 0) && !robot_names_string.empty()) {
39  ROS_ERROR("One one of the parameters nr_of_robots or robot_names_string need to be defined");
40  }
41  if (robot_names_string.size() > 0)
42  {
43  robot_names_string.erase(std::remove(robot_names_string.begin(), robot_names_string.end(), ' '), robot_names_string.end());
44  std::istringstream stringStr(robot_names_string);
45  std::string result;
46  robot_names_.clear();
47  while (std::getline(stringStr, result, ','))
48  {
49  robot_names_.push_back(result);
50  }
51  nr_of_robots_ = robot_names_.size();
52  } else {
54  for(int i = 0; i < nr_of_robots_; i++){
55  robot_names_[i] = robot_prefix_ + std::to_string(i);
56  }
57 
58  }
59 
60  controller.resize(robot_names_.size());
61  active_robots.resize(robot_names_.size(),false);
62  pubCmdVel_.resize(robot_names_.size());
63  subCtrl_.resize(robot_names_.size());
64  subOdom_.resize(robot_names_.size());
65  subRoute_.resize(robot_names_.size());
66  robot_pose_.resize(robot_names_.size());
67 
68  n_param_.param("robot_radius", robot_radius_, robot_radius_);
69 
70  //Robot radius can also be set as string and as array in yaml file
71  float default_radius = 0.3;
72  n_param_.param("robot_default_radius", default_radius, default_radius);
73  robot_radius_.resize(robot_names_.size(), default_radius);
74 
75  topic_odom_ = "odom";
76  n.getParam("odom_topic", topic_odom_);
77 
78  topic_cmdVel_ = "cmd_vel";
79  n.getParam("cmd_vel_topic", topic_cmdVel_);
80 
81  topic_route_ = "route";
82  n.getParam("route_topic", topic_route_);
83 
84  topic_robot_info_ = "/robot_info";
85  n.getParam("robot_info_topic", topic_robot_info_);
86 
87  max_vel_v_ = 0.8;
88  n.getParam("max_v", max_vel_v_);
89 
90  max_vel_w_ = 1.0;
91  n.getParam("max_w", max_vel_w_);
92 
93  goal_r_ = 0.2;
94  n.getParam("goal_radius", goal_r_);
95 
96  Kp_val_ = 5.0;
97  n.getParam("Kp", Kp_val_);
98 
99  Ki_val_ = 0.0;
100  n.getParam("Ki", Ki_val_);
101 
102  Kd_val_ = 1.0;
103  n.getParam("Kd", Kd_val_);
104 
105  topic_ctrl_ = "/ctrl";
106  n.getParam("topic_control", topic_ctrl_);
107 
108  n_param_.param<std::string>("frame_map", frame_map_, "map");
109 
110  n_param_.param<double>("update_rate", update_rate_, 20.0);
111 
112  ROS_INFO("Multi Robot Controller: %s", topic_cmdVel_.c_str());
113 
114  for (auto &ctrl : controller)
115  {
116  ctrl.setSpeedParams(max_vel_v_, max_vel_w_);
117  ctrl.setPID(Kp_val_, Ki_val_, Kd_val_);
118  ctrl.setGoalRadius(goal_r_);
119  }
120 
121  for (int i = 0; i < robot_names_.size(); i++)
122  {
123  pubCmdVel_[i] = n.advertise<geometry_msgs::Twist>(robot_names_[i] + "/" + topic_cmdVel_, 1);
124  pubRobotInfo_ = n.advertise<tuw_multi_robot_msgs::RobotInfo>(topic_robot_info_, robot_names_.size() * 2);
125  subOdom_[i] = n.subscribe<nav_msgs::Odometry>(robot_names_[i] + "/" + topic_odom_, 1, boost::bind(&LocalMultiRobotControllerNode::subOdomCb, this, _1, i));
126  subRoute_[i] = n.subscribe<tuw_multi_robot_msgs::Route>(robot_names_[i] + "/" + topic_route_, 1, boost::bind(&LocalMultiRobotControllerNode::subRouteCb, this, _1, i));
127  subCtrl_[i] = n.subscribe<std_msgs::String>(robot_names_[i] + "/" + topic_ctrl_, 1, boost::bind(&LocalMultiRobotControllerNode::subCtrlCb, this, _1, i));
128  }
129  ros::Rate r(update_rate_);
130 
131  int sleep_count_robot_info = 0;
132  while (ros::ok())
133  {
134  r.sleep();
135  ros::spinOnce();
136  sleep_count_robot_info++;
137  if(sleep_count_robot_info > update_rate_) {
139  sleep_count_robot_info = 0;
140  }
141  }
142 
143 }
144 
146 {
147  const nav_msgs::Odometry_<std::allocator<void>>::ConstPtr &odom = _event.getMessage();
148  robot_pose_[_topic] = odom->pose;
149 
150  PathPoint pt;
151  pt.x = odom->pose.pose.position.x;
152  pt.y = odom->pose.pose.position.y;
153 
154  tf::Quaternion q(odom->pose.pose.orientation.x, odom->pose.pose.orientation.y, odom->pose.pose.orientation.z, odom->pose.pose.orientation.w);
155  tf::Matrix3x3 m(q);
156  double roll, pitch, yaw;
157  m.getRPY(roll, pitch, yaw);
158 
159  pt.theta = yaw;
160 
161  ros::Time time = ros::Time::now();
162  ros::Duration d = time - last_update_;
163 
164  float delta_t = d.sec + NSEC_2_SECS(d.nsec);
165  controller[_topic].update(pt, delta_t);
166  if (controller[_topic].getPlanActive())
167  {
168  active_robots[_topic] = true;
169  }
170  if (!controller[_topic].getPlanActive() && active_robots[_topic])
171  {
172  nr_of_finished_++;
173  active_robots[_topic] = false;
174  }
175 
176  geometry_msgs::Twist msg;
177 
178  float v, w;
179  controller[_topic].getSpeed(&v, &w);
180  msg.linear.x = v;
181  msg.angular.z = w;
182 
183  pubCmdVel_[_topic].publish(msg);
184 
185  //Update
186  PathPrecondition pc = {_topic, controller[_topic].getCount()};
187 
188  for (SegmentController &c : controller)
189  {
190  c.updatePrecondition(pc);
191  }
192 }
193 
195 {
196  const tuw_multi_robot_msgs::Route_<std::allocator<void>>::ConstPtr &path = _event.getMessage();
197 
198  std::vector<PathPoint> localPath;
199 
200  if (path->segments.size() == 0)
201  return;
202 
203  for (const tuw_multi_robot_msgs::RouteSegment &seg : path->segments)
204  {
205  PathPoint pt;
206 
207  pt.x = seg.end.position.x;
208  pt.y = seg.end.position.y;
209 
210  double roll, pitch, yaw;
211  tf::Quaternion q(seg.end.orientation.x, seg.end.orientation.y, seg.end.orientation.z, seg.end.orientation.w);
212  tf::Matrix3x3(q).getRPY(roll, pitch, yaw);
213  pt.theta = yaw;
214 
215  for (const tuw_multi_robot_msgs::RoutePrecondition &pc : seg.preconditions)
216  {
218  p.robot = findRobotId(pc.robot_id);
219  p.stepCondition = pc.current_route_segment;
220  pt.precondition.push_back(p);
221  }
222 
223  localPath.push_back(pt);
224  }
225 
226  controller[_topic].setPath(std::make_shared<std::vector<PathPoint>>(localPath));
227  ROS_INFO("Multi Robot Controller: Got Plan");
228 }
229 
231 {
232  for (uint32_t i = 0; i < robot_names_.size(); i++)
233  {
234  if (robot_names_[i].compare(_name) == 0)
235  return i;
236  }
237 
238  return -1;
239 }
240 
242 {
243  const std_msgs::String_<std::allocator<void>>::ConstPtr &cmd = _event.getMessage();
244  std::string s = cmd->data;
245 
246  ROS_INFO("Multi Robot Controller: received %s", s.c_str());
247 
248  if (s.compare("run") == 0)
249  {
250  controller[_topic].setState(run);
251  }
252  else if (s.compare("stop") == 0)
253  {
254  controller[_topic].setState(stop);
255  }
256  else if (s.compare("step") == 0)
257  {
258  controller[_topic].setState(step);
259  }
260  else
261  {
262  controller[_topic].setState(run);
263  }
264 }
265 
267 {
268  for (uint32_t i = 0; i < robot_names_.size(); i++)
269  {
270  tuw_multi_robot_msgs::RobotInfo ri;
271  ri.header.stamp = ros::Time::now();
272  ri.header.frame_id = frame_map_;
273  ri.robot_name = robot_names_[i];
274  ri.pose = robot_pose_[i];
275  ri.shape = ri.SHAPE_CIRCLE;
276  ri.shape_variables.push_back(robot_radius_[i]);
277  ri.sync.robot_id = robot_names_[i];
278  ri.sync.current_route_segment = controller[i].getCount();
279  ri.mode = ri.MODE_NA;
280  if (active_robots[i])
281  {
282  ri.status = ri.STATUS_DRIVING; //TODO other statuses
283  } else {
284  ri.status = ri.STATUS_STOPPED;
285  }
286  ri.good_id = ri.GOOD_NA;
287 
289  }
290 }
291 
292 } // namespace velocity_controller
d
LocalMultiRobotControllerNode(ros::NodeHandle &n)
Construct a new Multi Segment Controller Node object.
void publish(const boost::shared_ptr< M > &message) const
string cmd
XmlRpcServer s
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void subCtrlCb(const ros::MessageEvent< std_msgs::String const > &_event, int _topic)
void subRouteCb(const ros::MessageEvent< tuw_multi_robot_msgs::Route const > &_event, int _topic)
void getRPY(tfScalar &roll, tfScalar &pitch, tfScalar &yaw, unsigned int solution_number=1) const
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ROSCPP_DECL bool ok()
void subOdomCb(const ros::MessageEvent< nav_msgs::Odometry const > &_event, int _topic)
std::vector< geometry_msgs::PoseWithCovariance > robot_pose_
#define NSEC_2_SECS(A)
ros::NodeHandle n_param_
Node handler to the current node.
TFSIMD_FORCE_INLINE const tfScalar & w() const
int main(int argc, char **argv)
static Time now()
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
boost::shared_ptr< M > getMessage() const


tuw_multi_robot_ctrl
Author(s): Benjamin Binder
autogenerated on Mon Jun 10 2019 15:42:29