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 #include <math.h>
00019 #include <vector>
00020
00021 #include <cob_cartesian_controller/trajectory_interpolator/trajectory_interpolator.h>
00022 #include <cob_cartesian_controller/trajectory_profile_generator/trajectory_profile_generator_builder.h>
00023
00024 bool TrajectoryInterpolator::linearInterpolation(geometry_msgs::PoseArray& pose_array,
00025 const cob_cartesian_controller::CartesianActionStruct as)
00026 {
00027 this->trajectory_profile_generator_.reset(TrajectoryProfileBuilder::createProfile(as));
00028
00029 pose_array.header.stamp = ros::Time::now();
00030 pose_array.header.frame_id = root_frame_;
00031
00032 tf::Quaternion q_start, q_end;
00033
00034 std::vector<double> linear_path, angular_path, path;
00035 std::vector<double> path_matrix[2];
00036 geometry_msgs::Pose pose;
00037
00038 double norm_factor;
00039 tf::quaternionMsgToTF(as.move_lin.start.orientation, q_start);
00040 tf::quaternionMsgToTF(as.move_lin.end.orientation, q_end);
00041
00042 double Se_lin = sqrt(pow((as.move_lin.end.position.x - as.move_lin.start.position.x), 2) +
00043 pow((as.move_lin.end.position.y - as.move_lin.start.position.y), 2) +
00044 pow((as.move_lin.end.position.z - as.move_lin.start.position.z), 2));
00045
00046 double Se_rot = q_start.angleShortestPath(q_end);
00047
00048 if (!trajectory_profile_generator_->calculateProfile(path_matrix, Se_lin, Se_rot))
00049 {
00050 return false;
00051 }
00052
00053 linear_path = path_matrix[0];
00054 angular_path = path_matrix[1];
00055
00056 if (fabs(linear_path.back()) > fabs(angular_path.back()))
00057 {
00058 path = linear_path;
00059 }
00060 else
00061 {
00062 path = angular_path;
00063 }
00064 norm_factor = 1/path.back();
00065
00066
00067 for (unsigned int i = 0; i < linear_path.size(); i++)
00068 {
00069 if (linear_path.back() == 0)
00070 {
00071 pose.position.x = as.move_lin.start.position.x;
00072 pose.position.y = as.move_lin.start.position.y;
00073 pose.position.z = as.move_lin.start.position.z;
00074 }
00075 else
00076 {
00077 pose.position.x = as.move_lin.start.position.x + linear_path.at(i) * (as.move_lin.end.position.x - as.move_lin.start.position.x) / linear_path.back();
00078 pose.position.y = as.move_lin.start.position.y + linear_path.at(i) * (as.move_lin.end.position.y - as.move_lin.start.position.y) / linear_path.back();
00079 pose.position.z = as.move_lin.start.position.z + linear_path.at(i) * (as.move_lin.end.position.z - as.move_lin.start.position.z) / linear_path.back();
00080 }
00081
00082 tf::quaternionTFToMsg(q_start.slerp(q_end, path.at(i) * norm_factor), pose.orientation);
00083 pose_array.poses.push_back(pose);
00084 }
00085 return true;
00086 }
00087
00088 bool TrajectoryInterpolator::circularInterpolation(geometry_msgs::PoseArray& pose_array,
00089 const cob_cartesian_controller::CartesianActionStruct as)
00090 {
00091 pose_array.header.stamp = ros::Time::now();
00092 pose_array.header.frame_id = root_frame_;
00093
00094 tf::Quaternion q;
00095 tf::Transform C, P, T;
00096
00097 std::vector<double> path_array;
00098 std::vector<double> path_matrix[2];
00099
00100 geometry_msgs::Pose pose;
00101
00102 double Se = as.move_circ.end_angle - as.move_circ.start_angle;
00103
00104 bool forward;
00105
00106
00107 if (Se < 0)
00108 {
00109 forward = false;
00110 }
00111 else
00112 {
00113 forward = true;
00114 }
00115 Se = std::fabs(Se);
00116
00117
00118 if (!this->trajectory_profile_generator_->calculateProfile(path_matrix, Se, 0))
00119 {
00120 return false;
00121 }
00122
00123 path_array = path_matrix[0];
00124
00125 C.setOrigin(tf::Vector3(as.move_circ.pose_center.position.x, as.move_circ.pose_center.position.y, as.move_circ.pose_center.position.z));
00126 tf::quaternionMsgToTF(as.move_circ.pose_center.orientation, q);
00127 C.setRotation(q);
00128
00129
00130 for (unsigned int i = 0; i < path_array.size(); i++)
00131 {
00132
00133 T.setOrigin(tf::Vector3(cos(path_array.at(i)) * as.move_circ.radius, 0, sin(path_array.at(i)) * as.move_circ.radius));
00134
00135 if (forward)
00136 {
00137 T.setOrigin(tf::Vector3(cos(path_array.at(i)) * as.move_circ.radius, 0, sin(path_array.at(i)) * as.move_circ.radius));
00138 q.setRPY(0, -path_array.at(i), 0);
00139 }
00140 else
00141 {
00142 T.setOrigin(tf::Vector3(cos(as.move_circ.start_angle - path_array.at(i)) * as.move_circ.radius, 0, sin(as.move_circ.start_angle - path_array.at(i)) * as.move_circ.radius));
00143 q.setRPY(0, path_array.at(i), 0);
00144 }
00145
00146 T.setRotation(q);
00147
00148
00149 P = C * T;
00150
00151 tf::pointTFToMsg(P.getOrigin(), pose.position);
00152 tf::quaternionTFToMsg(P.getRotation(), pose.orientation);
00153
00154 pose_array.poses.push_back(pose);
00155 }
00156
00157 return true;
00158 }