motor.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include "ssc32.hpp"
00003 #include "corobot_srvs/SetSpeed.h"
00004 #include "corobot_srvs/MoveArm.h"
00005 #include "corobot_msgs/ssc32_info.h"
00006 #include "corobot_msgs/MotorCommand.h"
00007 #include "corobot_msgs/ServoPosition.h"
00008 #include <math.h>
00009 #include <errno.h>
00010 #include <sys/stat.h>
00011 #include <diagnostic_updater/diagnostic_updater.h>
00012 #include <diagnostic_updater/publisher.h>
00013 
00014 
00015 using namespace Servo;
00016 
00017 SSC32 m_ssc32;
00018 
00019 std::string SSC32_PORT;
00020 ros::Timer timer;
00021 int ssc32Error = 0; // use for diagnostics purpose
00022 
00023 bool first_time_command[20] = {false};
00024 
00025 
00026 bool SetSpeed(corobot_srvs::SetSpeed::Request  &req, corobot_srvs::SetSpeed::Response &res )
00027 {
00028         bool ret;
00029         ret = m_ssc32.SendMessage(1,req.left_speed,req.speed);
00030         if (ret)
00031                 ssc32Error = 0;
00032         else
00033                 ssc32Error = 2;
00034         ret = m_ssc32.SendMessage(0,req.right_speed,req.speed); 
00035         if (ret)
00036                 ssc32Error = 0;
00037         else
00038                 ssc32Error = 2;
00039         return true;
00040 }
00041 
00042 
00043 void timerCallback(const ros::TimerEvent&)
00044 {
00045         bool ret;       
00046 
00047         m_ssc32.SendMessage(1,0,0);
00048         if (ret)
00049                 ssc32Error = 0;
00050         else
00051                 ssc32Error = 2;
00052 
00053         m_ssc32.SendMessage(0,0,0);
00054         if (ret)
00055                 ssc32Error = 0;
00056         else
00057                 ssc32Error = 2;
00058 }
00059 
00060 void SetSpeedTopic(const corobot_msgs::MotorCommand::ConstPtr &msg)
00061 {
00062         ros::NodeHandle n;
00063         bool ret;
00064 
00065         m_ssc32.SendMessage(1,(msg->leftSpeed*-5)+1500,(100-msg->acceleration)*10);
00066         if (ret)
00067                 ssc32Error = 0;
00068         else
00069                 ssc32Error = 2;
00070 
00071         m_ssc32.SendMessage(0,(msg->rightSpeed*-5)+1500,(100-msg->acceleration)*10);
00072         if (ret)
00073                 ssc32Error = 0;
00074         else
00075                 ssc32Error = 2;
00076 
00077         timer = n.createTimer(ros::Duration(msg->secondsDuration), timerCallback, true);
00078 }
00079 
00080 bool MoveArm(corobot_srvs::MoveArm::Request  &req, corobot_srvs::MoveArm::Response &res )
00081 {
00082   if(req.shoulderOrientation != 0)
00083   {
00084         int amount =  (int) (req.shoulderOrientation / M_PI * 1500) + 1500 - 1500 / 2;
00085         m_ssc32.SendMessage(4,amount,2000);
00086         return true;
00087   }
00088 
00089   if(req.elbowOrientation != 0)
00090   {
00091         int amount =  (int) ((req.elbowOrientation) / M_PI * 1500) + 1500 - 1500 / 2;
00092         m_ssc32.SendMessage(5,amount,2000);
00093         return true;
00094   }
00095   return false;
00096 
00097 }
00098 
00099 bool MoveWrist(corobot_srvs::MoveArm::Request  &req, corobot_srvs::MoveArm::Response &res )
00100 {       
00101         int amount =  (int) (req.wristOrientation / M_PI * 2000) + 1000 - 2000 / 2;
00102         m_ssc32.SendMessage(6,amount,2000);
00103         return true;
00104 }
00105 
00106 bool ResetArm(corobot_srvs::MoveArm::Request  &req, corobot_srvs::MoveArm::Response &res )
00107 {
00108         int amount =  (int) (req.shoulderOrientation / M_PI * 1500) + 1500 - 1500 / 2;
00109         m_ssc32.SendMessage(4,amount,2000);
00110 
00111         amount =  (int) (req.elbowOrientation / M_PI * 1500) + 1500 - 1500 / 2;
00112         m_ssc32.SendMessage(5,amount,2000);
00113         return true;
00114 }
00115 
00116 bool MoveGripper(corobot_srvs::MoveArm::Request  &req, corobot_srvs::MoveArm::Response &res )
00117 {
00118                 int amount;             
00119                 if (req.gripper == req.GRIPPER_OPEN)
00120                         amount = 1000;
00121                 else if (req.gripper == req.GRIPPER_CLOSED)
00122                         amount = 2000;
00123                 m_ssc32.SendMessage(7,amount,2000);
00124         
00125                 return true;
00126 }
00127 
00133 void setPositionCallback(const corobot_msgs::ServoPosition &msg)
00134 {
00135         int amount =  (int) (msg.position / 180 * 1500) + 750;  //ideally, msg.position is between 0 and 150 degrees
00136 
00137         // The first command should not contain any speed, so we are not sending any
00138         bool ok;
00139         if(first_time_command[msg.index] == false)
00140         {
00141                 ok = m_ssc32.SendMessage(msg.index,amount,-1);
00142                 first_time_command[msg.index] = true;
00143         }
00144         else
00145         {
00146                 ok = m_ssc32.SendMessage(msg.index,amount,2000);
00147         }
00148         
00149         if (!ok)
00150         {
00151                 ROS_ERROR("Could not set the servo motor number %d to the position %f",msg.index, msg.position);
00152                 ssc32Error = 2; 
00153         }
00154 }
00155 
00156 void ssc32_diagnostic(diagnostic_updater::DiagnosticStatusWrapper &stat)
00160 {
00161         if (!ssc32Error)  
00162                 stat.summaryf(diagnostic_msgs::DiagnosticStatus::OK, "initialized");
00163         else if (ssc32Error == 1)
00164         {
00165                 stat.summaryf(diagnostic_msgs::DiagnosticStatus::ERROR, "cannot be initialized");
00166                 stat.addf("Recommendation", "Please make sure the port path is the correct one.");
00167         }
00168         else if (ssc32Error == 2)
00169         {
00170                 stat.summaryf(diagnostic_msgs::DiagnosticStatus::ERROR, "cannot set speed");
00171                 stat.addf("Recommendation", "Please make sure the port path is the correct one. Also make sure the servo motors / motors are well connected to the ssc32 board");
00172         }
00173 }
00174 
00175 int main(int argc, char **argv)
00176 {
00177         ros::init(argc, argv, "ssc32_node");
00178         ros::NodeHandle n("~");
00179 
00180         //Declare services
00181         ros::ServiceServer speed = n.advertiseService("ssc32_set_speed", SetSpeed);
00182         ros::ServiceServer arm = n.advertiseService("/move_arm", MoveArm);
00183         ros::ServiceServer wrist = n.advertiseService("/move_wrist", MoveWrist);
00184         ros::ServiceServer gripper = n.advertiseService("/move_gripper", MoveGripper);
00185         ros::ServiceServer arm_reset = n.advertiseService("/reset_arm", ResetArm);
00186         ros::Publisher ssc32_info_pub = n.advertise<corobot_msgs::ssc32_info>("ssc32_info", 1000);
00187 
00188         //create an updater that will send information on the diagnostics topics
00189         diagnostic_updater::Updater updater;
00190         updater.setHardwareIDf("SSC32");
00191         updater.add("SSC32", ssc32_diagnostic); //function that will be executed with updater.update()
00192 
00193         //Subscribe to topics
00194         ros::Subscriber velocity=n.subscribe<corobot_msgs::MotorCommand>("/ssc32_velocity",1000, SetSpeedTopic);
00195         ros::Subscriber position_sub = n.subscribe("/setPositionServo",100, &setPositionCallback);
00196 
00197         std::string ssc32_port_;
00198 
00199         n.param<std::string>("ssc32_port", ssc32_port_, "/dev/ttyS1");
00200 
00201         if(!n.getParam("ssc32_port", ssc32_port_))
00202                 ROS_INFO("can not get parameter ssc32_port!");
00203 
00204         SSC32_PORT = ssc32_port_;
00205 
00206         // Let's give permission to do anything on the ssc32 port, or else we won't be able to use it.
00207         /*char mode[] = "0777";
00208         int i;
00209         i = strtol(mode, 0, 8);
00210         if (chmod (SSC32_PORT.c_str(),i) < 0)
00211         {
00212                 ROS_ERROR("%s: error in chmod(%s, %s) - %d (%s)\n", argv[0], SSC32_PORT.c_str(), mode, errno, strerror(errno));
00213         }
00214         */
00215         //Let's now initialize the ssc32 and connect to it
00216         m_ssc32.initSerial();
00217 
00218         if(m_ssc32.startSerial(SSC32_PORT))
00219         {
00220           ROS_INFO("Success!!! Connect to serial port");
00221           corobot_msgs::ssc32_info info;
00222           info.connected = 1;
00223           ssc32_info_pub.publish(info);
00224           ssc32Error = 0;
00225         }
00226         else
00227           ssc32Error = 1; 
00228 
00229         //main ros function
00230         while (ros::ok())
00231         {
00232                 ros::spinOnce();
00233                 updater.update();
00234         }
00235 
00236         m_ssc32.stopSerial();
00237         
00238         return 0;
00239 }


corobot_ssc32
Author(s): CoroWare/mcormier@coroware.com
autogenerated on Tue Jan 7 2014 11:38:55