00001 #include<ros/ros.h> 00002 #include<std_msgs/Float64.h> 00003 #include<stdio.h> 00004 #include<dynamixel_msgs/JointState.h> 00005 #include<cmath> 00006 00007 /* This program takes in numbers from the /commands topic and prepares them before publishing to the servo. The number 00008 on the /commands topic corresponds to a location on the servo's rotation in degrees. Each position is fixed 00009 (i.e. There is a 0 deg. position and a 180 deg. position. Sending a command of 180 will not necessarily make the motor 00010 turn 180 deg.). The program then converts the degree value into radians and publishes the value to the servo. The program 00011 also allows for enough time to pass prior to the next command to allow the servo to move */ 00012 00013 using namespace std; 00014 00015 //global variables 00016 float error = 1; 00017 int go = 0; 00018 float place; 00019 00020 //obtains error from message 00021 void obtainValues(const dynamixel_msgs::JointState &msg) 00022 { 00023 error = msg.error; 00024 } 00025 00026 //creates all commands for each motor 00027 class Dynamixel 00028 { 00029 private: 00030 ros::NodeHandle nh; 00031 ros::Publisher pub_n; 00032 public: 00033 Dynamixel(); 00034 void checkError(); 00035 void moveMotor(double position); 00036 }; 00037 00038 //creates publisher 00039 Dynamixel::Dynamixel() 00040 { 00041 pub_n = nh.advertise<std_msgs::Float64>("/tilt_controller/command", 10); 00042 } 00043 00044 //creates message and publishes -> degree to radian to publish 00045 void Dynamixel::moveMotor(double position) 00046 { 00047 double convert = (position * 3.14/180); 00048 std_msgs::Float64 aux; 00049 aux.data = convert; 00050 pub_n.publish(aux); 00051 //ROS_INFO_STREAM(aux); 00052 } 00053 00054 //ensures proper alignment 00055 void Dynamixel::checkError() 00056 { 00057 ros::spinOnce(); 00058 ROS_ERROR_STREAM(error); 00059 while(abs(error)>0.02) 00060 { 00061 ROS_INFO_STREAM("hi"); 00062 ros::Duration(0.5).sleep(); 00063 ROS_WARN_STREAM(error); 00064 ros::spinOnce(); 00065 00066 } 00067 } 00068 00069 //obtains requested position 00070 void transfer(const std_msgs::Float64 &msg) 00071 { 00072 place = msg.data; 00073 go = 1; 00074 } 00075 00076 //main 00077 int main (int argc, char **argv) 00078 { 00079 //initializes 00080 ros::init(argc, argv, "commander"); 00081 ros::NodeHandle nh; 00082 00083 //creates 1 Dynamixel named motor 00084 Dynamixel motor; 00085 00086 //subscribes to external requests 00087 ros::Subscriber sub_2=nh.subscribe("/commands", 1, &transfer); //external 00088 00089 ros::Subscriber sub=nh.subscribe("/tilt_controller/state", 5, &obtainValues); //checks error 00090 00091 //Wait for servo init by waiting for /state message 00092 ros::topic::waitForMessage<dynamixel_msgs::JointState>("/tilt_controller/state", ros::Duration(100)); 00093 00094 while(ros::ok()) 00095 { 00096 //if new request has been received 00097 if(go==1) 00098 { 00099 //move motor to request 00100 motor.moveMotor(place); 00101 ros::Duration(0.5).sleep(); 00102 motor.checkError(); 00103 ros::Duration(0.5).sleep(); //saftety break 00104 go = 0; 00105 } 00106 00107 else 00108 { 00109 ros::spinOnce(); 00110 } 00111 } 00112 }