Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <ros/ros.h>
00031 #include "kurt3d/ServoCommand.h"
00032 #include <sensor_msgs/JointState.h>
00033 #include <sstream>
00034 #include "USBInterface.h"
00035 #include <iostream>
00036 #include <boost/thread.hpp>
00037 #define _USE_MATH_DEFINES
00038
00039 #define RAD(GRAD) ((GRAD * (float)M_PI) / (float)180)
00040
00041 #define SERVO_RANGE 1000
00042 #define SERVO_MIN 1000
00043
00044 static ros::Publisher state_pub;
00045
00046 static sensor_msgs::JointState currentState;
00047
00048 static double min_pos[5] =
00049 {
00050 RAD(-50.0),
00051 RAD(-65.0),
00052 RAD(-65.0),
00053 RAD(-50.0),
00054 RAD(-65.0)
00055 };
00056 static double max_pos[5] =
00057 {
00058 RAD(60.0),
00059 RAD(45.0),
00060 RAD(45.0),
00061 RAD(60.0),
00062 RAD(45.0)
00063 };
00064
00065 static std::string jointNames[5] =
00066 { "drehobjekt_1_to_balken_1",
00067 "servo_1_a_to_wing_1_a",
00068 "servo_1_b_to_wing_1_b",
00069 "servo_2_a_to_wing_2_a",
00070 "servo_2_b_to_wing_2_b"};
00071
00072
00073 boost::mutex& mut()
00074 {
00075 static boost::mutex m;
00076 return m;
00077 }
00078
00079 void setJointState(int channel, double angle)
00080 {
00081 currentState.header.stamp = ros::Time::now();
00082
00083 currentState.position[channel] = angle;
00084 }
00085
00086 void moveServo(const sensor_msgs::JointState& req, bool secure)
00087 {
00088 boost::lock_guard<boost::mutex> _(mut());
00089
00090 USBPololuInterface usb;
00091
00092 uscSettings settings;
00093 usb.setUscSettings(settings);
00094
00095 for(size_t i = 0; i < req.name.size(); i++)
00096 {
00097 ROS_INFO("Channel: [%s] Target: [%f] Speed: [%f]",req.name[i].c_str(),req.position[i],req.velocity[i]);
00098 int channel;
00099 for(channel = 0; channel < 5; channel++)
00100 if(req.name[i] == jointNames[channel])
00101 break;
00102
00103 if(channel == 5)
00104 continue;
00105
00106 double angle = req.position[i];
00107
00108 if(angle < min_pos[channel])
00109 {
00110 ROS_INFO("Required Angle out of range!");
00111 angle = min_pos[channel];
00112 }
00113
00114 else if(angle > max_pos[channel])
00115 {
00116 ROS_INFO("Required Angle out of range!");
00117 angle = max_pos[channel];
00118 }
00119
00120
00121 ushort speed = req.velocity[i] * 10;
00122 usb.setSpeed(channel, speed);
00123
00124 double target = angle;
00125
00126
00127 if(channel == 2 || channel == 4|| channel == 0) target *= -1.0;
00128
00129 target -= min_pos[channel];
00130
00131 target /= (max_pos[channel] - min_pos[channel]);
00132
00133 target *= SERVO_RANGE;
00134
00135 target += SERVO_MIN;
00136
00137 if(secure)
00138 {
00139 usb.moveToTarget(channel, target);
00140 }
00141 else
00142 {
00143 usb.setTarget(channel, target);
00144 }
00145
00146 setJointState(channel, angle);
00147 }
00148
00149 state_pub.publish(currentState);
00150
00151 std::cout << "Reported servo status: " << std::endl;
00152 }
00153
00154
00155 void servoCallback(const sensor_msgs::JointState::ConstPtr& req)
00156 {
00157 ROS_INFO("A servo movement was requested by topic");
00158 moveServo(*req, false);
00159 }
00160
00161
00162 bool nod(kurt3d::ServoCommand::Request &req,
00163 kurt3d::ServoCommand::Response &res)
00164 {
00165 ROS_INFO("A servo movement was requested by service");
00166 moveServo(req.joint_goal, true);
00167
00168 res.finished = true;
00169 return true;
00170 }
00171
00172 int main(int argc, char **argv)
00173 {
00174 ros::init(argc, argv, "servo_node");
00175
00176 ros::NodeHandle n;
00177
00178
00179 ros::ServiceServer service = n.advertiseService("servo_node", nod);
00180
00181
00182 state_pub = n.advertise<sensor_msgs::JointState>("joint_states", 1);
00183
00184
00185 ros::Subscriber sub = n.subscribe("servo_control", 5, servoCallback);
00186
00187
00188
00189 currentState = sensor_msgs::JointState();
00190 currentState.name.resize(5);
00191 currentState.position.resize(5);
00192
00193
00194 for (int i = 0; i < 5; i++)
00195 {
00196 setJointState(i, 0.0);
00197 currentState.name[i] = jointNames[i];
00198 }
00199
00200
00201 ROS_INFO("Ready to control servos.");
00202
00203 while(ros::ok())
00204 {
00205 {
00206 boost::lock_guard<boost::mutex> _(mut());
00207
00208 currentState.header.stamp = ros::Time::now();
00209 state_pub.publish(currentState);
00210 }
00211
00212 ros::spinOnce();
00213 }
00214
00215 return 0;
00216 }