9 #include "geometry_msgs/Twist.h" 10 #include "geometry_msgs/Pose.h" 11 #include "geometry_msgs/PoseStamped.h" 12 #include <sensor_msgs/PointCloud.h> 13 #include <sensor_msgs/PointCloud2.h> 15 #include "nav_msgs/Odometry.h" 16 #include "rosaria/BumperState.h" 21 #include <dynamic_reconfigure/server.h> 22 #include <rosaria/RosAriaConfig.h> 23 #include "std_msgs/Float64.h" 24 #include "std_msgs/Float32.h" 25 #include "std_msgs/Int8.h" 26 #include "std_msgs/Bool.h" 27 #include "std_srvs/Empty.h" 58 void cmdvel_cb(
const geometry_msgs::TwistConstPtr &);
89 bool enable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response);
90 bool disable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response);
189 if(
TicksMM != config.TicksMM && config.TicksMM > 0)
191 ROS_INFO(
"Setting TicksMM from Dynamic Reconfigure: %d -> %d ",
TicksMM, config.TicksMM);
196 if(
DriftFactor != config.DriftFactor && config.DriftFactor != -99999)
198 ROS_INFO(
"Setting DriftFactor from Dynamic Reconfigure: %d -> %d ",
DriftFactor, config.DriftFactor);
203 if(
RevCount != config.RevCount && config.RevCount > 0)
205 ROS_INFO(
"Setting RevCount from Dynamic Reconfigure: %d -> %d ",
RevCount, config.RevCount);
214 value = config.trans_accel * 1000;
215 if(value !=
robot->getTransAccel() && value > 0)
217 ROS_INFO(
"Setting TransAccel from Dynamic Reconfigure: %d", value);
218 robot->setTransAccel(value);
221 value = config.trans_decel * 1000;
222 if(value !=
robot->getTransDecel() && value > 0)
224 ROS_INFO(
"Setting TransDecel from Dynamic Reconfigure: %d", value);
225 robot->setTransDecel(value);
228 value = config.lat_accel * 1000;
229 if(value !=
robot->getLatAccel() && value > 0)
231 ROS_INFO(
"Setting LatAccel from Dynamic Reconfigure: %d", value);
232 if (
robot->getAbsoluteMaxLatAccel() > 0 )
233 robot->setLatAccel(value);
236 value = config.lat_decel * 1000;
237 if(value !=
robot->getLatDecel() && value > 0)
239 ROS_INFO(
"Setting LatDecel from Dynamic Reconfigure: %d", value);
240 if (
robot->getAbsoluteMaxLatDecel() > 0 )
241 robot->setLatDecel(value);
244 value = config.rot_accel * 180/M_PI;
245 if(value !=
robot->getRotAccel() && value > 0)
247 ROS_INFO(
"Setting RotAccel from Dynamic Reconfigure: %d", value);
248 robot->setRotAccel(value);
251 value = config.rot_decel * 180/M_PI;
252 if(value !=
robot->getRotDecel() && value > 0)
254 ROS_INFO(
"Setting RotDecel from Dynamic Reconfigure: %d", value);
255 robot->setRotDecel(value);
268 robot->enableSonar();
273 robot->disableSonar();
345 robot->disableMotors();
346 robot->disableSonar();
348 robot->stopRunning();
349 robot->waitForRunExit();
358 robot =
new ArRobot();
359 ArArgumentBuilder *
args =
new ArArgumentBuilder();
360 ArArgumentParser *argparser =
new ArArgumentParser(args);
361 argparser->loadDefaultArguments();
368 if (colon_pos != std::string::npos)
370 args->add(
"-remoteHost");
371 args->add(
serial_port.substr(0, colon_pos).c_str());
372 args->add(
"-remoteRobotTcpPort");
373 args->add(
serial_port.substr(colon_pos+1).c_str());
389 args->add(
"-robotLogPacketsReceived");
390 args->add(
"-robotLogPacketsSent");
391 args->add(
"-robotLogVelocitiesReceived");
392 args->add(
"-robotLogMovementSent");
393 args->add(
"-robotLogMovementReceived");
399 conn =
new ArRobotConnector(argparser,
robot);
400 if (!conn->connectRobot()) {
401 ROS_ERROR(
"RosAria: ARIA could not connect to robot! (Check ~port parameter is correct, and permissions on port device, or any errors reported above)");
409 if(!Aria::parseArgs())
411 ROS_ERROR(
"RosAria: ARIA error parsing ARIA startup parameters!");
421 rosaria::RosAriaConfig dynConf_min;
422 rosaria::RosAriaConfig dynConf_max;
424 dynConf_max.trans_accel =
robot->getAbsoluteMaxTransAccel() / 1000;
425 dynConf_max.trans_decel =
robot->getAbsoluteMaxTransDecel() / 1000;
428 dynConf_max.lat_accel = ((
robot->getAbsoluteMaxLatAccel() > 0.0) ?
robot->getAbsoluteMaxLatAccel() : 0.1) / 1000;
429 dynConf_max.lat_decel = ((
robot->getAbsoluteMaxLatDecel() > 0.0) ?
robot->getAbsoluteMaxLatDecel() : 0.1) / 1000;
430 dynConf_max.rot_accel =
robot->getAbsoluteMaxRotAccel() * M_PI/180;
431 dynConf_max.rot_decel =
robot->getAbsoluteMaxRotDecel() * M_PI/180;
433 dynConf_min.trans_accel = 0;
434 dynConf_min.trans_decel = 0;
435 dynConf_min.lat_accel = 0;
436 dynConf_min.lat_decel = 0;
437 dynConf_min.rot_accel = 0;
438 dynConf_min.rot_decel = 0;
440 dynConf_min.TicksMM = 0;
441 dynConf_max.TicksMM = 200;
442 dynConf_min.DriftFactor = -99999;
443 dynConf_max.DriftFactor = 32767;
444 dynConf_min.RevCount = 0;
445 dynConf_max.RevCount = 65535;
451 rosaria::RosAriaConfig dynConf_default;
452 dynConf_default.trans_accel =
robot->getTransAccel() / 1000;
453 dynConf_default.trans_decel =
robot->getTransDecel() / 1000;
454 dynConf_default.lat_accel =
robot->getLatAccel() / 1000;
455 dynConf_default.lat_decel =
robot->getLatDecel() / 1000;
456 dynConf_default.rot_accel =
robot->getRotAccel() * M_PI/180;
457 dynConf_default.rot_decel =
robot->getRotDecel() * M_PI/180;
459 dynConf_default.TicksMM = 0;
460 dynConf_default.DriftFactor = -99999;
461 dynConf_default.RevCount = 0;
469 robot->enableMotors();
472 robot->disableSonar();
478 bumpers.front_bumpers.resize(
robot->getNumFrontBumpers());
479 bumpers.rear_bumpers.resize(
robot->getNumRearBumpers());
482 robot->runAsync(
true);
487 ROS_INFO_NAMED(
"rosaria",
"rosaria: Connecting to laser(s) configured in ARIA parameter file(s)...");
490 ROS_FATAL_NAMED(
"rosaria",
"rosaria: Error connecting to laser(s)...");
495 const std::map<int, ArLaser*> *lasers =
robot->getLaserMap();
496 ROS_INFO_NAMED(
"rosaria",
"rosaria: there are %lu connected lasers", lasers->size());
497 for(std::map<int, ArLaser*>::const_iterator i = lasers->begin(); i != lasers->end(); ++i)
499 ArLaser *l = i->second;
501 std::string tfname(
"laser");
502 if(lasers->size() > 1 || ln > 1)
505 ROS_INFO_NAMED(
"rosaria",
"rosaria: Creating publisher for laser #%d named %s with tf frame name %s", ln, l->getName(), tfname.c_str());
509 ROS_INFO_NAMED(
"rosaria",
"rosaria: Done creating laser publishers");
513 cmdvel_sub =
n.
subscribe(
"cmd_vel", 1, (boost::function <
void(
const geometry_msgs::TwistConstPtr&)>)
517 double cmdvel_timeout_param = 0.6;
518 n.
param(
"cmd_vel_timeout", cmdvel_timeout_param, 0.6);
520 if (cmdvel_timeout_param > 0.0)
540 position.twist.twist.angular.z =
robot->getRotVel()*M_PI/180;
547 ROS_DEBUG(
"RosAria: publish: (time %f) pose x: %f, pose y: %f, pose angle: %f; linear vel x: %f, vel y: %f; angular vel z: %f",
549 (double)
position.pose.pose.position.x,
550 (
double)
position.pose.pose.position.y,
551 (double)
position.pose.pose.orientation.w,
552 (
double)
position.twist.twist.linear.x,
553 (double)
position.twist.twist.linear.y,
554 (
double)
position.twist.twist.angular.z
570 int stall =
robot->getStallValue();
571 unsigned char front_bumpers = (
unsigned char)(stall >> 8);
572 unsigned char rear_bumpers = (
unsigned char)(stall);
577 std::stringstream bumper_info(std::stringstream::out);
579 for (
unsigned int i=0; i<
robot->getNumFrontBumpers(); i++)
581 bumpers.front_bumpers[i] = (front_bumpers & (1 << (i+1))) == 0 ? 0 : 1;
582 bumper_info <<
" " << (front_bumpers & (1 << (i+1)));
584 ROS_DEBUG(
"RosAria: Front bumpers:%s", bumper_info.str().c_str());
588 unsigned int numRearBumpers =
robot->getNumRearBumpers();
589 for (
unsigned int i=0; i<numRearBumpers; i++)
591 bumpers.rear_bumpers[i] = (rear_bumpers & (1 << (numRearBumpers-i))) == 0 ? 0 : 1;
592 bumper_info <<
" " << (rear_bumpers & (1 << (numRearBumpers-i)));
594 ROS_DEBUG(
"RosAria: Rear bumpers:%s", bumper_info.str().c_str());
600 std_msgs::Float64 batteryVoltage;
601 batteryVoltage.data =
robot->getRealBatteryVoltageNow();
604 if(
robot->haveStateOfCharge())
606 std_msgs::Float32 soc;
607 soc.data =
robot->getStateOfCharge()/100.0;
612 char s =
robot->getChargeState();
615 ROS_INFO(
"RosAria: publishing new recharge state %d.", s);
621 bool e =
robot->areMotorsEnabled();
624 ROS_INFO(
"RosAria: publishing new motors state %d.", e);
633 sensor_msgs::PointCloud cloud;
634 cloud.header.stamp =
position.header.stamp;
639 std::stringstream sonar_debug_info;
640 sonar_debug_info <<
"Sonar readings: ";
642 for (
int i = 0; i <
robot->getNumSonar(); i++) {
643 ArSensorReading* reading = NULL;
644 reading =
robot->getSonarReading(i);
646 ROS_WARN(
"RosAria: Did not receive a sonar reading.");
651 sonar_debug_info << reading->getRange() <<
" ";
665 geometry_msgs::Point32 p;
666 p.x = reading->getLocalX() / 1000.0;
667 p.y = reading->getLocalY() / 1000.0;
669 cloud.points.push_back(p);
677 sensor_msgs::PointCloud2 cloud2;
680 ROS_WARN(
"Error converting sonar point cloud message to point_cloud2 type before publishing! Not publishing this time.");
697 ROS_INFO(
"RosAria: Enable motors request.");
699 if(
robot->isEStopPressed())
700 ROS_WARN(
"RosAria: Warning: Enable motors requested, but robot also has E-Stop button pressed. Motors will not enable.");
701 robot->enableMotors();
709 ROS_INFO(
"RosAria: Disable motors request.");
711 robot->disableMotors();
721 ROS_INFO(
"new speed: [%0.2f,%0.2f](%0.3f)", msg->linear.x*1e3, msg->angular.z,
veltime.
toSec() );
724 robot->setVel(msg->linear.x*1e3);
725 if(
robot->hasLatVel())
726 robot->setLatVel(msg->linear.y*1e3);
727 robot->setRotVel(msg->angular.z*180/M_PI);
729 ROS_DEBUG(
"RosAria: sent vels to to aria (time %f): x vel %f mm/s, y vel %f mm/s, ang vel %f deg/s",
veltime.
toSec(),
730 (double) msg->linear.x * 1e3, (
double) msg->linear.y * 1.3, (double) msg->angular.z * 180/M_PI);
740 if(
robot->hasLatVel())
741 robot->setLatVel(0.0);
742 robot->setRotVel(0.0);
748 int main(
int argc,
char** argv )
756 if( node->
Setup() != 0 )
758 ROS_FATAL(
"RosAria: ROS node setup failed... \n" );
766 ROS_INFO(
"RosAria: Quitting... \n" );
ros::Duration cmdvel_timeout
bool enable_motors_cb(std_srvs::Empty::Request &request, std_srvs::Empty::Response &response)
#define ROS_INFO_NAMED(name,...)
void publish(const boost::shared_ptr< M > &message) const
std::string frame_id_bumper
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ros::ServiceServer enable_srv
geometry_msgs::TransformStamped odom_trans
ros::Subscriber cmdvel_sub
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void cmdvel_cb(const geometry_msgs::TwistConstPtr &)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
std_msgs::Int8 recharge_state
nav_msgs::Odometry position
std::string aria_log_filename
std::string frame_id_base_link
ROSCPP_DECL void spin(Spinner &spinner)
Node that interfaces between ROS and mobile robot base features via ARIA library. ...
std_msgs::Bool motors_state
bool publish_sonar_pointcloud2
RosAriaNode(ros::NodeHandle n)
static Quaternion createQuaternionFromYaw(double yaw)
void dynamic_reconfigureCB(rosaria::RosAriaConfig &config, uint32_t level)
ros::Publisher voltage_pub
bool published_motors_state
std::string frame_id_odom
ArLaserConnector * laserConnector
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
rosaria::BumperState bumpers
ros::Publisher sonar_pointcloud2_pub
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define ROS_DEBUG_STREAM(args)
int main(int argc, char **argv)
ros::ServiceServer disable_srv
uint32_t getNumSubscribers() const
static geometry_msgs::Quaternion createQuaternionMsgFromYaw(double yaw)
static void poseTFToMsg(const Pose &bt, geometry_msgs::Pose &msg)
static bool convertPointCloudToPointCloud2(const sensor_msgs::PointCloud &input, sensor_msgs::PointCloud2 &output)
ros::Timer cmdvel_watchdog_timer
ros::Publisher state_of_charge_pub
ArFunctorC< RosAriaNode > myPublishCB
bool disable_motors_cb(std_srvs::Empty::Request &request, std_srvs::Empty::Response &response)
ros::Publisher recharge_state_pub
bool getParam(const std::string &key, std::string &s) const
std::string frame_id_sonar
ros::Publisher bumpers_pub
#define ROS_FATAL_NAMED(name,...)
void cmdvel_watchdog(const ros::TimerEvent &event)
void sonarConnectCb()
Called when another node subscribes or unsubscribes from sonar topic.
ros::Publisher motors_state_pub
dynamic_reconfigure::Server< rosaria::RosAriaConfig > * dynamic_reconfigure_server
tf::TransformBroadcaster odom_broadcaster