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