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
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <youbot_oodl/youbot_trajectory_action_server/joint_trajectory_action.h>
00041 #include <youbot_oodl/youbot_trajectory_action_server/joint_state_observer.h>
00042
00043 #include <brics_actuator/JointPositions.h>
00044 #include <brics_actuator/JointVelocities.h>
00045
00046 #include <kdl/trajectory_composite.hpp>
00047 #include <kdl/trajectory_segment.hpp>
00048 #include <kdl/velocityprofile_spline.hpp>
00049 #include <kdl/path_line.hpp>
00050 #include <kdl/rotational_interpolation_sa.hpp>
00051
00052 #include <boost/units/systems/angle/degrees.hpp>
00053 #include <boost/units/conversion.hpp>
00054 #include <boost/units/systems/si/length.hpp>
00055 #include <boost/units/systems/si/plane_angle.hpp>
00056 #include <boost/units/systems/si/angular_velocity.hpp>
00057
00058 JointTrajectoryAction::JointTrajectoryAction(JointStateObserver* jointStateObserver) :
00059 jointStateObserver(jointStateObserver)
00060 {
00061
00062 setPositionGain(0.1);
00063 setVelocityGain(1.0);
00064 setFrequency(50);
00065
00066 }
00067
00068 JointTrajectoryAction::JointTrajectoryAction(JointStateObserver* jointStateObserver, double positionGain,
00069 double velocityGain, double frequency) :
00070 jointStateObserver(jointStateObserver)
00071 {
00072
00073 setFrequency(frequency);
00074 setPositionGain(positionGain);
00075 setVelocityGain(velocityGain);
00076
00077 }
00078
00079 JointTrajectoryAction::JointTrajectoryAction(const JointTrajectoryAction& orig) :
00080 jointStateObserver(orig.jointStateObserver)
00081 {
00082
00083 setPositionGain(orig.getPositionGain());
00084 setVelocityGain(orig.getVelocityGain());
00085 setFrequency(orig.getFrequency());
00086 }
00087
00088 JointTrajectoryAction::~JointTrajectoryAction()
00089 {
00090
00091 }
00092
00093 void JointTrajectoryAction::setFrequency(double frequency)
00094 {
00095 this->frequency = frequency;
00096 }
00097
00098 double JointTrajectoryAction::getFrequency() const
00099 {
00100 return frequency;
00101 }
00102
00103 void JointTrajectoryAction::setVelocityGain(double velocityGain)
00104 {
00105 this->velocityGain = velocityGain;
00106 }
00107
00108 double JointTrajectoryAction::getVelocityGain() const
00109 {
00110 return velocityGain;
00111 }
00112
00113 void JointTrajectoryAction::setPositionGain(double positionGain)
00114 {
00115 this->positionGain = positionGain;
00116 }
00117
00118 double JointTrajectoryAction::getPositionGain() const
00119 {
00120 return positionGain;
00121 }
00122
00123 double JointTrajectoryAction::calculateVelocity(double actualAngle, double actualVelocity,
00124 const KDL::Trajectory_Composite& trajectoryComposite,
00125 double elapsedTimeInSec)
00126 {
00127
00128 double error = 0;
00129
00130 if (trajectoryComposite.Duration() > 0 && elapsedTimeInSec <= trajectoryComposite.Duration())
00131 {
00132 double actualTime = elapsedTimeInSec;
00133
00134 double desiredAngle = trajectoryComposite.Pos(actualTime).p.x();
00135 double desiredVelocity = trajectoryComposite.Vel(actualTime).vel.x();
00136
00137 double positionError = desiredAngle - actualAngle;
00138 double gain1 = getPositionGain();
00139 double gain2 = getVelocityGain();
00140
00141 error = gain1 * positionError + gain2 * desiredVelocity;
00142
00143 }
00144
00145 return error;
00146 }
00147
00148 void JointTrajectoryAction::controlLoop(const std::vector<double>& actualJointAngles,
00149 const std::vector<double>& actualJointVelocities,
00150 const KDL::Trajectory_Composite* trajectoryComposite, int numberOfJoints,
00151 ros::Time startTime, std::vector<double>& velocities)
00152 {
00153
00154 velocities.clear();
00155 double elapsedTime = ros::Duration(ros::Time::now() - startTime).toSec();
00156
00157 for (int i = 0; i < numberOfJoints; ++i)
00158 {
00159 double velocity = calculateVelocity(actualJointAngles[i], actualJointVelocities[i], trajectoryComposite[i],
00160 elapsedTime);
00161
00162 velocities.push_back(velocity);
00163
00164 }
00165
00166 }
00167
00168 void JointTrajectoryAction::setTargetTrajectory(double angle1, double angle2, double duration,
00169 KDL::Trajectory_Composite& trajectoryComposite)
00170 {
00171
00172 KDL::Frame pose1(KDL::Rotation::RPY(0, 0, 0), KDL::Vector(angle1, 0, 0));
00173 KDL::Frame pose2(KDL::Rotation::RPY(0, 0, 0), KDL::Vector(angle2, 0, 0));
00174
00175 KDL::Path_Line* path = new KDL::Path_Line(pose1, pose2, new KDL::RotationalInterpolation_SingleAxis(), 0.001);
00176 KDL::VelocityProfile_Spline* velprof = new KDL::VelocityProfile_Spline();
00177
00178 velprof->SetProfileDuration(0, path->PathLength(), duration);
00179
00180 KDL::Trajectory_Segment* trajectorySegment = new KDL::Trajectory_Segment(path, velprof);
00181 trajectoryComposite.Add(trajectorySegment);
00182 }
00183
00184 void JointTrajectoryAction::execute(const control_msgs::FollowJointTrajectoryGoalConstPtr& goal, Server* as)
00185 {
00186
00187 current_state.name = goal->trajectory.joint_names;
00188 current_state.position.resize(current_state.name.size());
00189 current_state.velocity.resize(current_state.name.size());
00190 current_state.effort.resize(current_state.name.size());
00191
00192 sensor_msgs::JointState angle1;
00193 angle1.name = goal->trajectory.joint_names;
00194 angle1.position.resize(angle1.name.size());
00195 angle1.velocity.resize(angle1.name.size());
00196 angle1.effort.resize(angle1.name.size());
00197
00198 sensor_msgs::JointState angle2;
00199 angle2.name = goal->trajectory.joint_names;
00200 angle2.position.resize(angle2.name.size());
00201 angle2.velocity.resize(angle2.name.size());
00202 angle2.effort.resize(angle2.name.size());
00203
00204 const uint numberOfJoints = current_state.name.size();
00205 KDL::Trajectory_Composite trajectoryComposite[numberOfJoints];
00206
00207 angle2.position = goal->trajectory.points.at(0).positions;
00208 for (uint i = 1; i < goal->trajectory.points.size(); i++)
00209 {
00210 angle1.position = angle2.position;
00211 angle2.position = goal->trajectory.points.at(i).positions;
00212
00213 double duration =
00214 (goal->trajectory.points.at(i).time_from_start - goal->trajectory.points.at(i - 1).time_from_start).toSec();
00215
00216 for (uint j = 0; j < numberOfJoints; ++j)
00217 {
00218 setTargetTrajectory(angle1.position.at(j), angle2.position.at(j), duration, trajectoryComposite[j]);
00219
00220 }
00221 }
00222
00223 const double dt = 1.0 / getFrequency();
00224 std::vector<double> velocities;
00225 ros::Time startTime = ros::Time::now();
00226
00227 for (double time = 0; time <= trajectoryComposite[0].Duration(); time = time + dt)
00228 {
00229
00230 controlLoop(current_state.position, current_state.velocity, trajectoryComposite, numberOfJoints, startTime,
00231 velocities);
00232
00233 brics_actuator::JointVelocities command;
00234 std::vector < brics_actuator::JointValue > armJointVelocities;
00235 armJointVelocities.resize(current_state.name.size());
00236
00237 for (uint j = 0; j < numberOfJoints; j++)
00238 {
00239 armJointVelocities[j].joint_uri = current_state.name.at(j);
00240 armJointVelocities[j].value = velocities[j];
00241 armJointVelocities[j].unit = boost::units::to_string(boost::units::si::radian_per_second);
00242 }
00243
00244 command.velocities = armJointVelocities;
00245 jointStateObserver->updateVelocity(command);
00246
00247 ros::Duration(dt).sleep();
00248 }
00249
00250 sensor_msgs::JointState goal_state;
00251 goal_state.name = goal->trajectory.joint_names;
00252 goal_state.position = goal->trajectory.points.back().positions;
00253
00254 brics_actuator::JointPositions command;
00255 std::vector < brics_actuator::JointValue > armJointPositions;
00256 armJointPositions.resize(current_state.name.size());
00257
00258 for (uint j = 0; j < numberOfJoints; j++)
00259 {
00260 armJointPositions[j].joint_uri = current_state.name.at(j);
00261 armJointPositions[j].value = goal_state.position.at(j);
00262 armJointPositions[j].unit = boost::units::to_string(boost::units::si::radian);
00263 }
00264
00265 command.positions = armJointPositions;
00266 jointStateObserver->updatePosition(command);
00267 control_msgs::FollowJointTrajectoryResult result;
00268 result.error_code = control_msgs::FollowJointTrajectoryResult::SUCCESSFUL;
00269 as->setSucceeded(result);
00270 }
00271
00272 void JointTrajectoryAction::jointStateCallback(const sensor_msgs::JointState& joint_state)
00273 {
00274 int k = current_state.name.size();
00275
00276 if (k != 0)
00277 {
00278 for (uint i = 0; i < joint_state.name.size(); i++)
00279 {
00280 for (uint j = 0; j < current_state.name.size(); j++)
00281 {
00282 if (current_state.name.at(j) == joint_state.name.at(i))
00283 {
00284 current_state.position[j] = joint_state.position.at(i);
00285 k--;
00286 break;
00287 }
00288 }
00289 if (k == 0)
00290 {
00291 break;
00292 }
00293 }
00294 }
00295 }
00296