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;
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;
00136
00137
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
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
00189 diagnostic_updater::Updater updater;
00190 updater.setHardwareIDf("SSC32");
00191 updater.add("SSC32", ssc32_diagnostic);
00192
00193
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
00207
00208
00209
00210
00211
00212
00213
00214
00215
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
00230 while (ros::ok())
00231 {
00232 ros::spinOnce();
00233 updater.update();
00234 }
00235
00236 m_ssc32.stopSerial();
00237
00238 return 0;
00239 }