aras_visual_servo_controller.cpp
Go to the documentation of this file.
00001 #include "aras_visual_servo_controller/aras_visual_servo_controller.h"
00002 VisualServoController::VisualServoController():jacobian_inverse_mat_(KERNEL_SIZE,DOF, cv::DataType<double>::type)
00003 {
00004     initializeSubscribers();
00005     initializePublishers();
00006 }
00007 
00008 bool VisualServoController::setJointPositions(float target_positions[JOINTS_NUM])
00009 {
00010     for(int i=0;i<JOINTS_NUM;i++)
00011     {
00012         std_msgs::Float64 msg;
00013         msg.data=target_positions[i];
00014         joint_pub_[i].publish(msg);
00015     }
00016     return true;
00017 }
00018 
00019 float *VisualServoController::getJointPositions()
00020 {
00021     return joints_position_;
00022 }
00023 
00024 void VisualServoController::setTargetPositions(float target_positions[JOINTS_NUM])
00025 {
00026 
00027     hardSetJointPosition(target_positions);
00028     camera_call_backed_ =false;
00029     while(camera_call_backed_ == false)
00030     {
00031         ros::spinOnce();
00032     }
00033     ROS_INFO("camera call backed");
00034     for(int i=0;i<KERNEL_SIZE;i++)
00035     {
00036         target_kernel_[i] = kernel_[i];
00037     }
00038     for(int i=0;i<KERNEL_SIZE;i++)
00039     {
00040         ROS_INFO("kernel target %d = %lf" ,i, kernel_[i]);
00041     }
00042 
00043 }
00044 
00045 void VisualServoController::setInitialPositions(float target_positions[])
00046 {
00047     hardSetJointPosition(target_positions);
00048     camera_call_backed_ =false;
00049     while(camera_call_backed_ == false)
00050     {
00051         ros::spinOnce();
00052     }
00053     for(int i=0;i<KERNEL_SIZE;i++)
00054     {
00055         ROS_INFO("kernel initial %d = %lf" ,i, kernel_[i]);
00056     }
00057 }
00058 
00059 void VisualServoController::hardSetJointPosition(float target_positions[JOINTS_NUM])
00060 {
00061     bool close_enough=true;
00062 
00063     //TODO set timeout
00064 
00065     while(true)
00066     {
00067         setJointPositions(target_positions);
00068         ros::spinOnce();
00069         for(int i=0;i<JOINTS_NUM;i++)
00070         {
00071             if(fabs((target_positions[i]-joints_position_[i]))>JOINTS_ERROR)
00072             {
00073                 close_enough =false;
00074 //                ROS_INFO("%lf %d",fabs((target_positions[i]-joints_position_[i])),i);
00075 //                ROS_INFO("%lf , %lf",target_positions[i],joints_position_[i]);
00076                 break;
00077             }
00078         }
00079         if(close_enough == true)
00080         {
00081             return;
00082         }
00083         close_enough = true;
00084 //        ROS_INFO("not close enough");
00085     }
00086 
00087     return;
00088 }
00089 
00090 void VisualServoController::initializeSubscribers()
00091 {
00092     joint_state_sub_ = nh_.subscribe("/aras_visual_servo/joint_states", 1, &VisualServoController::jointStateCB,this);
00093     camera_data_sub_ = nh_.subscribe("/aras_visual_servo/camera/data" , 1, &VisualServoController::cameraDataCB,this);
00094 
00095 }
00096 
00097 
00098 
00099 void VisualServoController::initializePublishers()
00100 {
00101     joint_pub_[0]=nh_.advertise<std_msgs::Float64>("/aras_visual_servo/gantry_position_controller/command",10);
00102     //because the joint 1 is constant we don't need to set it's position.
00103     for(int i=1;i<JOINTS_NUM;i++)
00104     {
00105         int k=i;
00106         if(i>=4)
00107             k++;
00108         std::stringstream pub_topic;
00109         pub_topic << "/aras_visual_servo/joint" << k << "_position_controller/command";
00110         joint_pub_[i]=nh_.advertise<std_msgs::Float64>(pub_topic.str().c_str(),10);
00111     }
00112 
00113 }
00114 
00115 void VisualServoController::jointStateCB(const sensor_msgs::JointStatePtr& joint_states)
00116 {
00117     for(int i=0;i<JOINTS_NUM-1;i++)
00118     {
00119         joints_position_[i+1]= joint_states->position[i];
00120     }
00121     joints_position_[0] = joint_states->position[JOINTS_NUM-1];
00122 }
00123 
00124 void VisualServoController::cameraDataCB(const std_msgs::Float64MultiArray::ConstPtr &camera_data_arr)
00125 {
00126 
00127     if(camera_data_arr->data.size() != CAMERA_DATA_SIZE)
00128     {
00129         ROS_ERROR("Camera Data Size is not %d" , CAMERA_DATA_SIZE);
00130         return;
00131     }
00132     camera_call_backed_ = true;
00133     for(int i=0;i<KERNEL_SIZE;i++)
00134     {
00135         for(int j=0;j<DOF;j++)
00136         {
00137             jacobian_inverse_mat_.at<double>(j,i) = camera_data_arr->data[(i*DOF+j)];
00138         }
00139     }
00140     for(int i=CAMERA_DATA_SIZE-KERNEL_SIZE;i<CAMERA_DATA_SIZE;i++)
00141     {
00142         kernel_[i-(CAMERA_DATA_SIZE-KERNEL_SIZE)] = camera_data_arr->data[i];
00143     }
00144 }
00145 
00146 void VisualServoController::executeControlAlgorithm()
00147 {
00148     while(ros::ok())
00149     {
00150 //        ROS_INFO("executeControlAlgorithm");
00151         float velocity_x = 0, velocity_y = 0;
00152 
00153 
00154         cv::Mat error(KERNEL_SIZE,1, cv::DataType<double>::type);
00155         cv::Mat control_signal(DOF,1, cv::DataType<double>::type);
00157         cv::Mat lambda(KERNEL_SIZE,KERNEL_SIZE, cv::DataType<double>::type);
00158         //TODO
00159         //replace it with memcpy
00160 
00161         for(int i=0;i<KERNEL_SIZE;i++)
00162         {
00163             for(int j=0;j<KERNEL_SIZE;j++)
00164             {
00165                 lambda.at<double>(i,j) = 0;
00166             }
00167         }
00168         lambda.at<double>(0,0) = LAMBDA_X;
00169         lambda.at<double>(1,1) = LAMBDA_Y;
00170         lambda.at<double>(2,2) = LAMBDA_Z;
00171         lambda.at<double>(3,3) = LAMBDA_THETA;
00172 
00173 
00174         for(int i=0;i<KERNEL_SIZE;i++)
00175         {
00176             error.at<double>(i,0) = kernel_[i] - target_kernel_[i] ;
00177         }
00178 
00179         control_signal = -1 * lambda * jacobian_inverse_mat_ * error;
00180         control_signal.at<double>(0,0) *= -1 ;
00181 
00182         velocity_x =  control_signal.at<double>(0,0);
00183         velocity_y =  control_signal.at<double>(1,0);
00184         control_signal.at<double>(0,0) = velocity_x*cos(((double)joints_position_[1] + (double)joints_position_[5]))
00185                 - velocity_y*sin(((double)joints_position_[1] + (double)joints_position_[5]));
00186         control_signal.at<double>(1,0) = velocity_x*sin(((double)joints_position_[1] + (double)joints_position_[5]))
00187                 + velocity_y*cos(((double)joints_position_[1] + (double)joints_position_[5]));
00188         float current_x,current_y,current_z,current_yaw;
00189         float desired_x,desired_y,desired_z,desired_yaw;
00190 
00191         //Calcute current position
00192         forwardKinematic(joints_position_, current_x, current_y, current_z, current_yaw);
00193 //        for(int i=0;i<DOF;i++)
00194 //        {
00195 //            ROS_INFO("error :%lf",error.at<double>(i,0));
00196 //        }
00197 
00198         //Integral velocity to convert to Position;
00199         desired_x = current_x + control_signal.at<double>(0,0)*SAMPLE_TIME;
00200         desired_y = current_y + control_signal.at<double>(1,0)*SAMPLE_TIME;
00201         desired_z = current_z + control_signal.at<double>(2,0)*SAMPLE_TIME;
00202         desired_yaw = current_yaw + control_signal.at<double>(3,0);
00203 
00204         float target_position[JOINTS_NUM];
00205         // Compute Target joints value(Inverse Kinematic)
00206 
00207         inverseKinematic(target_position, desired_x, desired_y, desired_z, desired_yaw);
00208 
00209         hardSetJointPosition(target_position);
00210         camera_call_backed_ =false;
00211         while(camera_call_backed_ == false)
00212         {
00213             ros::spinOnce();
00214         }
00215     }
00216 }
00217 
00218 void VisualServoController::inverseKinematic(float target_joints[JOINTS_NUM], float x, float y, float z, float a)
00219 {
00220     float delta, c_theta3, s_theta3, c_theta2, s_theta2;
00221     delta = z - L5 - L1;
00222     c_theta3 = (x*x + delta*delta - L2*L2 - L3*L3)/(2*L2*L3);
00223     s_theta3 = - sqrt(1 - c_theta3*c_theta3);
00224     c_theta2 = (L3*s_theta3*x + (L2 + L3*c_theta3)*delta)/(L2*L2 + L3*L3 + 2*L2*L3*c_theta3);
00225     s_theta2 = ((L2 + L3*c_theta3)*x - L3*s_theta3*delta)/(L2*L2 + L3*L3 + 2*L2*L3*c_theta3);
00226     target_joints[0] = y;//gantry
00227     target_joints[1] = 0; //theta1 is zero
00228     target_joints[2] = atan2(s_theta2, c_theta2); //theta2, Degree
00229     target_joints[3] = atan2(s_theta3, c_theta3); //theta3, Degree
00230     target_joints[4] =  -(target_joints[2] + target_joints[3]); //theta5 = -(theta2 + theta3), Degree
00231     target_joints[5] = a; //theta 1 is zero, so A change only with theta6
00232 }
00233 void VisualServoController::forwardKinematic(float target_joints[JOINTS_NUM], float &x, float &y, float &z, float &a)
00234 {
00235     float theta1 = target_joints[1];
00236     float theta2 = target_joints[2];
00237     float theta3 = target_joints[3];
00238     float theta5 = target_joints[4];
00239     float theta6 = target_joints[5];
00240     x = cos(theta1)*(L2*sin(theta2) + L3*sin(theta2 + theta3) + L5*sin(theta2 + theta3 + theta5));//m
00241     y = sin(theta1)*(L2*sin(theta2) + L3*sin(theta2 + theta3) + L5*sin(theta2 + theta3 + theta5)) + (target_joints[0]);//m
00242     z = L1 + L2*cos(theta2) + L3*cos(theta2 + theta3) + L5*cos(theta2 + theta3 + theta5);//m
00243     a = (theta1 + theta6);//radian
00244 }
00245 VisualServoController::~VisualServoController()
00246 {
00247 
00248 }


aras_visual_servo_controller
Author(s): Babak Sistani Zadeh , Javad Ramezan Zadeh , Parisa Masnadi , Ebrahim Abedloo , Prof. Hamid D. Taghirad
autogenerated on Thu Jun 6 2019 21:48:46