00001 #include <robodyn_controllers/RosMsgForceTrajectoryFactory.h>
00002
00003 RosMsgForceTrajectoryFactory::RosMsgForceTrajectoryFactory()
00004 : logCategory("gov.nasa.controllers.RosMsgForceTrajectoryFactory")
00005 {
00006 }
00007
00008 boost::shared_ptr<RosMsgJointTrajectory> RosMsgForceTrajectoryFactory::getTrajectory(const sensor_msgs::JointState& jointPositions,
00009 const sensor_msgs::JointState& jointVels,
00010 const sensor_msgs::JointState& prevJointVels,
00011 const r2_msgs::PoseState& poseState,
00012 const r2_msgs::PoseState& poseVels,
00013 const r2_msgs::PoseTrajectory& goalTraj,
00014 const r2_msgs::ForceControlAxisArray& forceControlAxes) const
00015 {
00016 boost::shared_ptr<RosMsgJointTrajectory> trajPtr(new RosMsgJointTrajectory);
00017 trajPtr->setGoalId(goalTraj.header.stamp, goalTraj.header.frame_id);
00018 std::vector<std::string> jointNames;
00019 treeIk->getJointNames(jointNames);
00020 trajPtr->setJointNames(jointNames);
00021
00022 boost::shared_ptr<ForceTrajectory> ikTraj(new ForceTrajectory);
00023 ikTraj->setTreeIk(treeIk);
00024
00025
00026 std::map<std::string, std::pair<std::vector<int>, std::vector<double> > > forceControlMap;
00027
00028 if (forceControlAxes.nodes.size() != forceControlAxes.axes.size())
00029 {
00030 std::stringstream err;
00031 err << "forceControlAxis nodes and axis must have the same size!" << forceControlAxes.nodes.size() << " vs " << forceControlAxes.axes.size();
00032 NasaCommonLogging::Logger::log(logCategory, log4cpp::Priority::ERROR, err.str());
00033 throw std::runtime_error(err.str());
00034 }
00035
00036 for (unsigned int i = 0; i < forceControlAxes.nodes.size(); ++i)
00037 {
00038 if (forceControlAxes.axes[i].axis.size() != forceControlAxes.axes[i].magnitude.size())
00039 {
00040 std::stringstream err;
00041 err << "Node axis size and magnitude size must be the same! Axis size:" << forceControlAxes.axes[i].axis.size() << " Magnitude size: " << forceControlAxes.axes[i].magnitude.size();
00042 NasaCommonLogging::Logger::log(logCategory, log4cpp::Priority::ERROR, err.str());
00043 throw std::runtime_error(err.str());
00044 }
00045
00046 if (!forceControlAxes.axes[i].axis.empty())
00047 {
00048 forceControlMap[forceControlAxes.nodes[i]] = std::make_pair(std::vector<int>(forceControlAxes.axes.at(i).axis.begin(), forceControlAxes.axes.at(i).axis.end()),
00049 std::vector<double>(forceControlAxes.axes.at(i).magnitude.begin(), forceControlAxes.axes.at(i).magnitude.end()));
00050 }
00051 }
00052
00053 forceController->createForceControlMap(forceControlMap);
00054
00055
00056 KDL::JntArrayVel startVel(jointNames.size());
00057 KDL::JntArrayVel prevVel(jointNames.size());
00058 KDL::JntArrayAcc startJoints(jointNames.size());
00059
00060 try
00061 {
00062 RosMsgConverter::JointStateToJntArray(jointPositions, jointNames, startJoints.q);
00063 RosMsgConverter::JointStateToJntArrayVel(jointVels, jointNames, startVel);
00064 RosMsgConverter::JointStateToJntArrayVel(prevJointVels, jointNames, prevVel);
00065 }
00066 catch (std::exception& e)
00067 {
00068 NasaCommonLogging::Logger::log(logCategory, log4cpp::Priority::ERROR, e.what());
00069 }
00070
00071 startJoints.qdot = startVel.qdot;
00072 ros::Duration elapsedTime(jointVels.header.stamp - prevJointVels.header.stamp);
00073
00074 if (elapsedTime > ros::Duration(0.))
00075 {
00076 KDL::Subtract(startVel.qdot, prevVel.qdot, startJoints.qdotdot);
00077 KDL::Divide(startJoints.qdotdot, elapsedTime.toSec(), startJoints.qdotdot);
00078 }
00079
00080
00081 std::vector<KDL::FrameAcc> refPoses(goalTraj.nodes.size());
00082
00083 for (unsigned int i = 0; i < goalTraj.nodes.size(); ++i)
00084 {
00085 try
00086 {
00087 if (goalTraj.refFrames.size() == 1)
00088 {
00089 RosMsgConverter::PoseStateToFrameAcc(poseState, treeIk->getBaseName(), goalTraj.refFrames[0], refPoses[i]);
00090 }
00091 else
00092 {
00093 RosMsgConverter::PoseStateToFrameAcc(poseState, treeIk->getBaseName(), goalTraj.refFrames[i], refPoses[i]);
00094 }
00095 }
00096 catch (std::exception& e)
00097 {
00098 NasaCommonLogging::Logger::log(logCategory, log4cpp::Priority::ERROR, e.what());
00099 }
00100 }
00101
00102
00103 std::vector<KDL::FrameAcc> startPose(goalTraj.nodes.size());
00104 KDL::Frame frame;
00105
00106 for (unsigned int i = 0; i < goalTraj.nodes.size(); ++i)
00107 {
00108 try
00109 {
00110
00111 RosMsgConverter::PoseStateToFrameAcc(poseVels, treeIk->getBaseName(), goalTraj.nodes[i], startPose[i]);
00112 NasaCommonLogging::Logger::getCategory(logCategory) << log4cpp::Priority::DEBUG
00113 << "startPose[" << i << "] (" << goalTraj.nodes[i] << "): " << startPose[i].p.p.x() << ", " << startPose[i].p.p.y() << ", " << startPose[i].p.p.z()
00114 << ", " << startPose[i].M.R.GetRot().x() << ", " << startPose[i].M.R.GetRot().y() << ", " << startPose[i].M.R.GetRot().z()
00115 << "\n\t" << startPose[i].p.v.x() << ", " << startPose[i].p.v.y() << ", " << startPose[i].p.v.z()
00116 << ", " << startPose[i].M.dw.x() << ", " << startPose[i].M.dw.y() << ", " << startPose[i].M.dw.z();
00117 RosMsgConverter::PoseStateToFrame(poseState, treeIk->getBaseName(), goalTraj.nodes[i], frame);
00118 }
00119 catch (std::exception& e)
00120 {
00121 NasaCommonLogging::Logger::log(logCategory, log4cpp::Priority::ERROR, e.what());
00122 }
00123
00124 startPose[i].M.R = frame.M;
00125 startPose[i].p.p = frame.p;
00126 forceController->setInitialPose(goalTraj.nodes[i], frame);
00127 }
00128
00129
00130 std::vector<std::vector<KDL::FrameAcc> > goalPoses(goalTraj.points.size(), std::vector<KDL::FrameAcc>(goalTraj.nodes.size()));
00131 std::vector<double> durationTargets(goalTraj.points.size(), -1.);
00132
00133 for (unsigned int i = 0; i < goalPoses.size(); ++i)
00134 {
00135 if (goalTraj.points[i].positions.size() != goalTraj.nodes.size())
00136 {
00137 std::stringstream err;
00138 err << "RosMsgTreeIkTrajectoryFactory::getTrajectory() - A goal trajectory pose has mismatched size for nodes list";
00139 NasaCommonLogging::Logger::log("gov.nasa.controllers.RosMsgForceTrajectoryFactory", log4cpp::Priority::ERROR, err.str());
00140 throw std::runtime_error(err.str());
00141 }
00142
00143 for (unsigned int j = 0; j < goalTraj.nodes.size(); ++j)
00144 {
00145 goalPoses[i][j].p.p.x(goalTraj.points[i].positions[j].position.x);
00146 goalPoses[i][j].p.p.y(goalTraj.points[i].positions[j].position.y);
00147 goalPoses[i][j].p.p.z(goalTraj.points[i].positions[j].position.z);
00148 goalPoses[i][j].M.R = KDL::Rotation::Quaternion(goalTraj.points[i].positions[j].orientation.x,
00149 goalTraj.points[i].positions[j].orientation.y,
00150 goalTraj.points[i].positions[j].orientation.z,
00151 goalTraj.points[i].positions[j].orientation.w);
00152
00153
00154 if (goalTraj.points[i].velocities.size() == goalTraj.nodes.size())
00155 {
00156 goalPoses[i][j].p.v.x(goalTraj.points[i].velocities[j].linear.x);
00157 goalPoses[i][j].p.v.y(goalTraj.points[i].velocities[j].linear.y);
00158 goalPoses[i][j].p.v.z(goalTraj.points[i].velocities[j].linear.z);
00159 goalPoses[i][j].M.w.x(goalTraj.points[i].velocities[j].angular.x);
00160 goalPoses[i][j].M.w.y(goalTraj.points[i].velocities[j].angular.y);
00161 goalPoses[i][j].M.w.z(goalTraj.points[i].velocities[j].angular.z);
00162 }
00163
00164
00165 if (goalTraj.points[i].accelerations.size() == goalTraj.nodes.size())
00166 {
00167 goalPoses[i][j].p.dv.x(goalTraj.points[i].accelerations[j].linear.x);
00168 goalPoses[i][j].p.dv.y(goalTraj.points[i].accelerations[j].linear.y);
00169 goalPoses[i][j].p.dv.z(goalTraj.points[i].accelerations[j].linear.z);
00170 goalPoses[i][j].M.dw.x(goalTraj.points[i].accelerations[j].angular.x);
00171 goalPoses[i][j].M.dw.y(goalTraj.points[i].accelerations[j].angular.y);
00172 goalPoses[i][j].M.dw.z(goalTraj.points[i].accelerations[j].angular.z);
00173 }
00174
00175 goalPoses[i][j] = refPoses[j] * goalPoses[i][j];
00176 NasaCommonLogging::Logger::getCategory(logCategory) << log4cpp::Priority::DEBUG
00177 << "goalPoses[" << i << "][" << j << "] (" << goalTraj.nodes[j] << "): " << goalPoses[i][j].p.p.x() << ", " << goalPoses[i][j].p.p.y() << ", " << goalPoses[i][j].p.p.z()
00178 << ", " << goalPoses[i][j].M.R.GetRot().x() << ", " << goalPoses[i][j].M.R.GetRot().y() << ", " << goalPoses[i][j].M.R.GetRot().z();
00179 }
00180
00181 durationTargets[i] = goalTraj.points[i].time_from_start.toSec();
00182 }
00183
00184
00185 std::vector<KdlTreeIk::NodePriority> priorities(goalTraj.nodes.size());
00186
00187 if (goalTraj.node_priorities.size() != 0 && goalTraj.node_priorities.size() != goalTraj.nodes.size())
00188 {
00189 std::stringstream err;
00190 err << "invalid node_priorities size";
00191 NasaCommonLogging::Logger::log(logCategory, log4cpp::Priority::ERROR, err.str());
00192 throw std::runtime_error(err.str());
00193 }
00194
00195 for (unsigned int nodeIndex = 0; nodeIndex < goalTraj.node_priorities.size(); ++nodeIndex)
00196 {
00197 if (goalTraj.node_priorities[nodeIndex].axis_priorities.size() == 1)
00198 {
00199 for (unsigned int axisIndex = 0; axisIndex < 6; ++axisIndex)
00200 {
00201 priorities[nodeIndex][axisIndex] = static_cast<int>(goalTraj.node_priorities[nodeIndex].axis_priorities[0]);
00202 }
00203 }
00204 else
00205 {
00206 if (goalTraj.node_priorities[nodeIndex].axis_priorities.size() != 6)
00207 {
00208 std::stringstream err;
00209 err << "invalid axis_priorities size at node_priorities[" << nodeIndex << "]";
00210 NasaCommonLogging::Logger::log(logCategory, log4cpp::Priority::ERROR, err.str());
00211 throw std::runtime_error(err.str());
00212 }
00213
00214 for (unsigned int axisIndex = 0; axisIndex < 6; ++axisIndex)
00215 {
00216 priorities[nodeIndex][axisIndex] = static_cast<int>(goalTraj.node_priorities[nodeIndex].axis_priorities[axisIndex]);
00217 }
00218 }
00219 }
00220
00221 ikTraj->setCartesianHybCntrl(forceController);
00222 NasaCommonLogging::Logger::log("gov.nasa.controllers.RosMsgForceTrajectoryFactory", log4cpp::Priority::INFO, "setCartesianHybCntrl success");
00223
00224 ikTraj->setCartesianTrajectory(sequenceFactory->getTrajectory(startPose, goalPoses, durationTargets));
00225 ikTraj->setInitialJoints(startJoints);
00226 ikTraj->setNodeNames(goalTraj.nodes);
00227 ikTraj->setNodePriorities(priorities);
00228
00229 trajPtr->setTrajectory(ikTraj);
00230
00231 return trajPtr;
00232 }
00233