cartesian_arm_teleop_node.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  *
00003  *  Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2014, Alexander Buchegger
00006  *                      Institute for Software Technology,
00007  *                      Graz University of Technology
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *   * Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *   * Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions and the following
00018  *     disclaimer in the documentation and/or other materials provided
00019  *     with the distribution.
00020  *   * Neither the name of Graz University of Technology nor the names of
00021  *     its contributors may be used to endorse or promote products derived
00022  *     from this software without specific prior written permission.
00023  *
00024  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  *  POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  *********************************************************************/
00038 #include <tedusar_cartesian_arm_teleop/cartesian_arm_teleop_node.h>
00039 #include <stdexcept>
00040 
00041 namespace tedusar_cartesian_arm_teleop
00042 {
00043 
00044 CartesianArmTeleopNode::CartesianArmTeleopNode()
00045     : repeat_vel_commands_(false)
00046 {
00047 }
00048 
00049 void CartesianArmTeleopNode::init()
00050 {
00051     loadParameters();
00052     ROS_INFO_STREAM("Controller: " << parameters_.controller_);
00053 
00054     cmd_vel_.header.frame_id = parameters_.frame_id_;
00055 
00056     cmd_generator_timer_ = nh_.createTimer(ros::Duration(1.0 / parameters_.publication_rate_),
00057         &CartesianArmTeleopNode::cmdGeneratorTimerCB, this, false);
00058 
00059     cmd_vel_pub_ = nh_.advertise<geometry_msgs::TwistStamped>("/cartesian_controller/arm_cmd_vel", 1);
00060     joy_sub_ = nh_.subscribe<sensor_msgs::Joy>("joy", 10,
00061         &CartesianArmTeleopNode::joyCB, this);
00062 
00063     if (parameters_.have_gripper_)
00064     {
00065         gripper_command_ac_.reset(new GripperCommandActionClient("/gripper_controller/gripper_cmd", true));
00066         grasping_done_pub_ = nh_.advertise<std_msgs::Empty>("grasping_done", 1);
00067     }
00068 }
00069 
00070 void CartesianArmTeleopNode::loadParameters()
00071 {
00072     ros::NodeHandle private_nh("~");
00073 #define GOP(key, default_value) getOptionalParameter(private_nh, #key, parameters_.key##_, default_value)
00074 #define GRP(key) getRequiredParameter(private_nh, #key, parameters_.key##_)
00075 
00076     GOP(publication_rate, 20.0);
00077     GRP(frame_id);
00078 
00079     GOP(std_translation_vel, 0.01);
00080     GOP(std_rotation_vel, 0.1);
00081     GOP(turbo_factor, 2.0);
00082 
00083     GOP(have_gripper, true);
00084     GOP(gripper_grasp_position, 0.0);
00085     GOP(gripper_grasp_effort, 10.0);
00086     GOP(gripper_release_position, 0.1);
00087     GOP(gripper_release_effort, 0.0);
00088 
00089     GRP(controller);
00090     GRP(button_translation_deadman_switch);
00091     GRP(button_rotation_deadman_switch);
00092     GRP(button_turbo);
00093 
00094     if (parameters_.have_gripper_)
00095     {
00096         GRP(button_gripper_grasp);
00097         GRP(button_gripper_release);
00098         GRP(button_grasp_done);
00099     }
00100 
00101     GRP(axis_translation_x);
00102     GRP(axis_translation_y);
00103     GRP(axis_translation_z);
00104     GRP(axis_rotation_x);
00105     GRP(axis_rotation_y);
00106     GRP(axis_rotation_z);
00107 #undef GOP
00108 #undef GRP
00109 }
00110 
00111 void CartesianArmTeleopNode::cmdGeneratorTimerCB(const ros::TimerEvent & e)
00112 {
00113     if (repeat_vel_commands_)
00114         sendCmdVel();
00115 }
00116 
00117 void CartesianArmTeleopNode::joyCB(const sensor_msgs::Joy::ConstPtr & joy)
00118 {
00119     bool have_vel_commands = false;
00120 
00121     double turbo = joy->buttons.at(parameters_.button_turbo_) ? parameters_.turbo_factor_ : 1.0;
00122 
00123     if (joy->buttons.at(parameters_.button_translation_deadman_switch_) && !joy->buttons.at(parameters_.button_rotation_deadman_switch_))
00124     {
00125       have_vel_commands = true;
00126       cmd_vel_.twist.linear.x = parameters_.std_translation_vel_ * turbo * joy->axes.at(parameters_.axis_translation_x_);
00127       cmd_vel_.twist.linear.y = parameters_.std_translation_vel_ * turbo * joy->axes.at(parameters_.axis_translation_y_);
00128       cmd_vel_.twist.linear.z = parameters_.std_translation_vel_ * turbo * joy->axes.at(parameters_.axis_translation_z_);
00129     }
00130     else
00131     {
00132       cmd_vel_.twist.linear.x = 0;
00133       cmd_vel_.twist.linear.y = 0;
00134       cmd_vel_.twist.linear.z = 0;
00135     }
00136 
00137     if (!joy->buttons.at(parameters_.button_translation_deadman_switch_) && joy->buttons.at(parameters_.button_rotation_deadman_switch_))
00138     {
00139         have_vel_commands = true;
00140         cmd_vel_.twist.angular.x = parameters_.std_rotation_vel_ * turbo * joy->axes.at(parameters_.axis_rotation_x_);
00141         cmd_vel_.twist.angular.y = parameters_.std_rotation_vel_ * turbo * joy->axes.at(parameters_.axis_rotation_y_);
00142         cmd_vel_.twist.angular.z = parameters_.std_rotation_vel_ * turbo * joy->axes.at(parameters_.axis_rotation_z_);
00143     }
00144     else
00145     {
00146         cmd_vel_.twist.angular.x = 0;
00147         cmd_vel_.twist.angular.y = 0;
00148         cmd_vel_.twist.angular.z = 0;
00149     }
00150 
00151     if (parameters_.have_gripper_ && joy->buttons.at(parameters_.button_translation_deadman_switch_) &&
00152             joy->buttons.at(parameters_.button_rotation_deadman_switch_))
00153     {
00154         if (joy->buttons.at(parameters_.button_gripper_release_))
00155             sendGripperCommand(parameters_.gripper_release_position_, parameters_.gripper_release_effort_);
00156         else if (joy->buttons.at(parameters_.button_gripper_grasp_))
00157             sendGripperCommand(parameters_.gripper_grasp_position_, parameters_.gripper_grasp_effort_);
00158         else if (joy->buttons.at(parameters_.button_grasp_done_))
00159             sendGraspDone();
00160     }
00161 
00162     if (have_vel_commands)
00163         cmd_vel_.header.stamp = joy->header.stamp;
00164 
00165     if (have_vel_commands || repeat_vel_commands_)
00166     {
00167       sendCmdVel();
00168       repeat_vel_commands_ = have_vel_commands;
00169     }
00170 }
00171 
00172 void CartesianArmTeleopNode::sendCmdVel()
00173 {
00174     cmd_vel_pub_.publish(cmd_vel_);
00175 }
00176 
00177 void CartesianArmTeleopNode::sendGripperCommand(double position, double max_effort)
00178 {
00179     if (gripper_command_ac_)
00180     {
00181         control_msgs::GripperCommandGoal goal;
00182         goal.command.position = position;
00183         goal.command.max_effort = max_effort;
00184         gripper_command_ac_->sendGoal(goal);
00185     }
00186 }
00187 
00188 double CartesianArmTeleopNode::limit(double value, double min, double max)
00189 {
00190     if (value < min)
00191       return min;
00192     if (value > max)
00193       return max;
00194     return value;
00195 }
00196 
00197 void CartesianArmTeleopNode::sendGraspDone()
00198 {
00199     std_msgs::Empty msg;
00200     grasping_done_pub_.publish(msg);
00201 }
00202 
00203 template <typename T>
00204 void CartesianArmTeleopNode::getRequiredParameter(ros::NodeHandle & private_nh, const std::string & key, T & value)
00205 {
00206     if (!private_nh.getParam(key, value))
00207     {
00208         ROS_FATAL_STREAM("Missing required node parameter " << key);
00209         throw std::runtime_error("Missing required node parameter " + key);
00210     }
00211 }
00212 
00213 template <typename T>
00214 void CartesianArmTeleopNode::getOptionalParameter(ros::NodeHandle & private_nh, const std::string & key, T & value, T default_value)
00215 {
00216     if (!private_nh.getParam(key, value))
00217     {
00218         value = default_value;
00219         ROS_WARN_STREAM("Missing optional node parameter " << key << ", using default value " << default_value);
00220     }
00221 }
00222 
00223 
00224 
00225 
00226 }
00227 
00228 
00229 int main(int argc, char ** argv)
00230 {
00231     try
00232     {
00233         ros::init(argc, argv, "cartesian_arm_teleop");
00234         tedusar_cartesian_arm_teleop::CartesianArmTeleopNode node;
00235         node.init();
00236 
00237         ros::spin();
00238     }
00239     catch (std::exception & ex)
00240     {
00241         ROS_ERROR("Unhandled exception: %s", ex.what());
00242         return 1;
00243     }
00244     catch (...)
00245     {
00246         ROS_ERROR("Unhandled exception!");
00247         return 1;
00248     }
00249 
00250     return 0;
00251 }


tedusar_cartesian_arm_teleop
Author(s): Alexander Buchegger
autogenerated on Wed Aug 26 2015 16:30:33