xbot_ros.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Yujin Robot.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Yujin Robot nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
35 /*****************************************************************************
36  ** Includes
37  *****************************************************************************/
38 
39 #include "xbot_node/xbot_ros.hpp"
40 #include <float.h>
41 #include <tf/tf.h>
42 #include <ecl/streams/string_stream.hpp>
43 #include <string>
44 
45 /*****************************************************************************
46  ** Namespaces
47  *****************************************************************************/
48 
49 namespace xbot {
50 
51 /*****************************************************************************
52  ** Implementation [XbotRos]
53  *****************************************************************************/
54 
60 XbotRos::XbotRos(std::string& node_name)
61  : name(node_name),
62  led_times_(0),
63  sound_enabled_(true),
64  motor_enabled_(true),
65  ypd_(0),
66  ppd_(0),
67  cmd_vel_timed_out_(false),
68  base_timeout_times_(0),
69  sensor_timeout_times_(0),
70  base_slot_stream_data(&XbotRos::processBaseStreamData, *this),
71  sensor_slot_stream_data(&XbotRos::processSensorStreamData, *this) {}
72 
79  ROS_INFO_STREAM("Xbot : waiting for xbot thread to finish [" << name << "].");
80  sound_enabled_ = false;
81  motor_enabled_ = false;
82  ypd_=0;
83  ppd_=0;
84  xbot.setLedControl(0);
85 }
86 
88  /*********************
89  ** Communications
90  **********************/
91  advertiseTopics(nh);
92  subscribeTopics(nh);
93 
94  /*********************
95  ** Slots
96  **********************/
97  base_slot_stream_data.connect(name + std::string("/base_stream_data"));
98  sensor_slot_stream_data.connect(name + std::string("/sensor_stream_data"));
99  /*********************
100  ** Driver Parameters
101  **********************/
102  Parameters parameters;
103 
104  nh.param("acceleration_limiter", parameters.enable_acceleration_limiter,
105  false);
106 
107  nh.param("led_indicate_battery", led_indicate_battery, true);
108 
109  parameters.sigslots_namespace =
110  name; // name is automatically picked up by device_nodelet parent.
111  if (!nh.getParam("base_port", parameters.base_port)) {
113  "Xbot : no base device port given on the parameter server (e.g. "
114  "/dev/ttyUSB0)["
115  << name << "].");
116  return false;
117  }
118 
119  if (!nh.getParam("sensor_port", parameters.sensor_port)) {
121  "Xbot : no sensor device port given on the parameter server (e.g. "
122  "/dev/ttyUSB0)["
123  << name << "].");
124  return false;
125  }
126 
127  /*********************
128  ** Joint States
129  **********************/
130  std::string robot_description, wheel_left_joint_name, wheel_right_joint_name;
131 
132  nh.param("wheel_left_joint_name", wheel_left_joint_name,
133  std::string("wheel_left_joint"));
134  nh.param("wheel_right_joint_name", wheel_right_joint_name,
135  std::string("wheel_right_joint"));
136 
137  // minimalistic check: are joint names present on robot description file?
138  if (!nh.getParam("/robot_description", robot_description)) {
139  ROS_WARN("Xbot : no robot description given on the parameter server");
140  } else {
141  if (robot_description.find(wheel_left_joint_name) == std::string::npos) {
142  ROS_WARN("Xbot : joint name %s not found on robot description",
143  wheel_left_joint_name.c_str());
144  }
145 
146  if (robot_description.find(wheel_right_joint_name) == std::string::npos) {
147  ROS_WARN("Xbot : joint name %s not found on robot description",
148  wheel_right_joint_name.c_str());
149  }
150  }
151  // joint_states.name.push_back(wheel_left_joint_name);
152  // joint_states.name.push_back(wheel_right_joint_name);
153  // joint_states.position.resize(2,0.0);
154  // joint_states.velocity.resize(2,0.0);
155  // joint_states.effort.resize(2,0.0);
156  joint_states.name.resize(4);
157  joint_states.position.resize(4);
158  joint_states.velocity.resize(2);
159  joint_states.name[0] = "left_wheel_hinge";
160  joint_states.name[1] = "right_wheel_hinge";
161  joint_states.name[2] = "base_to_yaw_platform";
162  joint_states.name[3] = "yaw_to_pitch_platform";
163  joint_states.position[0] = 0;
164  joint_states.position[1] = 0;
165  joint_states.position[2] = 0;
166  joint_states.position[3] = 0;
167 
168  /*********************
169  ** Validation
170  **********************/
171  if (!parameters.validate()) {
172  ROS_ERROR_STREAM("Xbot : parameter configuration failed [" << name << "].");
173  ROS_ERROR_STREAM("Xbot : " << parameters.error_msg << "[" << name << "]");
174  return false;
175  } else {
176  if (parameters.simulation) {
177  ROS_INFO("Xbot : driver going into loopback (simulation) mode.");
178  } else {
179  ROS_INFO_STREAM("Xbot : configured for connection on base_port "
180  << parameters.base_port << " [" << name << "].");
181  ROS_INFO_STREAM("Xbot : configured for connection on sensor_port "
182  << parameters.sensor_port << " [" << name << "].");
183  ROS_INFO_STREAM("Xbot : driver running in normal (non-simulation) mode"
184  << " [" << name << "].");
185  }
186  }
187 
188  odometry.init(nh, name);
189 
190  /*********************
191  ** Driver Init
192  **********************/
193  try {
194  xbot.init(parameters);
195 
196  // xbot.setBaseControl(0.4,0);
197 
198  ros::Duration(0.1).sleep(); // wait for some data to come in.
199  if (!xbot.base_isAlive()) {
201  "Xbot : no base data stream, is base board connected or turned on?");
202  // don't need to return false here - simply turning xbot on while
203  // spin()'ing should resurrect the situation.
204  }
205  if (!xbot.sensor_isAlive()) {
207  "Xbot : no sensor data stream, is sensor board connected or turned "
208  "on?");
209  // don't need to return false here - simply turning xbot on while
210  // spin()'ing should resurrect the situation.
211  }
212  xbot.enable();
213  } catch (const ecl::StandardException& e) {
214  switch (e.flag()) {
215  case (ecl::OpenError): {
216  ROS_ERROR_STREAM("Xbot : could not open connection ["
217  << parameters.base_port << "][" << name << "].");
218  ROS_ERROR_STREAM("Xbot : could not open connection ["
219  << parameters.sensor_port << "][" << name << "].");
220  break;
221  }
222  default: {
223  ROS_ERROR_STREAM("Xbot : initialisation failed [" << name << "].");
224  ROS_DEBUG_STREAM(e.what());
225  break;
226  }
227  }
228  return false;
229  }
230  // xbot.printSigSlotConnections();
231  xbot.setSoundEnableControl(true);
232  return true;
233 }
246  if (xbot.isShutdown()) {
247  ROS_ERROR_STREAM("Xbot : Driver has been shutdown. Stopping update loop. ["
248  << name << "].");
249  return false;
250  }
251 
252  if ((xbot.isEnabled() == true) && odometry.commandTimeout()) {
253  if (!cmd_vel_timed_out_) {
254  xbot.setBaseControl(0, 0);
255  cmd_vel_timed_out_ = true;
256  // ROS_ERROR("Xbot : Incoming velocity commands not received for more
257  // than %.2f seconds -> zero'ing velocity commands",
258  // odometry.timeout().toSec());
259  }
260  } else {
261  cmd_vel_timed_out_ = false;
262  }
263 
264  bool base_is_alive = xbot.base_isAlive();
265  if (!base_is_alive) {
267  if (!base_timeout_times_>40) {
269  "Xbot : Timed out while waiting for base serial data stream ["
270  << name << "].");
271  } else {
273  }
274  }
275 
276  bool sensor_is_alive = xbot.sensor_isAlive();
277  if (!sensor_is_alive) {
278  if (!sensor_timeout_times_>40) {
280  "Xbot : Timed out while waiting for sensor serial data stream ["
281  << name << "].");
282 
283  } else {
285  }
286  }
287 
288  return true;
289 }
290 
296  /*********************
297  ** Joint state publisher init
298  **********************/
300  nh.advertise<sensor_msgs::JointState>("joint_states", 100);
301 
302  /*********************
303  ** Xbot publisher init
304  **********************/
306  nh.advertise<xbot_msgs::CoreSensor>("sensors/core", 100);
308  nh.advertise<xbot_msgs::ExtraSensor>("sensors/extra", 100);
310  nh.advertise<std_msgs::Int8>("sensors/yaw_platform_degree", 100);
312  nh.advertise<std_msgs::Int8>("sensors/pitch_platform_degree", 100);
314  nh.advertise<std_msgs::Bool>("sensors/motor_enabled", 100);
316  nh.advertise<std_msgs::Bool>("sensors/sound_enabled", 100);
318  nh.advertise<xbot_msgs::Battery>("sensors/battery", 100);
319 
321  nh.advertise<sensor_msgs::Range>("sensors/front_echo", 100);
323  nh.advertise<sensor_msgs::Range>("sensors/rear_echo", 100);
325  nh.advertise<xbot_msgs::InfraRed>("sensors/infrared", 100);
326 
327  imu_data_publisher = nh.advertise<sensor_msgs::Imu>("/imu", 100);
329  nh.advertise<xbot_msgs::RawImu>("sensors/raw_imu_data", 100);
330  robot_state_publisher = nh.advertise<xbot_msgs::XbotState>("xbot/state", 100);
331 }
332 
339  nh.subscribe(std::string("commands/motor_enable"), 10,
342  nh.subscribe(std::string("commands/velocity"), 10,
345  nh.subscribe(std::string("commands/yaw_platform"), 10,
348  nh.subscribe(std::string("commands/pitch_platform"), 10,
351  nh.subscribe(std::string("commands/sound_enable"), 10,
353  led_command_subscriber = nh.subscribe(std::string("commands/led"), 10,
356  "commands/reset_odometry", 10, &XbotRos::subscribeResetOdometry, this);
357 }
358 
359 } // namespace xbot
ros::Publisher rear_echo_data_publisher
Definition: xbot_ros.hpp:125
ros::Subscriber velocity_command_subscriber
Definition: xbot_ros.hpp:135
sensor_msgs::JointState joint_states
Definition: xbot_ros.hpp:100
ros::Subscriber motor_enable_command_subscriber
Definition: xbot_ros.hpp:134
ros::Subscriber yaw_platform_command_subscriber
Definition: xbot_ros.hpp:136
ros::Publisher robot_state_publisher
Definition: xbot_ros.hpp:127
Wraps the xbot driver in a ROS-specific library.
ros::Publisher motor_state_publisher
Definition: xbot_ros.hpp:120
bool led_indicate_battery
Definition: xbot_ros.hpp:108
std::string base_port
std::string error_msg
ecl::Slot base_slot_stream_data
Definition: xbot_ros.hpp:160
const char * what() const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::string sensor_port
bool sound_enabled_
Definition: xbot_ros.hpp:132
bool init(ros::NodeHandle &nh)
Definition: xbot_ros.cpp:87
uint32_t base_timeout_times_
Definition: xbot_ros.hpp:104
void subscribePitchPlatformCommand(const std_msgs::Int8)
ros::Subscriber sound_command_subscriber
Definition: xbot_ros.hpp:138
ros::Publisher core_sensor_publisher
Definition: xbot_ros.hpp:115
std::string name
Definition: xbot_ros.hpp:98
ecl::Slot sensor_slot_stream_data
Definition: xbot_ros.hpp:161
ros::Publisher yaw_platform_state_publisher
Definition: xbot_ros.hpp:117
bool update()
Definition: xbot_ros.cpp:245
std::string sigslots_namespace
#define ROS_WARN(...)
void subscribeSoundCommand(const std_msgs::Bool)
bool commandTimeout() const
Definition: odometry.cpp:92
ros::Publisher battery_state_publisher
Definition: xbot_ros.hpp:119
ros::Publisher joint_state_publisher
Definition: xbot_ros.hpp:126
void subscribeResetOdometry(const std_msgs::EmptyConstPtr)
Play a predefined sound (single sound or sound sequence)
Standard exception type, provides code location and error string.
bool cmd_vel_timed_out_
Definition: xbot_ros.hpp:102
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ros::Subscriber pitch_platform_command_subscriber
Definition: xbot_ros.hpp:137
ros::Publisher infrared_data_publisher
Definition: xbot_ros.hpp:124
void advertiseTopics(ros::NodeHandle &nh)
Definition: xbot_ros.cpp:295
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
ros::Publisher sound_state_publisher
Definition: xbot_ros.hpp:121
ros::Publisher front_echo_data_publisher
Definition: xbot_ros.hpp:125
void connect(const std::string &topic)
ros::Publisher pitch_platform_state_publisher
Definition: xbot_ros.hpp:118
#define ROS_INFO_STREAM(args)
bool getParam(const std::string &key, std::string &s) const
XbotRos(std::string &node_name)
Default constructor.
Definition: xbot_ros.cpp:60
TimeStamp Duration
Convenience typedef to associate timestamps with the concept of durations.
Definition: duration.hpp:41
ros::Publisher imu_data_publisher
Definition: xbot_ros.hpp:122
void subscribeLedCommand(const std_msgs::UInt8)
ros::Publisher extra_sensor_publisher
Definition: xbot_ros.hpp:116
ros::Publisher raw_imu_data_publisher
Definition: xbot_ros.hpp:123
#define ROS_ERROR_STREAM(args)
uint32_t sensor_timeout_times_
Definition: xbot_ros.hpp:106
bool motor_enabled_
Definition: xbot_ros.hpp:132
ros::Subscriber led_command_subscriber
Definition: xbot_ros.hpp:139
Odometry odometry
Definition: xbot_ros.hpp:101
bool enable_acceleration_limiter
void subscribeYawPlatformCommand(const std_msgs::Int8)
void subscribeVelocityCommand(const geometry_msgs::TwistConstPtr)
void init(ros::NodeHandle &nh, const std::string &name)
Definition: odometry.cpp:32
ros::Subscriber reset_odometry_subscriber
Definition: xbot_ros.hpp:140
void subscribeTopics(ros::NodeHandle &nh)
Definition: xbot_ros.cpp:337
const ErrorFlag & flag() const
void subscribeMotorEnableCommand(const std_msgs::Bool)


xbot_node
Author(s): Roc, wangpeng@droid.ac.cn
autogenerated on Sat Oct 10 2020 03:28:13