PX4 Teleop
px4_teleop_cmds.hpp
Go to the documentation of this file.
1 
7 #ifndef INCLUDED_px4_teleop_cmds_hpp_
8 #define INCLUDED_px4_teleop_cmds_hpp_
9 
10 // roscpp
11 #include <ros/ros.h>
12 
13 // geometry_msgs
14 #include <geometry_msgs/TwistStamped.h>
15 #include <geometry_msgs/PoseStamped.h>
16 
17 // sensor_msgs
18 #include <sensor_msgs/NavSatFix.h>
19 
20 // mavros_msgs
21 #include <mavros_msgs/CommandBool.h>
22 #include <mavros_msgs/SetMode.h>
23 #include <mavros_msgs/State.h>
24 #include <mavros_msgs/CommandTOL.h>
25 
26 
32 void arm(ros::ServiceClient& client, mavros_msgs::State& state){
33 
34  ros::Rate rate(20);
35 
36  // reject arming if already armed
37  if(state.armed){
38  ROS_WARN("Arm Rejected. Already armed.");
39  return;
40  }
41  mavros_msgs::CommandBool arm_cmd;
42  arm_cmd.request.value = true;
43 
44  // call arm service
45  while( not(client.call(arm_cmd)) and
46  arm_cmd.response.success){
47  ros::spinOnce();
48  rate.sleep();
49  }
50  ROS_INFO("Vehicle armed.");
51  return;
52 }
53 
62 void takeoff(ros::ServiceClient& client,
63  mavros_msgs::State& state,
64  geometry_msgs::PoseStamped& lpos,
65  sensor_msgs::NavSatFix& hp,
66  double height){
67 
68  ros::Rate rate(20);
69 
70  if(!state.armed){
71  ROS_WARN("Takeoff rejected. Arm first.");
72  return;
73  }
74 
75  if(lpos.pose.position.z > 1.0){
76  ROS_WARN("Takeoff rejected. Already took off.");
77  return;
78  }
79 
80  double home_alt = hp.altitude;
81  double home_lon = hp.longitude;
82  double home_lat = hp.latitude;
83 
84  mavros_msgs::CommandTOL takeoff_cmd;
85  takeoff_cmd.request.altitude = home_alt + height;
86  takeoff_cmd.request.longitude = home_lon;
87  takeoff_cmd.request.latitude = home_lat;
88 
89  ros::Time takeoff_last_request = ros::Time::now();
90 
91  ROS_DEBUG("set lat: %f, lon: %f, alt: %f", home_lat, home_lon, home_alt);
92 
93  while( not(client.call(takeoff_cmd)) and
94  takeoff_cmd.response.success){
95  ros::spinOnce();
96  rate.sleep();
97  if(ros::Time::now()-takeoff_last_request>ros::Duration(3.0)){
98  ROS_WARN("Takeoff service call failed.");
99  return;
100  }
101  }
102 
103  takeoff_last_request = ros::Time::now();
104 
105  while(lpos.pose.position.z < height-0.1){
106  ros::spinOnce();
107  rate.sleep();
108  if(ros::Time::now()-takeoff_last_request>ros::Duration(3.0)){
109  ROS_WARN("Takeoff failed.");
110  return;
111  }
112  }
113  ROS_INFO("Vehicle tookoff.");
114  return;
115 }
116 
124 void land(ros::ServiceClient& client,
125  geometry_msgs::PoseStamped& lpos,
126  sensor_msgs::NavSatFix& gpos,
127  sensor_msgs::NavSatFix& hp){
128 
129  ros::Rate rate(20);
130 
131  double curr_alt = gpos.altitude;
132  double curr_lon = gpos.longitude;
133  double curr_lat = gpos.latitude;
134  double home_alt = hp.altitude;
135 
136  mavros_msgs::CommandTOL landing_cmd;
137  landing_cmd.request.altitude = curr_alt - (curr_alt-home_alt) + 0.5;
138  landing_cmd.request.longitude = curr_lon;
139  landing_cmd.request.latitude = curr_lat;
140 
141  while( not(client.call(landing_cmd)) and
142  landing_cmd.response.success){
143  ros::spinOnce();
144  rate.sleep();
145  }
146  ROS_INFO("Vehicle landing...");
147 
148  while(lpos.pose.position.z > 0.1){
149  ros::spinOnce();
150  rate.sleep();
151  }
152  ROS_INFO("Vehicle landed.");
153  return;
154 }
155 
160 void disarm(ros::ServiceClient& client){
161 
162  ros::Rate rate(20);
163 
164  mavros_msgs::CommandBool arm_cmd;
165  arm_cmd.request.value = false;
166  while(!client.call(arm_cmd) && arm_cmd.response.success){
167  }
168  ROS_INFO("Vehicle disarmed");
169  return;
170 }
171 
183 void cmd_vel(ros::Publisher& pub,
184  ros::ServiceClient& client,
185  mavros_msgs::State& state,
186  double dt, double vx, double vy, double vz, double ang_z){
187 
188  ros::Rate rate(20);
189 
190  ros::Time start = ros::Time::now();
191  ros::Time last_request = ros::Time::now();
192 
193  mavros_msgs::SetMode offb_set_mode;
194  offb_set_mode.request.custom_mode = "OFFBOARD";
195 
196  geometry_msgs::TwistStamped target_vel_msg;
197  target_vel_msg.twist.linear.x = vx;
198  target_vel_msg.twist.linear.y = vy;
199  target_vel_msg.twist.linear.z = vz;
200  target_vel_msg.twist.angular.z = ang_z;
201 
202  ROS_INFO("Vehicle moving ...");
203 
204  while (ros::Time::now() - start < ros::Duration(dt)){
205  pub.publish(target_vel_msg);
206 
207  if(state.mode!="OFFBOARD" and
208  (ros::Time::now() - last_request > ros::Duration(0.1))){
209  if((client.call(offb_set_mode))){
210  ROS_INFO("Offboard enabled.");
211  }
212  last_request = ros::Time::now();
213  }
214  ros::spinOnce();
215  rate.sleep();
216  }
217  ROS_INFO("Vehicle arrived destination.");
218 
219 
220  mavros_msgs::SetMode loiter_set_mode;
221  loiter_set_mode.request.custom_mode = "AUTO.LOITER";
222  while( not(client.call(loiter_set_mode))){
223  ros::spinOnce();
224  rate.sleep();
225  }
226  ROS_INFO("Vehicle hovering.");
227  return;
228 }
229 
230 
231 #endif
void disarm(ros::ServiceClient &client)
Disarm vehicle.
void takeoff(ros::ServiceClient &client, mavros_msgs::State &state, geometry_msgs::PoseStamped &lpos, sensor_msgs::NavSatFix &hp, double height)
Take off vehicle.
void land(ros::ServiceClient &client, geometry_msgs::PoseStamped &lpos, sensor_msgs::NavSatFix &gpos, sensor_msgs::NavSatFix &hp)
Land vehicle.
void arm(ros::ServiceClient &client, mavros_msgs::State &state)
Arm vehicle.
void cmd_vel(ros::Publisher &pub, ros::ServiceClient &client, mavros_msgs::State &state, double dt, double vx, double vy, double vz, double ang_z)
Send velocity command to vehicle.