18 #include <condition_variable> 21 #include <mavros_msgs/CommandLong.h> 22 #include <mavros_msgs/CommandInt.h> 23 #include <mavros_msgs/CommandBool.h> 24 #include <mavros_msgs/CommandHome.h> 25 #include <mavros_msgs/CommandTOL.h> 26 #include <mavros_msgs/CommandTriggerControl.h> 27 #include <mavros_msgs/CommandTriggerInterval.h> 30 namespace std_plugins {
38 std::condition_variable
ack;
44 expected_command(command),
59 use_comp_id_system_control(false),
60 ACK_TIMEOUT_DT(ACK_TIMEOUT_MS / 1000.0)
65 PluginBase::initialize(uas_);
67 cmd_nh.param(
"use_comp_id_system_control", use_comp_id_system_control,
false);
104 static constexpr
int ACK_TIMEOUT_MS = 5000;
116 for (
auto &tr : ack_waiting_list) {
117 if (tr.expected_command == ack.command) {
118 tr.result = ack.result;
125 ack.command, ack.result);
132 if (tr.
ack.wait_for(lock, std::chrono::nanoseconds(ACK_TIMEOUT_DT.
toNSec())) == std::cv_status::timeout) {
146 uint16_t command, uint8_t confirmation,
147 float param1,
float param2,
148 float param3,
float param4,
149 float param5,
float param6,
151 unsigned char &success, uint8_t &
result)
153 using mavlink::common::MAV_RESULT;
157 L_CommandTransaction::iterator ack_it;
160 for (
const auto &tr : ack_waiting_list) {
161 if (tr.expected_command == command) {
171 bool is_ack_required = (confirmation != 0 || m_uas->is_ardupilotmega() || m_uas->is_px4()) && !broadcast;
173 ack_it = ack_waiting_list.emplace(ack_waiting_list.end(), command);
175 command_long(broadcast,
176 command, confirmation,
182 if (is_ack_required) {
184 bool is_not_timeout = wait_ack_for(*ack_it);
187 success = is_not_timeout && ack_it->result ==
enum_value(MAV_RESULT::ACCEPTED);
188 result = ack_it->result;
190 ack_waiting_list.erase(ack_it);
204 uint8_t frame, uint16_t command,
205 uint8_t current, uint8_t autocontinue,
206 float param1,
float param2,
207 float param3,
float param4,
208 int32_t x, int32_t y,
210 unsigned char &success)
215 command_int(broadcast,
216 frame, command, current, autocontinue,
227 template<
typename MsgT>
230 using mavlink::common::MAV_COMPONENT;
232 const uint8_t tgt_sys_id = (broadcast) ? 0 : m_uas->get_tgt_system();
233 const uint8_t tgt_comp_id = (broadcast) ? 0 :
234 (use_comp_id_system_control) ?
235 enum_value(MAV_COMPONENT::COMP_ID_SYSTEM_CONTROL) : m_uas->get_tgt_component();
237 cmd.target_system = tgt_sys_id;
238 cmd.target_component = tgt_comp_id;
242 uint16_t command, uint8_t confirmation,
243 float param1,
float param2,
244 float param3,
float param4,
245 float param5,
float param6,
248 const uint8_t confirmation_fixed = (broadcast) ? 0 : confirmation;
250 mavlink::common::msg::COMMAND_LONG
cmd {};
251 set_target(
cmd, broadcast);
253 cmd.command = command;
254 cmd.confirmation = confirmation_fixed;
263 UAS_FCU(m_uas)->send_message_ignore_drop(
cmd);
267 uint8_t frame, uint16_t command,
268 uint8_t current, uint8_t autocontinue,
269 float param1,
float param2,
270 float param3,
float param4,
271 int32_t x, int32_t y,
274 mavlink::common::msg::COMMAND_INT
cmd {};
275 set_target(
cmd, broadcast);
278 cmd.command = command;
279 cmd.current = current;
280 cmd.autocontinue = autocontinue;
289 UAS_FCU(m_uas)->send_message_ignore_drop(
cmd);
295 mavros_msgs::CommandLong::Response &res)
297 return send_command_long_and_wait(req.broadcast,
298 req.command, req.confirmation,
299 req.param1, req.param2,
300 req.param3, req.param4,
301 req.param5, req.param6,
303 res.success, res.result);
307 mavros_msgs::CommandInt::Response &res)
309 return send_command_int(req.broadcast,
310 req.frame, req.command,
311 req.current, req.autocontinue,
312 req.param1, req.param2,
313 req.param3, req.param4,
319 mavros_msgs::CommandBool::Response &res)
321 using mavlink::common::MAV_CMD;
322 return send_command_long_and_wait(
false,
324 (req.value) ? 1.0 : 0.0,
326 res.success, res.result);
330 mavros_msgs::CommandHome::Response &res)
332 using mavlink::common::MAV_CMD;
333 return send_command_long_and_wait(
false,
335 (req.current_gps) ? 1.0 : 0.0,
336 0, 0, 0, req.latitude, req.longitude, req.altitude,
337 res.success, res.result);
341 mavros_msgs::CommandTOL::Response &res)
343 using mavlink::common::MAV_CMD;
344 return send_command_long_and_wait(
false,
349 req.latitude, req.longitude, req.altitude,
350 res.success, res.result);
353 bool land_cb(mavros_msgs::CommandTOL::Request &req,
354 mavros_msgs::CommandTOL::Response &res)
356 using mavlink::common::MAV_CMD;
357 return send_command_long_and_wait(
false,
361 req.latitude, req.longitude, req.altitude,
362 res.success, res.result);
366 mavros_msgs::CommandTriggerControl::Response &res)
368 using mavlink::common::MAV_CMD;
369 return send_command_long_and_wait(
false,
371 (req.trigger_enable)? 1.0 : 0.0,
372 (req.sequence_reset)? 1.0 : 0.0,
373 (req.trigger_pause)? 1.0: 0.0,
375 res.success, res.result);
379 mavros_msgs::CommandTriggerInterval::Response &res)
381 using mavlink::common::MAV_CMD;
384 return send_command_long_and_wait(
false,
385 enum_value(MAV_CMD::DO_SET_CAM_TRIGG_INTERVAL), 1,
387 req.integration_time,
389 res.success, res.result);
MAVROS Plugin base class.
#define ROS_WARN_THROTTLE_NAMED(period, name,...)
#define ROS_WARN_NAMED(name,...)
void set_target(MsgT &cmd, bool broadcast)
ros::ServiceServer trigger_interval_srv
ros::ServiceServer arming_srv
std::lock_guard< std::mutex > lock_guard
void command_long(bool broadcast, uint16_t command, uint8_t confirmation, float param1, float param2, float param3, float param4, float param5, float param6, float param7)
bool trigger_control_cb(mavros_msgs::CommandTriggerControl::Request &req, mavros_msgs::CommandTriggerControl::Response &res)
void initialize(UAS &uas_)
Plugin initializer.
std::list< CommandTransaction > L_CommandTransaction
const ros::Duration ACK_TIMEOUT_DT
bool command_long_cb(mavros_msgs::CommandLong::Request &req, mavros_msgs::CommandLong::Response &res)
ros::ServiceServer command_long_srv
void handle_command_ack(const mavlink::mavlink_message_t *msg, mavlink::common::msg::COMMAND_ACK &ack)
ros::ServiceServer trigger_control_srv
uint16_t expected_command
bool arming_cb(mavros_msgs::CommandBool::Request &req, mavros_msgs::CommandBool::Response &res)
#define UAS_FCU(uasobjptr)
helper accessor to FCU link interface
bool send_command_long_and_wait(bool broadcast, uint16_t command, uint8_t confirmation, float param1, float param2, float param3, float param4, float param5, float param6, float param7, unsigned char &success, uint8_t &result)
CommandTransaction(uint16_t command)
bool trigger_interval_cb(mavros_msgs::CommandTriggerInterval::Request &req, mavros_msgs::CommandTriggerInterval::Response &res)
bool set_home_cb(mavros_msgs::CommandHome::Request &req, mavros_msgs::CommandHome::Response &res)
bool takeoff_cb(mavros_msgs::CommandTOL::Request &req, mavros_msgs::CommandTOL::Response &res)
std::vector< HandlerInfo > Subscriptions
Subscriptions vector.
std::condition_variable ack
bool use_comp_id_system_control
Subscriptions get_subscriptions()
Return vector of MAVLink message subscriptions (handlers)
L_CommandTransaction ack_waiting_list
bool send_command_int(bool broadcast, uint8_t frame, uint16_t command, uint8_t current, uint8_t autocontinue, float param1, float param2, float param3, float param4, int32_t x, int32_t y, float z, unsigned char &success)
bool command_int_cb(mavros_msgs::CommandInt::Request &req, mavros_msgs::CommandInt::Response &res)
ros::ServiceServer command_int_srv
std::unique_lock< std::mutex > unique_lock
bool land_cb(mavros_msgs::CommandTOL::Request &req, mavros_msgs::CommandTOL::Response &res)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
ros::ServiceServer takeoff_srv
bool wait_ack_for(CommandTransaction &tr)
ros::ServiceServer land_srv
void command_int(bool broadcast, uint8_t frame, uint16_t command, uint8_t current, uint8_t autocontinue, float param1, float param2, float param3, float param4, int32_t x, int32_t y, float z)
ros::ServiceServer set_home_srv
constexpr std::underlying_type< _T >::type enum_value(_T e)
std::recursive_mutex mutex