joy.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Daniel Koch and James Jackson, BYU MAGICC Lab.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * * Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <rosflight_utils/joy.h>
33 #include <gazebo_msgs/SetModelState.h>
34 #include <std_srvs/Empty.h>
35 
37 {
38  ros::NodeHandle pnh("~");
40 
41  pnh.param<std::string>("command_topic", command_topic_, "command");
42  pnh.param<std::string>("autopilot_command_topic", autopilot_command_topic_, "autopilot_command");
43 
44  // Get global parameters
45  double max_thrust;
46  namespace_nh.param<double>("mass", mass_, 3.61);
47  namespace_nh.param<double>("max_F", max_thrust, 64.50);
48  namespace_nh.param<std::string>("mav_name", mav_name_,"shredder");
49  equilibrium_thrust_ = (mass_*9.80665) / max_thrust;
50 
51  // Get Parameters from joystick configuration yaml
52  pnh.param<std::string>("gazebo_namespace", gazebo_ns_, "");
53  pnh.param<int>("x_axis", axes_.x, 1);
54  pnh.param<int>("y_axis", axes_.y, 2);
55  pnh.param<int>("F_axis", axes_.F, 0);
56  pnh.param<int>("z_axis", axes_.z, 4);
57 
58  pnh.param<int>("x_sign", axes_.x_direction, 1);
59  pnh.param<int>("y_sign", axes_.y_direction, 1);
60  pnh.param<int>("F_sign", axes_.F_direction, -1);
61  pnh.param<int>("z_sign", axes_.z_direction, 1);
62 
63  pnh.param<double>("max_aileron", max_.aileron, 15.0 * M_PI / 180.0);
64  pnh.param<double>("max_elevator", max_.elevator, 25.0 * M_PI / 180.0);
65  pnh.param<double>("max_rudder", max_.rudder, 15.0 * M_PI / 180.0);
66 
67  pnh.param<double>("max_roll_rate", max_.roll_rate, 360.0 * M_PI / 180.0);
68  pnh.param<double>("max_pitch_rate", max_.pitch_rate, 360.0 * M_PI / 180.0);
69  pnh.param<double>("max_yaw_rate", max_.yaw_rate, 360.0 * M_PI / 180.0);
70 
71  pnh.param<double>("max_roll_angle", max_.roll, 45.0 * M_PI / 180.0);
72  pnh.param<double>("max_pitch_angle", max_.pitch, 45.0 * M_PI / 180.0);
73 
74  pnh.param<double>("max_xvel", max_.xvel, 1.5);
75  pnh.param<double>("max_yvel", max_.yvel, 1.5);
76  pnh.param<double>("max_zvel", max_.zvel, 1.5);
77  command_msg_.mode = pnh.param<int>("control_mode", (int)rosflight_msgs::Command::MODE_ROLL_PITCH_YAWRATE_THROTTLE);
78 
79  pnh.param<double>("reset_pos_x", reset_pose_.position.x, 0.0);
80  pnh.param<double>("reset_pos_y", reset_pose_.position.y, 0.0);
81  pnh.param<double>("reset_pos_z", reset_pose_.position.z, 0.0);
82  pnh.param<double>("reset_orient_x", reset_pose_.orientation.x, 0.0);
83  pnh.param<double>("reset_orient_x", reset_pose_.orientation.y, 0.0);
84  pnh.param<double>("reset_orient_x", reset_pose_.orientation.z, 0.0);
85  pnh.param<double>("reset_orient_x", reset_pose_.orientation.w, 0.0);
86  pnh.param<double>("reset_linear_twist_x", reset_twist_.linear.x, 0.0);
87  pnh.param<double>("reset_linear_twist_y", reset_twist_.linear.y, 0.0);
88  pnh.param<double>("reset_linear_twist_z", reset_twist_.linear.z, 0.0);
89  pnh.param<double>("reset_angular_twist_x", reset_twist_.angular.x, 0.0);
90  pnh.param<double>("reset_angular_twist_x", reset_twist_.angular.y, 0.0);
91  pnh.param<double>("reset_angular_twist_x", reset_twist_.angular.z, 0.0);
92 
93  // Sets which buttons are tied to which commands
94  pnh.param<int>("button_takeoff", buttons_.fly.index, 0);
95  pnh.param<int>("button_mode", buttons_.mode.index, 1);
96  pnh.param<int>("button_reset", buttons_.reset.index, 9);
97  pnh.param<int>("button_pause", buttons_.pause.index, 8);
98  pnh.param<int>("button_override", buttons_.override.index, 8);
99 
100  command_pub_ = nh_.advertise<rosflight_msgs::Command>(command_topic_, 10);
101 
102  command_msg_.x = 0;
103  command_msg_.y = 0;
104  command_msg_.z = 0;
105  command_msg_.F = 0;
106  command_msg_.ignore = 0xFF;
107 
108  current_yaw_vel_ = 0;
109 
111  autopilot_command_sub_ = nh_.subscribe(autopilot_command_topic_, 10, &Joy::APCommandCallback, this);
112  joy_sub_ = nh_.subscribe("joy", 10, &Joy::JoyCallback, this);
115 
117 }
118 
120 {
121  command_msg_.x = 0;
122  command_msg_.y = 0;
123  command_msg_.z = 0;
124  command_msg_.F = 0;
125 }
126 
127 /* Resets the mav back to origin */
129 {
130  ROS_INFO("Mav position reset.");
131  ros::NodeHandle n;
132 
133  gazebo_msgs::ModelState modelstate;
134  modelstate.model_name = (std::string)mav_name_;
135  modelstate.reference_frame = (std::string) "world";
136  modelstate.pose = reset_pose_;
137  modelstate.twist = reset_twist_;
138 
139  ros::ServiceClient client = n.serviceClient<gazebo_msgs::SetModelState>("/gazebo/set_model_state");
140  gazebo_msgs::SetModelState setmodelstate;
141  setmodelstate.request.model_state = modelstate;
142  client.call(setmodelstate);
143 }
144 
145 // Pauses the gazebo physics and time
147 {
148  ROS_INFO("Simulation paused.");
149  ros::NodeHandle n;
150 
151  ros::ServiceClient client = n.serviceClient<std_srvs::Empty>("/gazebo/pause_physics");
152  std_srvs::Empty pauseSim;
153  client.call(pauseSim);
154 }
155 
156 // Resumes the gazebo physics and time
158 {
159  ROS_INFO("Simulation resumed.");
160  ros::NodeHandle n;
161 
162  ros::ServiceClient client = n.serviceClient<std_srvs::Empty>("/gazebo/unpause_physics");
163  std_srvs::Empty resumeSim;
164  client.call(resumeSim);
166 }
167 
168 void Joy::APCommandCallback(const rosflight_msgs::CommandConstPtr &msg)
169 {
170  autopilot_command_ = *msg;
171 }
172 
173 void Joy::JoyCallback(const sensor_msgs::JoyConstPtr &msg)
174 {
175  double dt = ros::Time::now().toSec() - last_time_;
177 
178  current_joy_ = *msg;
179 
180  // Perform button actions
181  if (msg->buttons[buttons_.override.index] == 0 && buttons_.override.prev_value == 1)
182  {
183  override_autopilot_ = true;
184  }
186 
187  // Resets the mav to the origin
188  if (msg->buttons[buttons_.reset.index] == 0 && buttons_.reset.prev_value == 1) // button release
189  {
190  ResetMav();
191  }
192  buttons_.reset.prev_value = msg->buttons[buttons_.reset.index];
193 
194  // Pauses/Unpauses the simulation
195  if (msg->buttons[buttons_.pause.index] == 0 && buttons_.pause.prev_value == 1) // button release
196  {
197  if (!paused)
198  {
199  PauseSimulation();
200  paused = true;
201  }
202  else
203  {
205  paused = false;
206  }
207  }
208  buttons_.pause.prev_value = msg->buttons[buttons_.pause.index];
209 
210  if (msg->buttons[buttons_.mode.index] == 0 && buttons_.mode.prev_value == 1)
211  {
212  command_msg_.mode = (command_msg_.mode + 1) % 6;
213  if (command_msg_.mode == rosflight_msgs::Command::MODE_PASS_THROUGH)
214  {
215  ROS_INFO("Passthrough");
216  }
217  else if (command_msg_.mode == rosflight_msgs::Command::MODE_ROLL_PITCH_YAWRATE_THROTTLE)
218  {
219  ROS_INFO("Angle Mode");
220  }
221  else if (command_msg_.mode == rosflight_msgs::Command::MODE_ROLL_PITCH_YAWRATE_ALTITUDE)
222  {
223  ROS_INFO("Altitude Mode");
224  }
225  else if (command_msg_.mode == rosflight_msgs::Command::MODE_XVEL_YVEL_YAWRATE_ALTITUDE)
226  {
227  ROS_INFO("Velocity Mode");
228  }
229  else if (command_msg_.mode == rosflight_msgs::Command::MODE_XPOS_YPOS_YAW_ALTITUDE)
230  {
231  ROS_INFO("Position Mode");
232  }
233  else
234  {
235  ROS_INFO("Passthrough");
236  }
237  }
238  buttons_.mode.prev_value = msg->buttons[buttons_.mode.index];
239 
240  // calculate the output command from the joysticks
242  {
243  command_msg_.F = msg->axes[axes_.F] * axes_.F_direction;
244  command_msg_.x = msg->axes[axes_.x] * axes_.x_direction;
245  command_msg_.y = msg->axes[axes_.y] * axes_.y_direction;
246  command_msg_.z = msg->axes[axes_.z] * axes_.z_direction;
247 
248  switch (command_msg_.mode)
249  {
250  case rosflight_msgs::Command::MODE_ROLLRATE_PITCHRATE_YAWRATE_THROTTLE:
254  if (command_msg_.F > 0.0)
255  {
257  }
258  else
259  {
261  }
262  break;
263 
264  case rosflight_msgs::Command::MODE_ROLL_PITCH_YAWRATE_THROTTLE:
265  command_msg_.x *= max_.roll;
266  command_msg_.y *= max_.pitch;
268  if (command_msg_.F > 0.0)
269  {
271  }
272  else
273  {
275  }
276  break;
277 
278  case rosflight_msgs::Command::MODE_ROLL_PITCH_YAWRATE_ALTITUDE:
279  command_msg_.x *= max_.roll;
280  command_msg_.y *= max_.pitch;
282  // Integrate altitude
285  break;
286 
287  case rosflight_msgs::Command::MODE_XVEL_YVEL_YAWRATE_ALTITUDE:
288  {
289  // Remember that roll affects y velocity and pitch affects -x velocity
290  double original_x = command_msg_.x;
291  command_msg_.x = max_.xvel * -1.0 * command_msg_.y;
292  command_msg_.y = max_.yvel * original_x;
294  // Integrate altitude
297  break;
298  }
299 
300  case rosflight_msgs::Command::MODE_XPOS_YPOS_YAW_ALTITUDE:
301  // Integrate all axes
302  // (Remember that roll affects y velocity and pitch affects -x velocity)
305 
308 
311 
314  break;
315  }
316  }
317  else
318  {
320  }
321 
322  Publish();
323 }
324 
326 {
328 }
329 
330 int main(int argc, char **argv)
331 {
332  ros::init(argc, argv, "rosflight_utils_joy");
333  Joy joy;
334 
335  ros::spin();
336 
337  return 0;
338 }
int main(int argc, char **argv)
Definition: joy.cpp:330
void PauseSimulation()
Definition: joy.cpp:146
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
double aileron
Definition: joy.h:61
double last_time_
Definition: joy.h:121
double current_y_setpoint_
Definition: joy.h:119
Definition: joy.h:85
int F
Definition: joy.h:44
double yaw_rate
Definition: joy.h:59
double current_yaw_vel_
Definition: joy.h:124
void publish(const boost::shared_ptr< M > &message) const
bool prev_value
Definition: joy.h:73
sensor_msgs::Joy current_joy_
Definition: joy.h:110
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
int y
Definition: joy.h:43
std::string mav_name_
Definition: joy.h:99
geometry_msgs::Twist reset_twist_
Definition: joy.h:115
int y_direction
Definition: joy.h:47
Buttons buttons_
Definition: joy.h:113
rosflight_msgs::Command command_msg_
Definition: joy.h:108
double zvel
Definition: joy.h:67
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::string gazebo_ns_
Definition: joy.h:100
bool call(MReq &req, MRes &res)
ros::Subscriber autopilot_command_sub_
Definition: joy.h:92
bool paused
Definition: joy.h:105
double equilibrium_thrust_
Definition: joy.h:106
double current_x_setpoint_
Definition: joy.h:118
double roll_rate
Definition: joy.h:57
Button override
Definition: joy.h:82
double xvel
Definition: joy.h:65
void Publish()
Definition: joy.cpp:325
int index
Definition: joy.h:72
ros::Publisher command_pub_
Definition: joy.h:91
double current_yaw_setpoint_
Definition: joy.h:120
void ResetMav()
Definition: joy.cpp:128
std::string autopilot_command_topic_
Definition: joy.h:97
void JoyCallback(const sensor_msgs::JoyConstPtr &msg)
Definition: joy.cpp:173
ROSCPP_DECL const std::string & getNamespace()
double roll
Definition: joy.h:54
ros::NodeHandle nh_
Definition: joy.h:90
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
bool override_autopilot_
Definition: joy.h:104
double pitch_rate
Definition: joy.h:58
double rudder
Definition: joy.h:63
int z
Definition: joy.h:45
Button fly
Definition: joy.h:78
const std::string & getNamespace() const
double current_altitude_setpoint_
Definition: joy.h:117
double pitch
Definition: joy.h:55
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
ros::Subscriber joy_sub_
Definition: joy.h:93
Max max_
Definition: joy.h:112
void StopMav()
Definition: joy.cpp:119
rosflight_msgs::Command autopilot_command_
Definition: joy.h:109
int x_direction
Definition: joy.h:46
double elevator
Definition: joy.h:62
Axes axes_
Definition: joy.h:102
double yvel
Definition: joy.h:66
void ResumeSimulation()
Definition: joy.cpp:157
int z_direction
Definition: joy.h:49
Joy()
Definition: joy.cpp:36
int F_direction
Definition: joy.h:48
geometry_msgs::Pose reset_pose_
Definition: joy.h:114
std::string namespace_
Definition: joy.h:95
static Time now()
Button pause
Definition: joy.h:81
std::string command_topic_
Definition: joy.h:96
int x
Definition: joy.h:42
void APCommandCallback(const rosflight_msgs::CommandConstPtr &msg)
Definition: joy.cpp:168
#define M_PI
Definition: turbomath.h:36
Button mode
Definition: joy.h:79
double mass_
Definition: joy.h:126
Button reset
Definition: joy.h:80


rosflight_utils
Author(s):
autogenerated on Wed Jul 3 2019 20:00:31