roomba500_lightweight.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *
00003 * Software License Agreement (BSD License)
00004 *
00005 *  Copyright (c) 2010, ISR University of Coimbra.
00006 *  All rights reserved.
00007 *
00008 *  Redistribution and use in source and binary forms, with or without
00009 *  modification, are permitted provided that the following conditions
00010 *  are met:
00011 *
00012 *   * Redistributions of source code must retain the above copyright
00013 *     notice, this list of conditions and the following disclaimer.
00014 *   * Redistributions in binary form must reproduce the above
00015 *     copyright notice, this list of conditions and the following
00016 *     disclaimer in the documentation and/or other materials provided
00017 *     with the distribution.
00018 *   * Neither the name of the ISR University of Coimbra nor the names of its
00019 *     contributors may be used to endorse or promote products derived
00020 *     from this software without specific prior written permission.
00021 *
00022 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 *  POSSIBILITY OF SUCH DAMAGE.
00034 *
00035 * Author: Gonçalo Cabrita on 07/10/2010
00036 *********************************************************************/
00037 #define NODE_VERSION 2.01
00038 
00039 #include <ros/ros.h>
00040 #include <tf/transform_broadcaster.h>
00041 #include <nav_msgs/Odometry.h>                  // odom
00042 #include <geometry_msgs/Twist.h>                // cmd_vel
00043 
00044 #include "roomba_500_series/OpenInterface.h"
00045 
00046 #include <string>
00047 
00048 std::string port;
00049 irobot::OpenInterface * roomba;
00050 
00051 
00052 std::string prefixTopic(std::string prefix, char * name)
00053 {
00054         std::string topic_name = prefix;
00055         topic_name.append(name);
00056         
00057         return topic_name;
00058 }
00059 
00060 void cmdVelReceived(const geometry_msgs::Twist::ConstPtr& cmd_vel)
00061 {
00062         roomba->drive(cmd_vel->linear.x, cmd_vel->angular.z);
00063 }
00064 
00065 
00066 int main(int argc, char** argv)
00067 {
00068         ros::init(argc, argv, "roomba560_light_node");
00069 
00070         ROS_INFO("Roomba for ROS %.2f", NODE_VERSION);
00071         
00072         double last_x, last_y, last_yaw;
00073         double vel_x, vel_y, vel_yaw;
00074         double dt;
00075 
00076         ros::NodeHandle n;
00077         
00078         n.param<std::string>("roomba/port", port, "/dev/ttyUSB0");
00079         
00080         roomba = new irobot::OpenInterface(port.c_str());
00081         
00082         ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("/odom", 50);
00083         tf::TransformBroadcaster odom_broadcaster;
00084         ros::Subscriber cmd_vel_sub  = n.subscribe<geometry_msgs::Twist>("/cmd_vel", 1, cmdVelReceived);
00085 
00086         if( roomba->openSerialPort(true) == 0) ROS_INFO("Connected to Roomba.");
00087         else
00088         {
00089                 ROS_FATAL("Could not connect to Roomba.");
00090                 ROS_BREAK();
00091         }
00092 
00093         ros::Time current_time, last_time;
00094         current_time = ros::Time::now();
00095         last_time = ros::Time::now();
00096 
00097         //int heartvalue = 0;
00098         //bool inc = true;
00099         
00100         ros::Rate r(10.0);
00101         while(n.ok())
00102         {
00103                 /*if(inc==true) heartvalue += 20;
00104                 else heartvalue -= 20;
00105                 if(heartvalue>=255)
00106                 {
00107                         heartvalue = 255;
00108                         inc=false;
00109                 }
00110                 if(heartvalue<=0)
00111                 {
00112                         heartvalue = 0;
00113                         inc=true;
00114                 }
00115                 roomba->setLeds(0, 0, 0, 0, (unsigned char)heartvalue, 255);*/
00116 
00117                 current_time = ros::Time::now();
00118                 
00119                 last_x = roomba->odometry_x_;
00120                 last_y = roomba->odometry_y_;
00121                 last_yaw = roomba->odometry_yaw_;
00122                 
00123                 if( roomba->getSensorPackets(100) == -1) ROS_ERROR("Could not retrieve sensor packets.");
00124                 else roomba->calculateOdometry();
00125                 
00126                 dt = (current_time - last_time).toSec();
00127                 vel_x = (roomba->odometry_x_ - last_x)/dt;
00128                 vel_y = (roomba->odometry_y_ - last_y)/dt;
00129                 vel_yaw = (roomba->odometry_yaw_ - last_yaw)/dt;
00130                 
00131                 //since all odometry is 6DOF we'll need a quaternion created from yaw
00132                 geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(roomba->odometry_yaw_);
00133                 
00134                 //first, we'll publish the transform over tf
00135                 geometry_msgs::TransformStamped odom_trans;
00136                 odom_trans.header.stamp = current_time;
00137                 odom_trans.header.frame_id = "odom";
00138                 odom_trans.child_frame_id = "base_link";
00139                 
00140                 odom_trans.transform.translation.x = roomba->odometry_x_;
00141                 odom_trans.transform.translation.y = roomba->odometry_y_;
00142                 odom_trans.transform.translation.z = 0.0;
00143                 odom_trans.transform.rotation = odom_quat;
00144                 
00145                 //send the transform
00146                 odom_broadcaster.sendTransform(odom_trans);
00147                 
00148                 //next, we'll publish the odometry message over ROS
00149                 nav_msgs::Odometry odom;
00150                 odom.header.stamp = current_time;
00151                 odom.header.frame_id = "odom";
00152                 
00153                 //set the position
00154                 odom.pose.pose.position.x = roomba->odometry_x_;
00155                 odom.pose.pose.position.y = roomba->odometry_y_;
00156                 odom.pose.pose.position.z = 0.0;
00157                 odom.pose.pose.orientation = odom_quat;
00158                 
00159                 //set the velocity
00160                 odom.child_frame_id = "base_link";
00161                 odom.twist.twist.linear.x = vel_x;
00162                 odom.twist.twist.linear.y = vel_y;
00163                 odom.twist.twist.angular.z = vel_yaw;
00164                 
00165                 //publish the message
00166                 odom_pub.publish(odom);
00167 
00168                 ros::spinOnce();
00169                 r.sleep();
00170         }
00171         
00172         roomba->powerDown();
00173         roomba->closeSerialPort();
00174 }
00175 
00176 // EOF


roomba_500_series
Author(s): Gonçalo Cabrita
autogenerated on Mon Jan 6 2014 11:26:40