Go to the documentation of this file.00001 #include <ros/ros.h>
00002 #include <riskrrt/PoseTwistStamped.h>
00003 #include <riskrrt/Trajectory.h>
00004 #include <geometry_msgs/Point.h>
00005 #include <geometry_msgs/Pose.h>
00006 #include <geometry_msgs/PoseStamped.h>
00007 #include <geometry_msgs/Twist.h>
00008 #include <geometry_msgs/PoseWithCovarianceStamped.h>
00009 #include <nav_msgs/Odometry.h>
00010 #include <tf/tf.h>
00011 #include <vector>
00012
00013 using namespace std;
00014
00015 geometry_msgs::Pose robot_pose;
00016 riskrrt::Trajectory trajectory;
00017
00018
00019
00020 geometry_msgs::Twist kanayama(geometry_msgs::Pose theoretical_pose, geometry_msgs::Pose estimated_pose, geometry_msgs::Twist control){
00021
00022 double delta_x, delta_y, delta_theta;
00023 double error_x, error_y, error_theta;
00024 double k_x, k_y, k_theta;
00025 geometry_msgs::Twist corrected_control;
00026
00027
00028 delta_x = theoretical_pose.position.x - estimated_pose.position.x;
00029 delta_y = theoretical_pose.position.y - estimated_pose.position.y;
00030 delta_theta = tf::getYaw(theoretical_pose.orientation) - tf::getYaw(estimated_pose.orientation);
00031
00032
00033 error_x = delta_x * cos(tf::getYaw(estimated_pose.orientation)) + delta_y * sin(tf::getYaw(estimated_pose.orientation));
00034 error_y = -delta_x * sin(tf::getYaw(estimated_pose.orientation)) + delta_y * cos(tf::getYaw(estimated_pose.orientation));
00035 error_theta = delta_theta;
00036
00037
00038 k_x = 0.15;
00039 k_y = 0.15;
00040 k_theta = 2 * sqrt(k_y);
00041
00042
00043 corrected_control.linear.x = control.linear.x * cos(error_theta) + k_x * error_x;
00044 corrected_control.angular.z = control.angular.z + control.linear.x * (k_y * error_y + k_theta * sin(error_theta));
00045
00046 return corrected_control;
00047 }
00048
00049
00050 geometry_msgs::Twist brake(){
00051
00052 geometry_msgs::Twist corrected_control;
00053
00054 corrected_control.linear.x = 0.0;
00055 corrected_control.angular.z = 0.0;
00056
00057 return corrected_control;
00058 };
00059
00060
00061
00062 geometry_msgs::Pose robotKinematic(geometry_msgs::Pose pose, geometry_msgs::Twist velocity, double duration){
00063 geometry_msgs::Pose new_pose;
00064 double rotation_radius;
00065 double delta_theta, delta_x, delta_y;
00066
00067 if(velocity.linear.x == 0.0){
00068 delta_theta = velocity.angular.z * duration;
00069 delta_x = 0.0;
00070 delta_y = 0.0;
00071 }
00072 else if(velocity.angular.z == 0.0){
00073 delta_theta = 0.0;
00074 delta_x = velocity.linear.x * duration;
00075 delta_y = 0.0;
00076 }
00077 else{
00078 rotation_radius = velocity.linear.x / velocity.angular.z;
00079 delta_theta = velocity.angular.z * duration;
00080 delta_x = rotation_radius * sin(delta_theta);
00081 delta_y = rotation_radius * (1.0 - cos(delta_theta));
00082 }
00083 new_pose.position.x = pose.position.x + (delta_x * cos(tf::getYaw(pose.orientation)) - delta_y * sin(tf::getYaw(pose.orientation)));
00084 new_pose.position.y = pose.position.y + (delta_x * sin(tf::getYaw(pose.orientation)) + delta_y * cos(tf::getYaw(pose.orientation)));
00085 new_pose.orientation = tf::createQuaternionMsgFromYaw(tf::getYaw(pose.orientation) + delta_theta);
00086
00087 return new_pose;
00088 }
00089
00090
00091 int interpolation(riskrrt::Trajectory trajectory, double timeStep){
00092
00093 int index;
00094 ros::Time present;
00095
00096 present = ros::Time::now();
00097
00098
00099 if(trajectory.poses.size() <= 1){
00100 index = -1;
00101 }
00102
00103 else if(trajectory.poses.front().time > present){
00104 index = -1;
00105 }
00106
00107 else if(trajectory.poses.back().time < present){
00108 index = -1;
00109 }
00110 else{
00111 index = floor((present - trajectory.poses.front().time).toSec() / timeStep);
00112 }
00113
00114 return index;
00115 }
00116
00117 void trajectoryCallback(const riskrrt::Trajectory::ConstPtr& msg){
00118 trajectory = *msg;
00119 }
00120
00121 void poseCallback(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& msg){
00122 robot_pose = msg->pose.pose;
00123 }
00124
00125 int main(int argc, char** argv){
00126
00127 ros::init(argc, argv, "riskrrt_controller");
00128
00129 ros::NodeHandle n;
00130
00131 geometry_msgs::Pose theoretical_pose;
00132 geometry_msgs::Twist raw_control;
00133 int index;
00134 double duration;
00135 double timeStep;
00136 geometry_msgs::Twist corrected_control;
00137 std_msgs::Bool controller_feedback;
00138
00139 n.param("timeStep", timeStep, 0.5);
00140
00141 ros::Publisher controlPublisher = n.advertise<geometry_msgs::Twist>("/cmd_vel", 100);
00142
00143 ros::Publisher controllerFeedbackPublisher = n.advertise<std_msgs::Bool>("controller_feedback",1);
00144
00145 ros::Subscriber trajectorySubscriber = n.subscribe("/traj", 1, trajectoryCallback);
00146 ros::Subscriber poseSubscriber = n.subscribe("/amcl_pose", 1, poseCallback);
00147
00148 ros::Rate loop_rate(20.0);
00149 trajectory.exists.data = false;
00150
00151 while(ros::ok()){
00152
00153 ros::spinOnce();
00154
00155 if(trajectory.exists.data){
00156
00157
00158 index = interpolation(trajectory, timeStep);
00159
00160 if(index != -1){
00161
00162
00163 duration = (ros::Time::now() - trajectory.poses[index].time).toSec();
00164
00165 theoretical_pose = robotKinematic(trajectory.poses[index].pose, trajectory.poses[index+1].twist, duration);
00166
00167 corrected_control = kanayama(theoretical_pose, robot_pose, trajectory.poses[index+1].twist);
00168
00169
00170 double pose_error = sqrt(pow(theoretical_pose.position.x - robot_pose.position.x, 2) + pow(theoretical_pose.position.y - robot_pose.position.y, 2));
00171 controller_feedback.data = (pose_error < 0.3);
00172
00173 }
00174 else{
00175 corrected_control = brake();
00176 controller_feedback.data = true;
00177 }
00178
00179 }
00180 else{
00181 corrected_control = brake();
00182 controller_feedback.data = true;
00183 }
00184
00185
00186 controlPublisher.publish(corrected_control);
00187
00188 controllerFeedbackPublisher.publish(controller_feedback);
00189
00190 loop_rate.sleep();
00191 }
00192
00193 return 0;
00194 }