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 #ifndef JOYSTICK_HANDLER_H__
00030 #define JOYSTICK_HANDLER_H__
00031
00032 #include <ros/ros.h>
00033
00034 #include <geometry_msgs/Point.h>
00035 #include <geometry_msgs/Twist.h>
00036
00037 #include <sensor_msgs/Joy.h>
00038
00039
00040
00041 namespace vigir_footstep_planning
00042 {
00043 class JoystickInputHandle
00044 {
00045 public:
00046 JoystickInputHandle(double thresh = 1.0)
00047 : val_(0.0)
00048 , thresh_(thresh)
00049 {}
00050
00051 virtual void joyCallback(const sensor_msgs::Joy::ConstPtr& joy_msg) = 0;
00052
00053 virtual double getValue() const { return val_; }
00054 virtual bool isPressed() const { return std::abs(val_) >= thresh_; }
00055
00056 typedef boost::shared_ptr<JoystickInputHandle> Ptr;
00057 typedef boost::shared_ptr<JoystickInputHandle> ConstPtr;
00058
00059 protected:
00060 double val_;
00061 double thresh_;
00062 };
00063
00064 class JoystickButton
00065 : public JoystickInputHandle
00066 {
00067 public:
00068 JoystickButton(int button, double thresh = 1.0)
00069 : JoystickInputHandle(thresh)
00070 , button_id_(button)
00071 {
00072 ROS_INFO("[Button %i]", button_id_);
00073 }
00074
00075 JoystickButton(XmlRpc::XmlRpcValue& params)
00076 : JoystickButton(params["button"], params["thresh"])
00077 {}
00078
00079 void joyCallback(const sensor_msgs::Joy::ConstPtr& joy_msg) override
00080 {
00081 if (joy_msg->buttons.size() <= button_id_)
00082 ROS_ERROR_THROTTLE(1.0, "Couldn't read button %i as only %lu buttons exist. Maybe wrong controller connected?", button_id_, joy_msg->buttons.size());
00083 else
00084 val_ = joy_msg->buttons[button_id_];
00085 }
00086
00087 protected:
00088 int button_id_;
00089 };
00090
00091 class JoystickAxis
00092 : public JoystickInputHandle
00093 {
00094 public:
00095 JoystickAxis(int axis, double thresh = 1.0, double min_val = -1.0, double max_val = 1.0, double zero_val = 0.0, double calib_offset = 0.0, bool invert = false)
00096 : JoystickInputHandle(thresh)
00097 , axis_id_(axis)
00098 , min_(min_val)
00099 , max_(max_val)
00100 , zero_val_(zero_val)
00101 , calib_offset_(calib_offset)
00102 , invert_(invert)
00103 , scale_factor_(2.0/(max_-min_))
00104 , scale_offset_(0.5*(max_+min_))
00105 {
00106 ROS_INFO("[Axis %i] %f - (%f, %f) - %f", axis, thresh, min_val, max_val, calib_offset);
00107 }
00108
00109 JoystickAxis(XmlRpc::XmlRpcValue& params)
00110 : JoystickAxis(params["axis"], params["thresh"], params["min"], params["max"], params["zero"], params["calib"], params["invert"])
00111 {}
00112
00113 void joyCallback(const sensor_msgs::Joy::ConstPtr& joy_msg) override
00114 {
00115 if (joy_msg->axes.size() <= axis_id_)
00116 ROS_ERROR_THROTTLE(1.0, "Couldn't read axis %i as only %lu axes exist. Maybe wrong controller connected?", axis_id_, joy_msg->axes.size());
00117 else
00118 {
00119
00120 val_ = joy_msg->axes[axis_id_] - calib_offset_;
00121
00122
00123 if (invert_)
00124 val_ = -val_;
00125
00126
00127 val_ = std::min(std::max(val_, min_), max_);
00128 val_ = val_ * scale_factor_ + scale_offset_;
00129 }
00130 }
00131
00132 bool isPressed() const override { return std::abs(val_-zero_val_) >= thresh_; }
00133
00134 protected:
00135 int axis_id_;
00136
00137 double min_;
00138 double max_;
00139 double zero_val_;
00140
00141 double calib_offset_;
00142
00143 bool invert_;
00144
00145 double scale_factor_;
00146 double scale_offset_;
00147 };
00148
00149 class JoystickHandler
00150 {
00151 public:
00152 JoystickHandler(ros::NodeHandle& nh);
00153 virtual ~JoystickHandler();
00154
00155
00156 void joyCallback(const sensor_msgs::Joy::ConstPtr& last_joy_msg);
00157
00158 void getJoystickCommand(geometry_msgs::Twist& twist, bool& enable) const;
00159
00160 typedef boost::shared_ptr<JoystickHandler> Ptr;
00161 typedef boost::shared_ptr<JoystickHandler> ConstPtr;
00162
00163 protected:
00164 void initJoystickInput(XmlRpc::XmlRpcValue& params, std::string name, JoystickInputHandle::Ptr& handle) const;
00165
00166 void updateJoystickCommand(double elapsed_time_sec, double joy_val, double& val, double min_vel, double max_vel, double min_acc, double max_acc, double sensivity) const;
00167 double convertJoyAxisToAcc(double elapsed_time_sec, double joy_val, double val, double min_vel, double max_vel) const;
00168
00169
00170 JoystickInputHandle::Ptr x_axis_;
00171 JoystickInputHandle::Ptr y_axis_;
00172 JoystickInputHandle::Ptr yaw_axis_;
00173
00174 JoystickInputHandle::Ptr enable_;
00175
00176 bool has_joy_msg_;
00177
00178
00179 ros::Subscriber joy_sub_;
00180 };
00181 }
00182
00183 #endif