joint_trajectory_action.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  * Copyright (c) 2011
00003  * GPS GmbH
00004  *
00005  * Author:
00006  * Alexey Zakharov
00007  *
00008  *
00009  * This software is published under a dual-license: GNU Lesser General Public
00010  * License LGPL 2.1 and BSD license. The dual-license implies that users of this
00011  * code may choose which terms they prefer.
00012  *a
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * * Redistributions of source code must retain the above copyright
00017  * notice, this list of conditions and the following disclaimer.
00018  * * Redistributions in binary form must reproduce the above copyright
00019  * notice, this list of conditions and the following disclaimer in the
00020  * documentation and/or other materials provided with the distribution.
00021  * * Neither the name of GPS GmbH nor the names of its
00022  * contributors may be used to endorse or promote products derived from
00023  * this software without specific prior written permission.
00024  *
00025  * This program is free software: you can redistribute it and/or modify
00026  * it under the terms of the GNU Lesser General Public License LGPL as
00027  * published by the Free Software Foundation, either version 2.1 of the
00028  * License, or (at your option) any later version or the BSD license.
00029  *
00030  * This program is distributed in the hope that it will be useful,
00031  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00032  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00033  * GNU Lesser General Public License LGPL and the BSD license for more details.
00034  *
00035  * You should have received a copy of the GNU Lesser General Public
00036  * License LGPL and BSD license along with this program.
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     //double velocityError = desiredVelocity - actualVelocity;
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines


youbot_oodl
Author(s): Sebastian Blumenthal
autogenerated on Fri Jul 26 2013 12:00:42