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
00019 #include "descartes_trajectory_test/cartesian_robot.h"
00020 #include "descartes_core/pretty_print.hpp"
00021 #include "eigen_conversions/eigen_kdl.h"
00022 #include "ros/console.h"
00023 #include "ros/assert.h"
00024
00025 namespace descartes_trajectory_test
00026 {
00027 const static int DOF = 6;
00028
00029 static void displayRange(double pos_range, double orient_range)
00030 {
00031 double pos_limit = pos_range / 2.0;
00032 double orient_limit = orient_range / 2.0;
00033 ROS_INFO_STREAM("Creating Cartesian Robot with valid linear ranges from "
00034 << -pos_limit << " to " << pos_limit << ", and orientation from " << -orient_limit << " to "
00035 << orient_limit);
00036 }
00037
00038 CartesianRobot::CartesianRobot() : pos_range_(2.0), orient_range_(M_PI_2), joint_velocities_(DOF, 1.0)
00039 {
00040 displayRange(pos_range_, orient_range_);
00041 }
00042
00043 CartesianRobot::CartesianRobot(double pos_range, double orient_range, const std::vector<double> &joint_velocities)
00044 : pos_range_(pos_range), orient_range_(orient_range), joint_velocities_(joint_velocities)
00045 {
00046 ROS_ASSERT(joint_velocities_.size() == DOF);
00047 displayRange(pos_range_, orient_range_);
00048 }
00049
00050 bool CartesianRobot::initialize(const std::string &robot_description, const std::string &group_name,
00051 const std::string &world_frame, const std::string &tcp_frame)
00052 {
00053 return true;
00054 }
00055
00056 bool CartesianRobot::getIK(const Eigen::Affine3d &pose, const std::vector<double> &seed_state,
00057 std::vector<double> &joint_pose) const
00058 {
00059 bool rtn = false;
00060 KDL::Frame kdl_frame;
00061 tf::transformEigenToKDL(pose, kdl_frame);
00062
00063 joint_pose.resize(DOF, 0.0);
00064 joint_pose[0] = kdl_frame.p.x();
00065 joint_pose[1] = kdl_frame.p.y();
00066 joint_pose[2] = kdl_frame.p.z();
00067 kdl_frame.M.GetRPY(joint_pose[3], joint_pose[4], joint_pose[5]);
00068
00069 if (isValid(joint_pose))
00070 {
00071 rtn = true;
00072 }
00073 else
00074 {
00075 rtn = false;
00076 }
00077 return rtn;
00078 }
00079
00080 bool CartesianRobot::getAllIK(const Eigen::Affine3d &pose, std::vector<std::vector<double> > &joint_poses) const
00081 {
00082 std::vector<double> empty;
00083 joint_poses.resize(1);
00084 return getIK(pose, empty, joint_poses[0]);
00085 }
00086
00087 bool CartesianRobot::getFK(const std::vector<double> &joint_pose, Eigen::Affine3d &pose) const
00088 {
00089 bool rtn = false;
00090
00091 if (isValid(joint_pose))
00092 {
00093 pose = Eigen::Translation3d(joint_pose[0], joint_pose[1], joint_pose[2]) *
00094 Eigen::AngleAxisd(joint_pose[5], Eigen::Vector3d::UnitZ()) *
00095 Eigen::AngleAxisd(joint_pose[4], Eigen::Vector3d::UnitY()) *
00096 Eigen::AngleAxisd(joint_pose[3], Eigen::Vector3d::UnitX());
00097 rtn = true;
00098 }
00099 else
00100 {
00101 ROS_WARN_STREAM("Invalid joint pose passed to get FK, joint pose" << joint_pose);
00102 rtn = false;
00103 }
00104
00105 return rtn;
00106 }
00107
00108 int CartesianRobot::getDOF() const
00109 {
00110 return DOF;
00111 }
00112
00113 bool CartesianRobot::isValid(const std::vector<double> &joint_pose) const
00114 {
00115 bool rtn = false;
00116
00117 double pos_limit = pos_range_ / 2.0;
00118 double orient_limit = orient_range_ / 2.0;
00119
00120 if (DOF == joint_pose.size())
00121 {
00122 rtn = (fabs(joint_pose[0]) <= pos_limit && fabs(joint_pose[1]) <= pos_limit && fabs(joint_pose[2]) <= pos_limit &&
00123 fabs(joint_pose[3]) <= orient_limit && fabs(joint_pose[4]) <= orient_limit &&
00124 fabs(joint_pose[5]) <= orient_limit);
00125 }
00126 else
00127 {
00128 ROS_DEBUG_STREAM("Joint pose size: " << joint_pose.size() << "exceeds " << DOF);
00129 }
00130
00131 return rtn;
00132 }
00133
00134 bool CartesianRobot::isValid(const Eigen::Affine3d &pose) const
00135 {
00136 bool rtn = false;
00137 double R, P, Y;
00138 KDL::Frame kdl_frame;
00139 tf::transformEigenToKDL(pose, kdl_frame);
00140 kdl_frame.M.GetRPY(R, P, Y);
00141
00142 double pos_limit = pos_range_ / 2.0;
00143 double orient_limit = orient_range_ / 2.0;
00144
00145 rtn =
00146 (fabs(kdl_frame.p.x()) <= pos_limit && fabs(kdl_frame.p.y()) <= pos_limit && fabs(kdl_frame.p.z()) <= pos_limit &&
00147 fabs(R) <= orient_limit && fabs(P) <= orient_limit && fabs(Y) <= orient_limit);
00148
00149 return rtn;
00150 }
00151
00152 bool CartesianRobot::isValidMove(const std::vector<double> &from_joint_pose, const std::vector<double> &to_joint_pose,
00153 double dt) const
00154 {
00155 for (size_t i = 0; i < from_joint_pose.size(); ++i)
00156 {
00157 if (std::abs(from_joint_pose[i] - to_joint_pose[i]) / dt > joint_velocities_[i])
00158 return false;
00159 }
00160 return true;
00161 }
00162
00163 }