gripper_action_controller_impl.h
Go to the documentation of this file.
00001 //
00002 // Created by tom on 07/04/16.
00003 //
00004 
00005 #ifndef ROBOTICAN_CONTROLLERS_GRIPPER_ACTION_CONTROLLER_IMPL_H
00006 #define ROBOTICAN_CONTROLLERS_GRIPPER_ACTION_CONTROLLER_IMPL_H
00007 
00008 
00009 
00010 namespace gripper_action_controller
00011 {
00012     namespace internal
00013     {
00014         std::string getLeafNamespace(const ros::NodeHandle& nh)
00015         {
00016             const std::string complete_ns = nh.getNamespace();
00017             std::size_t id   = complete_ns.find_last_of("/");
00018             return complete_ns.substr(id + 1);
00019         }
00020 
00021         boost::shared_ptr<urdf::Model> getUrdf(const ros::NodeHandle& nh, const std::string& param_name)
00022         {
00023             boost::shared_ptr<urdf::Model> urdf(new urdf::Model);
00024 
00025             std::string urdf_str;
00026             // Check for robot_description in proper namespace
00027             if (nh.getParam(param_name, urdf_str))
00028             {
00029                 if (!urdf->initString(urdf_str))
00030                 {
00031                     ROS_ERROR_STREAM("Failed to parse URDF contained in '" << param_name << "' parameter (namespace: " <<
00032                                                                            nh.getNamespace() << ").");
00033                     return boost::shared_ptr<urdf::Model>();
00034                 }
00035             }
00036                 // Check for robot_description in root
00037             else if (!urdf->initParam("robot_description"))
00038             {
00039                 ROS_ERROR_STREAM("Failed to parse URDF contained in '" << param_name << "' parameter");
00040                 return boost::shared_ptr<urdf::Model>();
00041             }
00042             return urdf;
00043         }
00044 
00045         typedef boost::shared_ptr<const urdf::Joint> UrdfJointConstPtr;
00046         std::vector<UrdfJointConstPtr> getUrdfJoints(const urdf::Model& urdf, const std::vector<std::string>& joint_names)
00047         {
00048             std::vector<UrdfJointConstPtr> out;
00049             for (unsigned int i = 0; i < joint_names.size(); ++i)
00050             {
00051                 UrdfJointConstPtr urdf_joint = urdf.getJoint(joint_names[i]);
00052                 if (urdf_joint)
00053                 {
00054                     out.push_back(urdf_joint);
00055                 }
00056                 else
00057                 {
00058                     ROS_ERROR_STREAM("Could not find joint '" << joint_names[i] << "' in URDF model.");
00059                     return std::vector<UrdfJointConstPtr>();
00060                 }
00061             }
00062             return out;
00063         }
00064 
00065     } // namespace
00066 
00067     template <class HardwareInterface>
00068     inline void GripperActionControllerTwo<HardwareInterface>::
00069     starting(const ros::Time& time)
00070     {
00071         command_struct_rt_.position_ = pos2Gap(rightjoint_.getPosition());
00072         command_struct_rt_.max_effort_ = default_max_effort_;
00073         command_.initRT(command_struct_rt_);
00074 
00075         _lastPosition = command_struct_rt_.position_;
00076 
00077 
00078         // Hardware interface adapter
00079         left_hw_iface_adapter_.starting(ros::Time(0.0));
00080         right_hw_iface_adapter_.starting(ros::Time(0.0));
00081         last_movement_time_ = time;
00082     }
00083 
00084     template <class HardwareInterface>
00085     inline void GripperActionControllerTwo<HardwareInterface>::
00086     stopping(const ros::Time& time)
00087     {
00088         preemptActiveGoal();
00089     }
00090 
00091     template <class HardwareInterface>
00092     inline void GripperActionControllerTwo<HardwareInterface>::
00093     preemptActiveGoal()
00094     {
00095         RealtimeGoalHandlePtr current_active_goal(rt_active_goal_);
00096 
00097         // Cancels the currently active goal
00098         if (current_active_goal)
00099         {
00100             // Marks the current goal as canceled
00101             rt_active_goal_.reset();
00102             if(current_active_goal->gh_.getGoalStatus().status == actionlib_msgs::GoalStatus::ACTIVE)
00103                 current_active_goal->gh_.setCanceled();
00104         }
00105     }
00106 
00107     template <class HardwareInterface>
00108     GripperActionControllerTwo<HardwareInterface>::
00109     GripperActionControllerTwo()
00110             : verbose_(false) // Set to true during debugging
00111     {}
00112 
00113     template <class HardwareInterface>
00114     bool GripperActionControllerTwo<HardwareInterface>::init(HardwareInterface* hw,
00115                                                              ros::NodeHandle&   root_nh,
00116                                                              ros::NodeHandle&   controller_nh)
00117     {
00118         using namespace internal;
00119 
00120         // Cache controller node handle
00121         controller_nh_ = controller_nh;
00122 
00123         // Controller name
00124         name_ = getLeafNamespace(controller_nh_);
00125 
00126         // Action status checking update rate
00127         double action_monitor_rate = 20.0;
00128         controller_nh_.getParam("action_monitor_rate", action_monitor_rate);
00129         action_monitor_period_ = ros::Duration(1.0 / action_monitor_rate);
00130         ROS_DEBUG_STREAM_NAMED(name_, "Action status changes will be monitored at " << action_monitor_rate << "Hz.");
00131 
00132         // Controlled joint
00133         controller_nh_.getParam("leftJoint", leftJoint_name_);
00134         controller_nh_.getParam("rightJoint", rightJoint_name_);
00135         _gapPub = controller_nh_.advertise<control_msgs::GripperCommandResult>("current_gap", 10);
00136         if (leftJoint_name_.empty() || rightJoint_name_.empty())
00137         {
00138             ROS_ERROR_STREAM_NAMED(name_, "Could not find joint name on param server");
00139             return false;
00140         }
00141 
00142         // URDF joints
00143         boost::shared_ptr<urdf::Model> urdf = getUrdf(root_nh, "robot_description");
00144         if (!urdf)
00145         {
00146             return false;
00147         }
00148 
00149         std::vector<std::string> joint_names;
00150         joint_names.push_back(leftJoint_name_);
00151         joint_names.push_back(rightJoint_name_);
00152         std::vector<UrdfJointConstPtr> urdf_joints = getUrdfJoints(*urdf, joint_names);
00153         if (urdf_joints.empty())
00154         {
00155             return false;
00156         }
00157 
00158         // Initialize members
00159         // Joint handle
00160         try
00161         {
00162             leftjoint_ = hw->getHandle(leftJoint_name_);
00163             rightjoint_ = hw->getHandle(rightJoint_name_);
00164         }
00165         catch (...)
00166         {
00167             ROS_ERROR_STREAM_NAMED(name_, "Could not find joint '" << leftJoint_name_ << "' in '" <<
00168                                                                    this->getHardwareInterfaceType() << "'.");
00169             return false;
00170         }
00171 
00172         ROS_DEBUG_STREAM_NAMED(name_, "Initialized controller '" << name_ << "' with:" <<
00173                                                                  "\n- Hardware interface type: '" << this->getHardwareInterfaceType() << "'" <<
00174                                                                  "\n");
00175 
00176         // Default tolerances
00177         controller_nh_.param<double>("goal_tolerance", goal_tolerance_, 0.01);
00178         goal_tolerance_ = fabs(goal_tolerance_);
00179         // Max allowable effort
00180         controller_nh_.param<double>("max_effort", default_max_effort_, 0.0);
00181         default_max_effort_ = fabs(default_max_effort_);
00182         // Stall - stall velocity threshold, stall timeout
00183         controller_nh_.param<double>("stall_velocity_threshold", stall_velocity_threshold_, 0.001);
00184         controller_nh_.param<double>("stall_timeout", stall_timeout_, 1.0);
00185 
00186         // Hardware interface adapter
00187         left_hw_iface_adapter_.init(leftjoint_, controller_nh_);
00188         right_hw_iface_adapter_.init(rightjoint_, controller_nh_);
00189 
00190         // Command - non RT version
00191         command_struct_.position_ = pos2Gap(rightjoint_.getPosition());
00192         command_struct_.max_effort_ = default_max_effort_;
00193 
00194         // Result
00195         pre_alloc_result_.reset(new control_msgs::GripperCommandResult());
00196         pre_alloc_result_->position = command_struct_.position_;
00197         pre_alloc_result_->reached_goal = false;
00198         pre_alloc_result_->stalled = false;
00199 
00200         // ROS API: Action interface
00201         action_server_.reset(new ActionServer(controller_nh_, "gripper_cmd",
00202                                               boost::bind(&GripperActionControllerTwo::goalCB, this, _1),
00203                                               boost::bind(&GripperActionControllerTwo::cancelCB, this, _1),
00204                                               false));
00205 
00206         action_server_->start();
00207         return true;
00208     }
00209 
00210     template <class HardwareInterface>
00211     void GripperActionControllerTwo<HardwareInterface>::
00212     update(const ros::Time& time, const ros::Duration& period)
00213     {
00214         command_struct_rt_ = *(command_.readFromRT());
00215 
00216         double current_position = pos2Gap(rightjoint_.getPosition());
00217 //ROS_INFO("current_gap: %f",current_position);
00218         double current_velocity =  current_position - _lastPosition / period.toSec();
00219         double current_effort = (fabs(leftjoint_.getEffort())>fabs(rightjoint_.getEffort())) ? fabs(leftjoint_.getEffort()):fabs(rightjoint_.getEffort());
00220         double error_position = command_struct_rt_.position_ - current_position;
00221         double error_velocity = - current_velocity;
00222         _lastPosition = current_position;
00223         if (command_struct_rt_.max_effort_==0) current_effort=-1;
00224         checkForSuccess(time, error_position, current_position, current_velocity, current_effort,command_struct_rt_.max_effort_);
00225 
00226         // Hardware interface adapter: Generate and send commands
00227         double jointsPos = gap2Pos(command_struct_rt_.position_);
00228 //ROS_WARN("jointsPos: %f",jointsPos);
00229         computed_command_ = left_hw_iface_adapter_.updateCommand(time, period,
00230                                                                  -jointsPos, 0.0, error_position, error_velocity, command_struct_rt_.max_effort_);
00231         computed_command_ = right_hw_iface_adapter_.updateCommand(time, period,
00232                                                                   jointsPos, 0.0, error_position, error_velocity, command_struct_rt_.max_effort_);
00233     }
00234 
00235     template <class HardwareInterface>
00236     void GripperActionControllerTwo<HardwareInterface>::
00237     goalCB(GoalHandle gh)
00238     {
00239         ROS_INFO("Recieved new action goal");
00240 
00241         // Precondition: Running controller
00242         if (!this->isRunning())
00243         {
00244             ROS_ERROR_NAMED(name_, "Can't accept new action goals. Controller is not running.");
00245             control_msgs::GripperCommandResult result;
00246             gh.setRejected(result);
00247             return;
00248         }
00249 
00250         // Try to update goal
00251         RealtimeGoalHandlePtr rt_goal(new RealtimeGoalHandle(gh));
00252 
00253         // Accept new goal
00254         preemptActiveGoal();
00255         gh.setAccepted();
00256 
00257         // This is the non-realtime command_struct
00258         // We use command_ for sharing
00259         command_struct_.position_ = gh.getGoal()->command.position;
00260         command_struct_.max_effort_ = gh.getGoal()->command.max_effort;
00261         command_.writeFromNonRT(command_struct_);
00262 
00263         pre_alloc_result_->reached_goal = false;
00264         pre_alloc_result_->stalled = false;
00265 
00266         last_movement_time_ = ros::Time::now();
00267 
00268         // Setup goal status checking timer
00269         goal_handle_timer_ = controller_nh_.createTimer(action_monitor_period_,
00270                                                         &RealtimeGoalHandle::runNonRealtime,
00271                                                         rt_goal);
00272         goal_handle_timer_.start();
00273         rt_active_goal_ = rt_goal;
00274         ROS_INFO("GRIPPER: Got new goal");
00275     }
00276 
00277     template <class HardwareInterface>
00278     void GripperActionControllerTwo<HardwareInterface>::
00279     cancelCB(GoalHandle gh)
00280     {
00281         RealtimeGoalHandlePtr current_active_goal(rt_active_goal_);
00282 
00283         // Check that cancel request refers to currently active goal (if any)
00284         if (current_active_goal && current_active_goal->gh_ == gh)
00285         {
00286             // Reset current goal
00287             rt_active_goal_.reset();
00288 
00289             // Enter hold current position mode
00290             setHoldPosition(ros::Time(0.0));
00291             ROS_DEBUG_NAMED(name_, "Canceling active action goal because cancel callback recieved from actionlib.");
00292 
00293             // Mark the current goal as canceled
00294             current_active_goal->gh_.setCanceled();
00295         }
00296     }
00297 
00298     template <class HardwareInterface>
00299     void GripperActionControllerTwo<HardwareInterface>::
00300     setHoldPosition(const ros::Time& time)
00301     {
00302         ROS_WARN("INSIDE setHoldPosition");
00303         ROS_WARN("rightjoint_.getPosition(): %f", rightjoint_.getPosition());
00304         
00305         command_struct_.position_ = pos2Gap(rightjoint_.getPosition()) - 0.03;
00306         
00307         ROS_WARN("command_struct_.position_ = pos2Gap(rightjoint_.getPosition()): %f", pos2Gap(rightjoint_.getPosition()));
00308 
00309         command_.writeFromNonRT(command_struct_);
00310 
00311     }
00312 
00313     template <class HardwareInterface>
00314     void GripperActionControllerTwo<HardwareInterface>::
00315     checkForSuccess(const ros::Time &time, double error_position, double current_position, double current_velocity,
00316                     double current_effort,double max_effort)
00317     {
00318 
00319 //ROS_ERROR("error_position: %f",error_position);
00320         if(!rt_active_goal_) {
00321             return;
00322 }
00323 
00324         if(rt_active_goal_->gh_.getGoalStatus().status != actionlib_msgs::GoalStatus::ACTIVE){
00325             return;
00326 }
00327         if(fabs(error_position) < goal_tolerance_)
00328         {
00329             pre_alloc_result_->effort = computed_command_;
00330             pre_alloc_result_->position = current_position;
00331             pre_alloc_result_->reached_goal = true;
00332             pre_alloc_result_->stalled = false;
00333             rt_active_goal_->setSucceeded(pre_alloc_result_);
00334             ROS_INFO("GRIPPER: Reached Goal");
00335         }
00336         else
00337         {
00338             if (current_effort >= fabs(max_effort)) {
00339                 ROS_WARN("GRIPPER: MAX EFFORT");
00340 
00341                 
00342                 
00343                 pre_alloc_result_->effort = computed_command_;
00344                 pre_alloc_result_->position = current_position;
00345                 pre_alloc_result_->reached_goal = false;
00346                 pre_alloc_result_->stalled = true;
00347 
00348 
00349                         ROS_WARN("pre_alloc_result_->effort: %f", pre_alloc_result_->effort);
00350                         ROS_WARN("pre_alloc_result_->position: %f", pre_alloc_result_->position);
00351 
00352                 rt_active_goal_->setSucceeded(pre_alloc_result_);
00353                 setHoldPosition(ros::Time(0.0));
00354                 return;
00355             }
00356 
00357             if(fabs(current_velocity) > stall_velocity_threshold_) {
00358 
00359                 last_movement_time_ = time;
00360             }
00361             else if( (time - last_movement_time_).toSec() > stall_timeout_)
00362             {
00363                 ROS_WARN("GRIPPER: STALLED");
00364                 pre_alloc_result_->effort = computed_command_;
00365                 pre_alloc_result_->position = current_position;
00366                 pre_alloc_result_->reached_goal = false;
00367                 pre_alloc_result_->stalled = true;
00368                 rt_active_goal_->setAborted(pre_alloc_result_);
00369                 setHoldPosition(ros::Time(0.0));
00370 
00371             }
00372         }
00373     }
00374 
00375 }
00376 
00377 #endif //ROBOTICAN_CONTROLLERS_GRIPPER_ACTION_CONTROLLER_IMPL_H


robotican_controllers
Author(s):
autogenerated on Fri Oct 27 2017 03:02:40