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


youbot_driver_ros_interface
Author(s): Sebastian Blumenthal
autogenerated on Thu Jun 6 2019 20:43:35