Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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 }