21 #include <mavros_msgs/CommandLong.h> 22 #include <mavros_msgs/MountControl.h> 23 #include <geometry_msgs/Quaternion.h> 24 #include <geometry_msgs/Vector3Stamped.h> 25 #include <mavros_msgs/MountConfigure.h> 28 namespace extra_plugins {
30 using mavlink::common::MAV_MOUNT_MODE;
31 using mavlink::common::MAV_CMD;
56 std::lock_guard<std::mutex> lock(
mutex);
61 std::lock_guard<std::mutex> lock(
mutex);
66 std::lock_guard<std::mutex> lock(
mutex);
74 std::lock_guard<std::mutex> lock(
mutex);
86 bool error_detected =
false;
89 if (
_mode != mavros_msgs::MountControl::MAV_MOUNT_MODE_MAVLINK_TARGETING) {
91 stat.
summary(diagnostic_msgs::DiagnosticStatus::WARN,
"Can not diagnose in this targeting mode");
98 std::lock_guard<std::mutex> lock(
mutex);
105 error_detected =
true;
108 error_detected =
true;
111 error_detected =
true;
131 stat.
summary(diagnostic_msgs::DiagnosticStatus::STALE,
"No MOUNT_ORIENTATION received in the last 5 s");
133 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"angle error too high");
135 stat.
summary(diagnostic_msgs::DiagnosticStatus::OK,
"Normal");
138 stat.
addf(
"Roll err (deg)",
"%.1f", roll_err_deg);
139 stat.
addf(
"Pitch err (deg)",
"%.1f", pitch_err_deg);
140 stat.
addf(
"Yaw err (deg)",
"%.1f", yaw_err_deg);
169 mount_nh(
"~mount_control"),
178 mount_orientation_pub = mount_nh.advertise<geometry_msgs::Quaternion>(
"orientation", 10);
179 mount_status_pub = mount_nh.advertise<geometry_msgs::Vector3Stamped>(
"status", 10);
184 mount_nh.param<
bool>(
"negate_measured_roll", negate_measured_roll,
false);
185 mount_nh.param<
bool>(
"negate_measured_pitch", negate_measured_pitch,
false);
186 mount_nh.param<
bool>(
"negate_measured_yaw", negate_measured_yaw,
false);
187 if (!mount_nh.getParam(
"negate_measured_roll", negate_measured_roll)) {
188 ROS_WARN(
"Could not retrive negate_measured_roll parameter value, using default (%d)", negate_measured_roll);
190 if (!mount_nh.getParam(
"negate_measured_pitch", negate_measured_pitch)) {
191 ROS_WARN(
"Could not retrive negate_measured_pitch parameter value, using default (%d)", negate_measured_pitch);
193 if (!mount_nh.getParam(
"negate_measured_yaw", negate_measured_yaw)) {
194 ROS_WARN(
"Could not retrive negate_measured_yaw parameter value, using default (%d)", negate_measured_yaw);
200 double err_threshold_deg;
201 mount_nh.param(
"debounce_s", debounce_s, 4.0);
202 mount_nh.param(
"err_threshold_deg", err_threshold_deg, 10.0);
203 if (!mount_nh.getParam(
"debounce_s", debounce_s)) {
204 ROS_WARN(
"Could not retrive debounce_s parameter value, using default (%f)", debounce_s);
206 if (!mount_nh.getParam(
"err_threshold_deg", err_threshold_deg)) {
207 ROS_WARN(
"Could not retrive err_threshold_deg parameter value, using default (%f)", err_threshold_deg);
209 mount_diag.set_debounce_s(debounce_s);
210 mount_diag.set_err_threshold_deg(err_threshold_deg);
247 if (negate_measured_roll) {
250 if (negate_measured_pitch) {
251 mo.pitch = -mo.pitch;
253 if (negate_measured_yaw) {
255 mo.yaw_absolute = -mo.yaw_absolute;
258 geometry_msgs::Quaternion quaternion_msg;
260 mount_orientation_pub.
publish(quaternion_msg);
271 void handle_mount_status(
const mavlink::mavlink_message_t *, mavlink::ardupilotmega::msg::MOUNT_STATUS &ms)
273 geometry_msgs::Vector3Stamped publish_msg;
277 publish_msg.header.frame_id =
std::to_string(ms.target_component);
279 auto vec = Eigen::Vector3d(ms.pointing_b, ms.pointing_a, ms.pointing_c) * M_PI / 18000.0;
282 mount_status_pub.
publish(publish_msg);
286 geometry_msgs::Quaternion quaternion_msg;
288 mount_orientation_pub.
publish(quaternion_msg);
299 mavlink::common::msg::COMMAND_LONG
cmd {};
301 cmd.target_system =
m_uas->get_tgt_system();
302 cmd.target_component =
m_uas->get_tgt_component();
304 cmd.param1 = req->pitch;
305 cmd.param2 = req->roll;
306 cmd.param3 = req->yaw;
307 cmd.param4 = req->altitude;
308 cmd.param5 = req->latitude;
309 cmd.param6 = req->longitude;
310 cmd.param7 = req->mode;
314 mount_diag.
set_setpoint(req->roll*0.01f, req->pitch*0.01f, req->yaw*0.01f, req->mode);
318 mavros_msgs::MountConfigure::Response &res)
320 using mavlink::common::MAV_CMD;
323 auto client = nh.
serviceClient<mavros_msgs::CommandLong>(
"cmd/command");
325 mavros_msgs::CommandLong
cmd{};
327 cmd.request.broadcast =
false;
328 cmd.request.command =
enum_value(MAV_CMD::DO_MOUNT_CONFIGURE);
329 cmd.request.confirmation =
false;
330 cmd.request.param1 = req.mode;
331 cmd.request.param2 = req.stabilize_roll;
332 cmd.request.param3 = req.stabilize_pitch;
333 cmd.request.param4 = req.stabilize_yaw;
334 cmd.request.param5 = req.roll_input;
335 cmd.request.param6 = req.pitch_input;
336 cmd.request.param7 = req.yaw_input;
338 ROS_DEBUG_NAMED(
"mount",
"MountConfigure: Request mode %u ", req.mode);
340 res.success =
cmd.response.success;
346 ROS_ERROR_COND_NAMED(!res.success,
"mount",
"MountConfigure: command plugin service call failed!");
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
#define ROS_ERROR_COND_NAMED(cond, name,...)
Subscriptions get_subscriptions() override
void initialize(UAS &uas_) override
void set_status(float roll_deg, float pitch_deg, float yaw_deg, ros::Time timestamp)
std::shared_ptr< MAVConnInterface const > ConstPtr
MountStatusDiag(const std::string &name)
void set_setpoint(float roll_deg, float pitch_deg, float yaw_deg, uint8_t mode)
void summary(unsigned char lvl, const std::string s)
void quaternionEigenToMsg(const Eigen::Quaterniond &e, geometry_msgs::Quaternion &m)
HandlerInfo make_handler(const mavlink::msgid_t id, void(_C::*fn)(const mavlink::mavlink_message_t *msg, const mavconn::Framing framing))
#define UAS_DIAG(uasobjptr)
void run(diagnostic_updater::DiagnosticStatusWrapper &stat)
std::string to_string(MAV_SENSOR_ORIENTATION orientation)
void addf(const std::string &key, const char *format,...)
void handle_mount_orientation(const mavlink::mavlink_message_t *msg, mavlink::common::msg::MOUNT_ORIENTATION &mo)
Publish the mount orientation.
bool mount_configure_cb(mavros_msgs::MountConfigure::Request &req, mavros_msgs::MountConfigure::Response &res)
ros::Subscriber command_sub
#define ROS_DEBUG_NAMED(name,...)
MountStatusDiag mount_diag
void publish(const boost::shared_ptr< M > &message) const
bool getParam(const std::string &key, std::string &s) const
void vectorEigenToMsg(const Eigen::Vector3d &e, geometry_msgs::Vector3 &m)
#define UAS_FCU(uasobjptr)
ros::Publisher mount_status_pub
PluginBase(const PluginBase &)=delete
float _setpoint_pitch_deg
ros::ServiceServer configure_srv
bool negate_measured_pitch
DiagnosticTask(const std::string name)
void set_err_threshold_deg(float threshold_deg)
Eigen::Quaterniond quaternion_from_rpy(const Eigen::Vector3d &rpy)
std::vector< HandlerInfo > Subscriptions
void set_debounce_s(double debounce_s)
#define ROS_ERROR_NAMED(name,...)
ros::Time _last_orientation_update
void handle_mount_status(const mavlink::mavlink_message_t *, mavlink::ardupilotmega::msg::MOUNT_STATUS &ms)
Publish the mount status.
void initialize(UAS &uas_) override
ros::Publisher mount_orientation_pub
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
bool negate_measured_roll
void command_cb(const mavros_msgs::MountControl::ConstPtr &req)
Send mount control commands to vehicle.
constexpr std::underlying_type< _T >::type enum_value(_T e)
std::recursive_mutex mutex