pr2_base_trajectory_action_controller.h
Go to the documentation of this file.
00001 // -*- mode: c++ -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2016, JSK Lab
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/o2r other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the JSK Lab nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *********************************************************************/
00035 
00036 /*
00037  * pr2_base_trajectory_action_controller.h
00038  * Author: Yuki Furuta <furushchev@jsk.imi.i.u-tokyo.ac.jp>
00039  */
00040 
00041 #ifndef PR2_BASE_TRAJECTORY_ACTION_CONTROLLER_H__
00042 #define PR2_BASE_TRAJECTORY_ACTION_CONTROLLER_H__
00043 
00044 #include <algorithm>
00045 #include <string>
00046 #include <stdexcept>
00047 //#include <boost/range/algorithm.hpp>
00048 #include <boost/shared_ptr.hpp>
00049 #include <boost/thread.hpp>
00050 
00051 #include <ros/ros.h>
00052 #include <actionlib/server/action_server.h>
00053 #include <control_msgs/FollowJointTrajectoryAction.h>
00054 #include <trajectory_msgs/JointTrajectory.h>
00055 #include <nav_msgs/Odometry.h>
00056 
00057 #include <pr2_base_trajectory_action/math_spline.h>
00058 
00059 namespace pr2_base_trajectory_action {
00060   typedef actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction> Server;
00061   typedef Server::GoalHandle GoalHandle;
00062 
00063   struct JointState {
00064     std::string name;
00065     double position, velocity;
00066     double max_velocity;
00067     double commanded_velocity;
00068     double commanded_effort;
00069   };
00070 
00071   struct BaseJointState {
00072     ros::Time real_latest_time;
00073     JointState x, y, yaw;
00074     const JointState &operator[] (size_t i) const {
00075       if (i == 0) return x;
00076       else if (i == 1) return y;
00077       else if (i == 2) return yaw;
00078       else throw std::out_of_range("range must be 0-2");
00079     }
00080     JointState &operator[] (size_t i) {
00081       if (i == 0) return x;
00082       else if (i == 1) return y;
00083       else if (i == 2) return yaw;
00084       else throw std::out_of_range("range must be 0-2");
00085     }
00086   };
00087 
00088   struct Trajectory {
00089     struct Segment
00090     {
00091       double start_time;
00092       double duration;
00093       Spline splines[3];
00094       boost::shared_ptr<GoalHandle> gh;
00095       Segment(){}
00096       Segment(const double &start_time,
00097               const double &duration,
00098               const boost::shared_ptr<GoalHandle> &gh,
00099               const Spline &spline_x,
00100               const Spline &spline_y,
00101               const Spline &spline_yaw) :
00102         start_time(start_time),
00103         duration(duration),
00104         gh(gh) {
00105         splines[0] = spline_x;
00106         splines[1] = spline_y;
00107         splines[2] = spline_yaw;
00108       }
00109       void sample(const double &time, BaseMotion &base) {
00110         for (int i = 0; i < 3; ++i)
00111           splines[i].sampleWithTimeBounds(duration, time, base[i]);
00112       }
00113       typedef boost::shared_ptr< ::pr2_base_trajectory_action::Trajectory::Segment > Ptr;
00114     };
00115     std::vector<Segment> segments;
00116 
00117     Trajectory() {}
00118     Trajectory(int size) : segments(size) {}
00119 
00120     bool nextSegment(const double &time, Segment &seg) {
00121       if (size() == 0) {
00122         ROS_ERROR("no segments in trajectory");
00123         return false;
00124       }
00125       int seg_idx = -1;
00126       while (seg_idx + 1 < size() &&
00127              segments[seg_idx+1].start_time < time)
00128         ++seg_idx;
00129       if (seg_idx == -1) {
00130         ROS_ERROR("No earlier segments. Segment starts at %.3lf (now: %.3lf)",
00131                   segments[0].start_time, time);
00132         return false;
00133       }
00134       seg = segments[seg_idx];
00135       return true;
00136     }
00137     bool motionAtTime(const double &time, BaseMotion &base) {
00138       Segment s;
00139       if (!nextSegment(time, s)) return false;
00140       double diff_time = time - s.start_time;
00141       s.sample(diff_time, base);
00142       return true;
00143     }
00144     bool goalAtTime(const double &time, boost::shared_ptr<GoalHandle> &gh) {
00145       Segment s;
00146       if (!nextSegment(time, s)) return false;
00147       gh = s.gh;
00148       return true;
00149     }
00150     double endTime() {
00151       Segment s = segments[size() - 1];
00152       return s.start_time + s.duration;
00153     }
00154     inline int size() const {
00155       return segments.size();
00156     }
00157     typedef boost::shared_ptr< ::pr2_base_trajectory_action::Trajectory > Ptr;
00158     typedef boost::shared_ptr< ::pr2_base_trajectory_action::Trajectory const > ConstPtr;
00159   };
00160 
00161   class Controller
00162   {
00163 
00164     boost::mutex mutex_;
00165     ros::NodeHandle nh_, pnh_;
00166     ros::Subscriber odom_sub_;
00167     ros::Publisher cmd_vel_pub_;
00168     ros::Timer update_timer_;
00169     boost::shared_ptr<Server> as_;
00170     boost::shared_ptr<GoalHandle> active_goal_;
00171     Trajectory::Ptr active_traj_;
00172     ros::Time real_latest_time_;
00173     BaseJointState joints_;
00174     double frequency_;
00175     double stopped_velocity_tolerance_;
00176     double goal_threshold_;
00177     double goal_time_constraint_;
00178     bool use_pid;
00179     control_msgs::FollowJointTrajectoryFeedback::Ptr feedback_msg_;
00180     geometry_msgs::Twist::Ptr cmd_vel_msg_;
00181   
00182     void setFeedback(const ros::Time &time, const BaseMotion &desired, const BaseMotion &error);
00183     void clearTrajectory();
00184     void setTrajectory(const trajectory_msgs::JointTrajectory::ConstPtr &msg,
00185                        boost::shared_ptr<GoalHandle> &gh);
00186   public:
00187 
00188     Controller();
00189     virtual ~Controller();
00190     void goalCallback(GoalHandle gh);
00191     void cancelCallback(GoalHandle gh);
00192     void odomCallback(const nav_msgs::Odometry::ConstPtr & msg);
00193     void update(const ros::TimerEvent& event);
00194   }; // class
00195 
00196   template<typename T>
00197   inline int findIndex(std::vector<T> vec, T val)
00198   {
00199     typename
00200       std::vector<T>::iterator it = std::find(vec.begin(), vec.end(), val);
00201     int d = it - vec.begin();
00202     return d == vec.size() ? -1 : d;
00203   }
00204 
00205   template <typename E, typename M>
00206   inline boost::shared_ptr<M> share_member(boost::shared_ptr<E> e, M &m)
00207   {
00208     actionlib::EnclosureDeleter<E> d(e);
00209     boost::shared_ptr<M> p(&m, d);
00210     return p;
00211   }
00212 } // namespace
00213 
00214 
00215 #endif // PR2_BASE_TRAJECTORY_ACTION_CONTROLLER_H__


pr2_base_trajectory_action
Author(s): saito, Yuki Furuta
autogenerated on Sat Jul 1 2017 02:43:02