trajectory_interpolator.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
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     // Interpolate the linear path
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      // Needed for the circle direction!
00107      if (Se < 0)
00108      {
00109          forward = false;
00110      }
00111      else
00112      {
00113          forward = true;
00114      }
00115      Se = std::fabs(Se);
00116 
00117      // Calculates the Path with RAMP or SINOID profile
00118      if (!this->trajectory_profile_generator_->calculateProfile(path_matrix, Se, 0))
00119      {
00120          return false;
00121      }
00122 
00123      path_array = path_matrix[0];
00124      // Define Center Pose
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      // Interpolate the circular path
00130      for (unsigned int i = 0; i < path_array.size(); i++)
00131      {
00132          // Rotate T
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          // Calculate TCP Position
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 }


cob_cartesian_controller
Author(s): Christoph Mark
autogenerated on Thu Jun 6 2019 21:19:40