dynamic_positioning.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, LABUST, UNIZG-FER
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the LABUST nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *  Author: Dula Nad
00035  *  Created: 01.02.2013.
00036  *********************************************************************/
00037 #include <labust/primitive/PrimitiveBase.hpp>
00038 #include <labust/math/NumberManipulation.hpp>
00039 #include <labust/math/Line.hpp>
00040 #include <labust/tools/conversions.hpp>
00041 
00042 #include <Eigen/Dense>
00043 #include <navcon_msgs/DynamicPositioningAction.h>
00044 #include <navcon_msgs/EnableControl.h>
00045 #include <geometry_msgs/Point.h>
00046 #include <geometry_msgs/TransformStamped.h>
00047 #include <tf2_ros/static_transform_broadcaster.h>
00048 #include <ros/ros.h>
00049 
00050 #include <boost/thread/mutex.hpp>
00051 #include <boost/array.hpp>
00052 
00053 namespace labust
00054 {
00055         namespace primitive
00056         {
00057 
00058                 struct DynamicPositionining : protected ExecutorBase<navcon_msgs::DynamicPositioningAction>{
00059 
00060                         typedef navcon_msgs::DynamicPositioningGoal Goal;
00061                         typedef navcon_msgs::DynamicPositioningResult Result;
00062                         typedef navcon_msgs::DynamicPositioningFeedback Feedback;
00063 
00064 
00065                         enum {ualf=0,falf, fadp, hdg, numcnt};
00066 
00067                         DynamicPositionining():
00068                                 ExecutorBase("dynamic_positioning"),
00069                                 underactuated(true),
00070                                 headingEnabled(false),
00071                                 processNewGoal(false){};
00072 
00073                         void init(){
00074                                 ros::NodeHandle ph("~");
00075 
00076                                 /*** Initialize controller names ***/
00077                                 controllers.name.resize(numcnt);
00078                                 controllers.state.resize(numcnt, false);
00079 
00080                                 controllers.name[fadp] = "FADP_enable";
00081                                 controllers.name[hdg] = "HDG_enable";
00082                         }
00083 
00084                         void onGoal(){
00085 
00086                                 boost::mutex::scoped_lock l(state_mux);
00087                                 ROS_DEBUG("On goal.");
00088                                 //Set the flag to avoid disabling controllers on preemption
00089 
00090                         //      if(aserver->isActive()){
00091 
00092                                 //      aserver->setPreempted();
00093                                 //}
00094 
00095                                 processNewGoal = true;
00096                                 Goal::ConstPtr new_goal = aserver->acceptNewGoal();
00097                                 processNewGoal = false;
00098 
00099 
00100                                 //if ((goal == 0) || (new_goal->course != goal->course))
00101 //                              if ((goal == 0) || (new_goal->T1.point.x != goal->T1.point.x)
00102 //                                                              || (new_goal->T1.point.y != goal->T1.point.y)
00103 //                                                              || (new_goal->yaw != goal->yaw))
00104 //                              {
00105 
00106                                 if (goal == 0){
00107 
00108                                         //Save new goal
00109                                         goal = new_goal;
00110 
00111                                         //Update reference
00112                                         stateRef.publish(step(lastState));
00113                     controllers.state[fadp] = true;
00114                     controllers.state[hdg] = true;
00115 
00116 
00117                                         this->updateControllers();
00118                                 }
00119 
00120                                 //Save new goal
00121                                 goal = new_goal;
00122                         }
00123 
00124                         void onPreempt()
00125                         {
00126                                 ROS_ERROR("Preempted.");
00127                                 if (!processNewGoal)
00128                                 {
00129                                         //ROS_ERROR("Stopping controllers.");
00130                                         //controllers.state.assign(numcnt, false);
00131                                         //this->updateControllers();
00132                                 }
00133                                 else
00134                                 {
00135                                         //ROS_ERROR("New goal processing.");
00136                                 }
00137                                 aserver->setPreempted();
00138                         };
00139 
00140                         void updateControllers(){
00141 
00142                                 /* Enable high level controllers */
00143                                 ros::NodeHandle nh;
00144                                 ros::ServiceClient cl;
00145 
00146                                 cl = nh.serviceClient<navcon_msgs::EnableControl>(std::string(controllers.name[fadp]));
00147                                 navcon_msgs::EnableControl a;
00148                 a.request.enable =  controllers.state[fadp];
00149                                 cl.call(a);
00150 
00151                                 cl = nh.serviceClient<navcon_msgs::EnableControl>(std::string(controllers.name[hdg]));
00152                 a.request.enable =  controllers.state[fadp];
00153                                 cl.call(a);
00154                         }
00155 
00156                         void onStateHat(const auv_msgs::NavSts::ConstPtr& estimate){
00157 
00158                                 boost::mutex::scoped_lock l(state_mux);
00159 
00160                                 if (aserver->isActive()){
00161 
00162                                         stateRef.publish(step(*estimate));
00163 
00164                                         /*** Check if goal (victory radius) is achieved ***/
00165                                         Eigen::Vector3d distance;
00166                                         distance<<goal->T1.point.x-estimate->position.north, goal->T1.point.y-estimate->position.east, 0;
00167 
00168                                         /*** Calculate bearing to endpoint ***/
00169                                         Eigen::Vector3d T1,T2;
00170                                         labust::math::Line bearing_to_endpoint;
00171                                         T1 << estimate->position.north, estimate->position.east, 0;
00172                                         T2 << goal->T1.point.x, goal->T1.point.y, 0;
00173                                         bearing_to_endpoint.setLine(T1,T2);
00174 
00175                                         /*** Publish primitive feedback ***/
00176                                         Feedback feedback;
00177                                         feedback.error.point.x = distance(0);
00178                                         feedback.error.point.y = distance(1);
00179                                         feedback.distance = distance.norm();
00180                                         feedback.bearing = bearing_to_endpoint.gamma();
00181                                         aserver->publishFeedback(feedback);
00182                                 }
00183                                 else if (goal != 0){
00184 
00185                                                 goal.reset();
00186                                                 ROS_INFO("Stopping controllers.");
00187                                                 controllers.state.assign(numcnt, false);
00188                                                 this->updateControllers();
00189                                 }
00190 
00191                                 lastState = *estimate;
00192                         }
00193 
00194                         auv_msgs::NavStsPtr step(const auv_msgs::NavSts& state)
00195                         {
00196                                 auv_msgs::NavStsPtr ref(new auv_msgs::NavSts());
00197 
00198                                 ref->position.north = goal->T1.point.x;
00199                                 ref->position.east = goal->T1.point.y;
00200                                 ref->orientation.yaw = goal->yaw;
00201                                 ref->header.frame_id = "local";
00202                                 ref->header.stamp = ros::Time::now();
00203 
00204                                 return ref;
00205                         }
00206 
00207                 private:
00208                         geometry_msgs::Point lastPosition;
00209                         labust::math::Line line;
00210                         tf2_ros::StaticTransformBroadcaster broadcaster;
00211                         bool underactuated;
00212                         bool headingEnabled;
00213                         bool processNewGoal;
00214                         Goal::ConstPtr goal;
00215                         auv_msgs::NavSts lastState;
00216                         boost::mutex state_mux;
00217                         navcon_msgs::ControllerSelectRequest controllers;
00218                 };
00219         }
00220 }
00221 
00222 int main(int argc, char* argv[]){
00223 
00224         ros::init(argc,argv,"dynamic_positioning");
00225 
00226         labust::primitive::PrimitiveBase<labust::primitive::DynamicPositionining> primitive;
00227         ros::spin();
00228 
00229         return 0;
00230 }
00231 
00232 
00233 


labust_primitives
Author(s): Filip Mandic
autogenerated on Fri Aug 28 2015 11:22:51