40 #include "sensor_msgs/Joy.h" 41 #include "geometry_msgs/Twist.h" 42 #include "sensor_msgs/JointState.h" 43 #include "trajectory_msgs/JointTrajectory.h" 44 #include "pr2_controllers_msgs/JointTrajectoryControllerState.h" 45 #include "topic_tools/MuxSelect.h" 46 #include "std_msgs/String.h" 48 #include "std_msgs/Float64.h" 50 #define TORSO_TOPIC "torso_controller/command" 51 #define HEAD_TOPIC "head_traj_controller/command" 59 geometry_msgs::Twist
cmd;
63 double req_vx,
req_vy, req_vw, req_torso, req_pan, req_tilt;
65 double max_vx, max_vy, max_vw, max_vx_run,
max_vy_run, max_vw_run;
66 double max_pan, max_tilt, min_tilt, pan_step,
tilt_step;
67 int axis_vx,
axis_vy, axis_vw, axis_pan, axis_tilt;
90 max_vx(0.6), max_vy(0.6), max_vw(0.8),
91 max_vx_run(0.6), max_vy_run(0.6), max_vw_run(0.8),
92 max_pan(2.7), max_tilt(1.4), min_tilt(-0.4),
93 pan_step(0.02), tilt_step(0.015),
94 deadman_no_publish_(deadman_no_publish),
95 torso_publish_(false), head_publish_(false),
96 deadman_(false), cmd_head(false),
97 use_mux_(false), last_deadman_(false),
103 cmd.linear.x = cmd.linear.y = cmd.angular.z = 0;
104 req_pan = req_tilt = 0;
109 n_private_.
param(
"use_mux", use_mux_,
false);
111 n_private_.
param(
"max_vx", max_vx, max_vx);
112 n_private_.
param(
"max_vy", max_vy, max_vy);
113 n_private_.
param(
"max_vw", max_vw, max_vw);
116 n_private_.
param(
"max_vx_run", max_vx_run, max_vx_run);
117 n_private_.
param(
"max_vy_run", max_vy_run, max_vy_run);
118 n_private_.
param(
"max_vw_run", max_vw_run, max_vw_run);
121 n_private_.
param(
"max_pan", max_pan, max_pan);
122 n_private_.
param(
"max_tilt", max_tilt, max_tilt);
123 n_private_.
param(
"min_tilt", min_tilt, min_tilt);
125 n_private_.
param(
"tilt_step", tilt_step, tilt_step);
126 n_private_.
param(
"pan_step", pan_step, pan_step);
128 n_private_.
param(
"axis_pan", axis_pan, 0);
129 n_private_.
param(
"axis_tilt", axis_tilt, 2);
131 n_private_.
param(
"axis_vx", axis_vx, 3);
132 n_private_.
param(
"axis_vw", axis_vw, 0);
133 n_private_.
param(
"axis_vy", axis_vy, 2);
135 n_private_.
param(
"torso_step", torso_step, 0.01);
136 n_private_.
param(
"min_torso", min_torso, 0.0);
137 n_private_.
param(
"max_torso", max_torso, 0.3);
139 n_private_.
param(
"deadman_button", deadman_button, 0);
140 n_private_.
param(
"run_button", run_button, 0);
141 n_private_.
param(
"torso_dn_button", torso_dn_button, 0);
142 n_private_.
param(
"torso_up_button", torso_up_button, 0);
143 n_private_.
param(
"head_button", head_button, 0);
145 double joy_msg_timeout;
146 n_private_.
param(
"joy_msg_timeout", joy_msg_timeout, 0.5);
147 if (joy_msg_timeout <= 0)
150 ROS_DEBUG(
"joy_msg_timeout <= 0 -> no timeout");
154 joy_msg_timeout_.
fromSec(joy_msg_timeout);
159 ROS_DEBUG(
"max_vy: %.3f m/s\n", max_vy);
160 ROS_DEBUG(
"max_vw: %.3f deg/s\n", max_vw*180.0/M_PI);
162 ROS_DEBUG(
"max_vx_run: %.3f m/s\n", max_vx_run);
163 ROS_DEBUG(
"max_vy_run: %.3f m/s\n", max_vy_run);
164 ROS_DEBUG(
"max_vw_run: %.3f deg/s\n", max_vw_run*180.0/M_PI);
166 ROS_DEBUG(
"tilt step: %.3f rad\n", tilt_step);
167 ROS_DEBUG(
"pan step: %.3f rad\n", pan_step);
169 ROS_DEBUG(
"axis_vx: %d\n", axis_vx);
170 ROS_DEBUG(
"axis_vy: %d\n", axis_vy);
171 ROS_DEBUG(
"axis_vw: %d\n", axis_vw);
172 ROS_DEBUG(
"axis_pan: %d\n", axis_pan);
173 ROS_DEBUG(
"axis_tilt: %d\n", axis_tilt);
175 ROS_DEBUG(
"deadman_button: %d\n", deadman_button);
176 ROS_DEBUG(
"run_button: %d\n", run_button);
177 ROS_DEBUG(
"torso_dn_button: %d\n", torso_dn_button);
178 ROS_DEBUG(
"torso_up_button: %d\n", torso_up_button);
179 ROS_DEBUG(
"head_button: %d\n", head_button);
180 ROS_DEBUG(
"joy_msg_timeout: %f\n", joy_msg_timeout);
182 if (torso_dn_button != 0 && torso_up_button != 0)
184 torso_publish_ =
true;
188 if (head_button != 0)
191 head_publish_ =
true;
194 vel_pub_ = n_.
advertise<geometry_msgs::Twist>(
"cmd_vel", 1);
203 mux_client_ = mux_nh.
serviceClient<topic_tools::MuxSelect>(
"select");
210 void joy_cb(
const sensor_msgs::Joy::ConstPtr& joy_msg)
213 if(joy_msg->header.stamp == last_processed_joy_message_.header.stamp) {
216 ROS_WARN_THROTTLE(1.0,
"Received Joy message with same timestamp multiple times. Ignoring subsequent messages.");
220 last_processed_joy_message_ = *joy_msg;
225 deadman_ = (((
unsigned int)deadman_button < joy_msg->buttons.size()) && joy_msg->buttons[deadman_button]);
230 cmd_head = (((
unsigned int)head_button < joy_msg->buttons.size()) && joy_msg->buttons[head_button] && head_publish_);
233 bool running = (((
unsigned int)run_button < joy_msg->buttons.size()) && joy_msg->buttons[run_button]);
234 double vx = running ? max_vx_run : max_vx;
235 double vy = running ? max_vy_run : max_vy;
236 double vw = running ? max_vw_run : max_vw;
238 if((axis_vx >= 0) && (((
unsigned int)axis_vx) < joy_msg->axes.size()) && !cmd_head)
239 req_vx = joy_msg->axes[axis_vx] * vx;
242 if((axis_vy >= 0) && (((
unsigned int)axis_vy) < joy_msg->axes.size()) && !cmd_head)
243 req_vy = joy_msg->axes[axis_vy] * vy;
246 if((axis_vw >= 0) && (((
unsigned int)axis_vw) < joy_msg->axes.size()) && !cmd_head)
247 req_vw = joy_msg->axes[axis_vw] * vw;
253 req_vx = max(
min(req_vx, vx), -vx);
254 req_vy = max(
min(req_vy, vy), -vy);
255 req_vw = max(
min(req_vw, vw), -vw);
260 if (deadman_ && cmd_head)
262 if (axis_pan >= 0 && axis_pan < (
int)joy_msg->axes.size())
264 req_pan_vel = joy_msg->axes[axis_pan] * pan_step;
267 if (axis_tilt >= 0 && axis_tilt < (
int)joy_msg->axes.size())
269 req_tilt_vel = joy_msg->axes[axis_tilt] * tilt_step;
274 bool down = (((
unsigned int)torso_dn_button < joy_msg->buttons.size()) && joy_msg->buttons[torso_dn_button]);
275 bool up = (((
unsigned int)torso_up_button < joy_msg->buttons.size()) && joy_msg->buttons[torso_up_button]);
279 req_torso_vel = -torso_step;
280 else if (up && !down)
281 req_torso_vel = torso_step;
290 last_recieved_joy_message_time_ + joy_msg_timeout_ >
ros::Time::now())
293 if(use_mux_ && !last_deadman_){
294 topic_tools::MuxSelect select_srv;
295 select_srv.request.topic = vel_pub_.
getTopic();
296 if(mux_client_.
call(select_srv)){
297 last_selected_topic_ = select_srv.response.prev_topic;
298 ROS_DEBUG(
"Setting mux to %s for teleop", select_srv.request.topic.c_str());
301 ROS_ERROR(
"Failed to call select service %s on mux. Are you sure that it is up and connected correctly to the teleop node?", mux_client_.
getService().c_str());
306 cmd.linear.x = req_vx;
307 cmd.linear.y = req_vy;
308 cmd.angular.z = req_vw;
315 double horizon = 5.0 * dt;
317 trajectory_msgs::JointTrajectory traj;
319 traj.joint_names.push_back(
"torso_lift_joint");
320 traj.points.resize(1);
321 traj.points[0].positions.push_back(req_torso + req_torso_vel * horizon);
322 traj.points[0].velocities.push_back(req_torso_vel);
327 req_torso += req_torso_vel * dt;
328 req_torso = max(
min(req_torso, max_torso), min_torso);
332 if (cmd_head && head_publish_)
335 double horizon = 3.0 * dt;
337 trajectory_msgs::JointTrajectory traj;
339 traj.joint_names.push_back(
"head_pan_joint");
340 traj.joint_names.push_back(
"head_tilt_joint");
341 traj.points.resize(1);
342 traj.points[0].positions.push_back(req_pan + req_pan_vel * horizon);
343 traj.points[0].velocities.push_back(req_pan_vel);
344 traj.points[0].positions.push_back(req_tilt + req_tilt_vel * horizon);
345 traj.points[0].velocities.push_back(req_tilt_vel);
351 fprintf(stdout,
"teleop_base:: %f, %f, %f. Head:: %f, %f. Torso cmd: %f.\n",
352 cmd.linear.x, cmd.linear.y, cmd.angular.z, req_pan, req_tilt, req_torso_vel);
354 fprintf(stdout,
"teleop_base:: %f, %f, %f. Head:: %f, %f\n",
355 cmd.linear.x ,cmd.linear.y, cmd.angular.z, req_pan, req_tilt);
360 if(use_mux_ && last_deadman_){
361 topic_tools::MuxSelect select_srv;
362 select_srv.request.topic = last_selected_topic_;
363 if(mux_client_.
call(select_srv)){
364 ROS_DEBUG(
"Setting mux back to %s", last_selected_topic_.c_str());
367 ROS_ERROR(
"Failed to call select service %s on mux. Are you sure that it is up and connected correctly to the teleop node?", mux_client_.
getService().c_str());
372 cmd.linear.x = cmd.linear.y = cmd.angular.z = 0;
373 if (!deadman_no_publish_)
381 last_deadman_ = deadman_;
384 void torsoCB(
const pr2_controllers_msgs::JointTrajectoryControllerState::ConstPtr &msg)
386 double xd = req_torso;
387 const double A = 0.003;
388 if (fabs(msg->actual.positions[0] - xd) > A*1.001)
390 req_torso =
min(max(msg->actual.positions[0] - A, xd), msg->actual.positions[0] + A);
394 void headCB(
const pr2_controllers_msgs::JointTrajectoryControllerState::ConstPtr &msg)
397 req_pan = msg->desired.positions[0];
398 req_pan = max(
min(req_pan, max_pan), -max_pan);
399 req_tilt = msg->desired.positions[1];
400 req_tilt = max(
min(req_tilt, max_tilt), min_tilt);
404 int main(
int argc,
char **argv)
407 const char* opt_no_publish =
"--deadman_no_publish";
409 bool no_publish =
false;
410 for(
int i=1;i<argc;i++)
412 if(!strncmp(argv[i], opt_no_publish, strlen(opt_no_publish)))
421 while (teleop_pr2.
n_.
ok())
void joy_cb(const sensor_msgs::Joy::ConstPtr &joy_msg)
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
ros::Subscriber torso_state_sub_
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
TeleopPR2(bool deadman_no_publish=false)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool call(MReq &req, MRes &res)
void torsoCB(const pr2_controllers_msgs::JointTrajectoryControllerState::ConstPtr &msg)
std::string last_selected_topic_
ros::Subscriber head_state_sub_
ros::Publisher torso_pub_
#define ROS_WARN_THROTTLE(period,...)
Duration & fromSec(double t)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
ros::NodeHandle n_private_
int main(int argc, char **argv)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::Duration joy_msg_timeout_
#define TORSO_TOPIC
Converts joystick commands on /joy to commands to PR2 base, spine, head.
std::string getTopic() const
ROSCPP_DECL void spinOnce()
sensor_msgs::Joy last_processed_joy_message_
void headCB(const pr2_controllers_msgs::JointTrajectoryControllerState::ConstPtr &msg)
ros::ServiceClient mux_client_
ros::Time last_recieved_joy_message_time_