00001 #include <robodyn_controllers/RosMsgTrajectoryFactory.h>
00002
00003 static const double eps = std::numeric_limits<float>::epsilon();
00004
00005 void RosMsgJointTrajectoryFactory::setSettings(const r2_msgs::ControllerJointSettings& settings)
00006 {
00007 motionLimiter.setLimits(settings.joint_names, settings.jointVelocityLimits, settings.jointAccelerationLimits);
00008 }
00009
00010 void RosMsgJointTrajectoryFactory::getSettings(r2_msgs::ControllerJointSettings& settings)
00011 {
00012 motionLimiter.getAllLimits(settings.joint_names, settings.jointVelocityLimits, settings.jointAccelerationLimits);
00013 }
00014
00015 void RosMsgJointTrajectoryFactory::setLimits(const std::vector<std::string>& jointNames, double velLim, double accLim)
00016 {
00017 motionLimiter.setLimits(jointNames, velLim, accLim);
00018 }
00019
00020 void RosMsgJointTrajectoryFactory::setPositionLimiter(boost::shared_ptr<JointNamePositionLimiter> posLimiter)
00021 {
00022 positionLimiter = posLimiter;
00023 }
00024
00025 boost::shared_ptr<RosMsgJointTrajectory> RosMsgJointTrajectoryFactory::getTrajectory(const sensor_msgs::JointState& jointPositions,
00026 const sensor_msgs::JointState& jointVels,
00027 const sensor_msgs::JointState& prevJointVels,
00028 const trajectory_msgs::JointTrajectory& goalTraj)
00029 {
00030 boost::shared_ptr<RosMsgJointTrajectory> trajPtr(new RosMsgJointTrajectory);
00031 trajPtr->setGoalId(goalTraj.header.stamp, goalTraj.header.frame_id);
00032 trajPtr->setJointNames(goalTraj.joint_names);
00033
00034
00035 motionLimiter.reorderLimits(goalTraj.joint_names);
00036
00037 KDL::JntArrayVel startVel(goalTraj.joint_names.size());
00038 KDL::JntArrayVel prevVel(goalTraj.joint_names.size());
00039 KDL::JntArrayAcc startPose(goalTraj.joint_names.size());
00040
00041
00042 RosMsgConverter::JointStateToJntArray(jointPositions, goalTraj.joint_names, startPose.q);
00043 RosMsgConverter::JointStateToJntArrayVel(jointVels, goalTraj.joint_names, startVel);
00044 RosMsgConverter::JointStateToJntArrayVel(prevJointVels, goalTraj.joint_names, prevVel);
00045
00046 startPose.qdot = startVel.qdot;
00047 ros::Duration elapsedTime(jointVels.header.stamp - prevJointVels.header.stamp);
00048
00049 if (elapsedTime > ros::Duration(0.))
00050 {
00051 KDL::Subtract(startVel.qdot, prevVel.qdot, startPose.qdotdot);
00052 KDL::Divide(startPose.qdotdot, elapsedTime.toSec(), startPose.qdotdot);
00053 }
00054
00055 std::vector<KDL::JntArrayAcc> goalPoses(goalTraj.points.size(), KDL::JntArrayAcc(goalTraj.joint_names.size()));
00056 std::vector<double> durationTargets(goalTraj.points.size(), -1.);
00057
00058 for (unsigned int i = 0; i < goalPoses.size(); ++i)
00059 {
00060 if (goalTraj.points[i].positions.size() != goalTraj.joint_names.size())
00061 {
00062 std::stringstream err;
00063 err << "RosMsgJointTrajectoryFactory::getTrajectory() - A goal trajectory pose has mismatched size for joint_names list";
00064 NasaCommonLogging::Logger::log("gov.nasa.controllers.RosMsgJointTrajectoryFactory", log4cpp::Priority::ERROR, err.str());
00065 throw std::runtime_error(err.str());
00066 }
00067
00068 for (unsigned int j = 0; j < goalTraj.joint_names.size(); ++j)
00069 {
00070 goalPoses[i].q(j) = goalTraj.points[i].positions[j];
00071
00072 if (goalTraj.points[i].velocities.size() == goalTraj.joint_names.size())
00073 {
00074 goalPoses[i].qdot(j) = goalTraj.points[i].velocities[j];
00075 }
00076
00077 if (goalTraj.points[i].accelerations.size() == goalTraj.joint_names.size())
00078 {
00079 goalPoses[i].qdotdot(j) = goalTraj.points[i].accelerations[j];
00080 }
00081
00083 if (positionLimiter->hasLimits(goalTraj.joint_names[j]) &&
00084 positionLimiter->limit(goalTraj.joint_names[j], goalPoses[i].q(j)))
00085 {
00087 goalPoses[i].qdot(j) = 0.;
00088 goalPoses[i].qdotdot(j) = 0.;
00090 KDL::JntArrayAcc iPose;
00091
00092 if (i == 0)
00093 {
00094 iPose = startPose;
00095 }
00096 else
00097 {
00098 iPose = goalPoses[i - 1];
00099 }
00100
00101 double aLim = 0;
00102
00103 if (fabs(goalPoses[i].qdot(j) - iPose.qdot(j)) > eps)
00104 {
00105 aLim = fabs(0.5 * iPose.qdot(j) * iPose.qdot(j) / (goalPoses[i].qdot(j) - iPose.qdot(j)));
00106 }
00107
00108 if (aLim > motionLimiter.getAccelerationLimit(goalTraj.joint_names[j]))
00109 {
00110 std::vector<std::string> jointName;
00111 jointName.push_back(goalTraj.joint_names[j]);
00112 motionLimiter.setLimits(jointName, motionLimiter.getVelocityLimit(goalTraj.joint_names[j]), aLim);
00113 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.RosMsgJointTrajectoryFactory") << log4cpp::Priority::NOTICE << "set acceleration limit to " << aLim;
00114 }
00115
00116 std::stringstream ss;
00117 ss << "Goal Pose limited for " << goalTraj.joint_names[j];
00118 ss << " calculated acceleration limit: " << aLim << std::endl;
00119 ss << " current acceleration limit: " << motionLimiter.getAccelerationLimit(goalTraj.joint_names[j]) << std::endl;
00120 NasaCommonLogging::Logger::log("gov.nasa.controllers.RosMsgJointTrajectoryFactory", log4cpp::Priority::INFO, ss.str());
00121 }
00122 }
00123
00124 durationTargets[i] = goalTraj.points[i].time_from_start.toSec();
00125 }
00126
00127 NasaCommonLogging::Logger::log("gov.nasa.controllers.RosMsgJointTrajectoryFactory", log4cpp::Priority::INFO, "setting joint trajectory");
00128 trajPtr->setTrajectory(sequenceFactory.getTrajectory(startPose, goalPoses, durationTargets));
00129
00130 return trajPtr;
00131 }
00132
00133 void RosMsgCartesianTrajectoryFactory::setSettings(const r2_msgs::ControllerPoseSettings& settings)
00134 {
00135 factory->setVelocityLimits(settings.maxLinearVelocity, settings.maxRotationalVelocity);
00136 factory->setAccelerationLimits(settings.maxLinearAcceleration, settings.maxRotationalAcceleration);
00137 }
00138
00139 boost::shared_ptr<RosMsgSynchedCartesianTrajectory> RosMsgCartesianTrajectoryFactory::getTrajectory(const r2_msgs::PoseState& poseState,
00140 const r2_msgs::PoseTrajectory& goalTraj)
00141 {
00142 boost::shared_ptr<RosMsgSynchedCartesianTrajectory> trajPtr(new RosMsgSynchedCartesianTrajectory);
00143 trajPtr->setGoalId(goalTraj.header.stamp, goalTraj.header.frame_id);
00144
00145
00146 if (goalTraj.nodes.empty())
00147 {
00148 std::stringstream err;
00149 err << "RosMsgCartesianTrajectoryFactory::getTrajectory() - No nodes provided";
00150 NasaCommonLogging::Logger::log("gov.nasa.controllers.RosMsgCartesianTrajectoryFactory", log4cpp::Priority::ERROR, err.str());
00151 throw std::runtime_error(err.str());
00152 }
00153 else if (goalTraj.refFrames.size() != goalTraj.nodes.size() && goalTraj.refFrames.size() != 1)
00154 {
00155 std::stringstream err;
00156 err << "RosMsgCartesianTrajectoryFactory::getTrajectory() - refFrames size invalid";
00157 NasaCommonLogging::Logger::log("gov.nasa.controllers.RosMsgCartesianTrajectoryFactory", log4cpp::Priority::ERROR, err.str());
00158 throw std::runtime_error(err.str());
00159 }
00160
00161 trajPtr->setNodeNames(goalTraj.nodes);
00162 trajPtr->setRefFrames(goalTraj.refFrames);
00163 trajPtr->setPriorities(goalTraj.node_priorities);
00164
00165
00166 std::vector<KDL::FrameAcc> startPoses(goalTraj.nodes.size());
00167 KDL::Frame tempPose;
00168
00169 for (unsigned int i = 0; i < goalTraj.nodes.size(); ++i)
00170 {
00171 if (goalTraj.refFrames.size() == 1)
00172 {
00173
00174 RosMsgConverter::PoseStateToFrame(poseState, goalTraj.refFrames.at(0), goalTraj.nodes[i], tempPose);
00175 }
00176 else
00177 {
00178
00179 RosMsgConverter::PoseStateToFrame(poseState, goalTraj.refFrames.at(i), goalTraj.nodes[i], tempPose);
00180 }
00181
00182 startPoses[i].p.p = tempPose.p;
00183 startPoses[i].M.R = tempPose.M;
00184 }
00185
00186 std::vector<std::vector<KDL::FrameAcc> > goalPoses(goalTraj.points.size(), std::vector<KDL::FrameAcc>(goalTraj.nodes.size()));
00187 std::vector<double> durationTargets(goalTraj.points.size(), -1.);
00188
00189 for (unsigned int i = 0; i < goalPoses.size(); ++i)
00190 {
00191 if (goalTraj.points[i].positions.size() != goalTraj.nodes.size())
00192 {
00193 std::stringstream err;
00194 err << "RosMsgCartesianTrajectoryFactory::getTrajectory() - A goal trajectory pose has mismatched size for nodes list";
00195 NasaCommonLogging::Logger::log("gov.nasa.controllers.RosMsgCartesianTrajectoryFactory", log4cpp::Priority::ERROR, err.str());
00196 throw std::runtime_error(err.str());
00197 }
00198
00199 for (unsigned int j = 0; j < goalTraj.nodes.size(); ++j)
00200 {
00201 goalPoses[i][j].p.p.x(goalTraj.points[i].positions[j].position.x);
00202 goalPoses[i][j].p.p.y(goalTraj.points[i].positions[j].position.y);
00203 goalPoses[i][j].p.p.z(goalTraj.points[i].positions[j].position.z);
00204 goalPoses[i][j].M.R = KDL::Rotation::Quaternion(goalTraj.points[i].positions[j].orientation.x,
00205 goalTraj.points[i].positions[j].orientation.y,
00206 goalTraj.points[i].positions[j].orientation.z,
00207 goalTraj.points[i].positions[j].orientation.w);
00208
00209
00210 if (goalTraj.points[i].velocities.size() == goalTraj.nodes.size())
00211 {
00212 goalPoses[i][j].p.v.x(goalTraj.points[i].velocities[j].linear.x);
00213 goalPoses[i][j].p.v.y(goalTraj.points[i].velocities[j].linear.y);
00214 goalPoses[i][j].p.v.z(goalTraj.points[i].velocities[j].linear.z);
00215 goalPoses[i][j].M.w.x(goalTraj.points[i].velocities[j].angular.x);
00216 goalPoses[i][j].M.w.y(goalTraj.points[i].velocities[j].angular.y);
00217 goalPoses[i][j].M.w.z(goalTraj.points[i].velocities[j].angular.z);
00218 }
00219
00220
00221 if (goalTraj.points[i].accelerations.size() == goalTraj.nodes.size())
00222 {
00223 goalPoses[i][j].p.dv.x(goalTraj.points[i].accelerations[j].linear.x);
00224 goalPoses[i][j].p.dv.y(goalTraj.points[i].accelerations[j].linear.y);
00225 goalPoses[i][j].p.dv.z(goalTraj.points[i].accelerations[j].linear.z);
00226 goalPoses[i][j].M.dw.x(goalTraj.points[i].accelerations[j].angular.x);
00227 goalPoses[i][j].M.dw.y(goalTraj.points[i].accelerations[j].angular.y);
00228 goalPoses[i][j].M.dw.z(goalTraj.points[i].accelerations[j].angular.z);
00229 }
00230 }
00231
00232 durationTargets[i] = goalTraj.points[i].time_from_start.toSec();
00233 }
00234
00235 NasaCommonLogging::Logger::log("gov.nasa.controllers.RosMsgJointTrajectoryFactory", log4cpp::Priority::INFO, "setting cartesian trajectory");
00236 trajPtr->setTrajectory(sequenceFactory.getTrajectory(startPoses, goalPoses, durationTargets));
00237
00238 return trajPtr;
00239 }
00240