Program Listing for File control_mode_utils.cpp
↰ Return to documentation for file (/tmp/ws/src/aerostack2/as2_core/src/utils/control_mode_utils.cpp
)
// Copyright 2023 Universidad Politécnica de Madrid
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the Universidad Politécnica de Madrid nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
/*!*******************************************************************************************
* \file control_mode_utils.cpp
* \brief Utility functions for handling control modes over the aerostack2 framework
* \authors Miguel Fernández Cortizas
* Pedro Arias Pérez
* David Pérez Saura
* Rafael Pérez Seguí
********************************************************************************/
#include "as2_core/utils/control_mode_utils.hpp"
#include <rclcpp/logger.hpp>
#include <rclcpp/logging.hpp>
namespace as2
{
namespace control_mode
{
uint8_t convertAS2ControlModeToUint8t(const as2_msgs::msg::ControlMode & mode)
{
// # ------------- mode codification (4 bits) ----------------------
// #
// # unset = 0 = 0b00000000
// # hover = 1 = 0b00010000
// # acro = 2 = 0b00100000
// # attitude = 3 = 0b00110000
// # speed = 4 = 0b01000000
// # speed_in_a_plane = 5 = 0b01010000
// # position = 6 = 0b01100000
// # trajectory = 7 = 0b01110000
// #
// #-------------- yaw codification --------------------------------
// #
// # angle = 0 = 0b00000000
// # speed = 1 = 0b00000100
// # none = 2 = 0b00001000
// #
// # frame codification
// #
// # local_frame_flu = 0 = 0b00000000
// # global_frame_enu = 1 = 0b00000001
// # global_frame_lla = 2 = 0b00000010
// # undefined_frame = 3 = 0b00000011
// #
// #-----------------------------------------------------------------
uint8_t control_mode_uint8t = 0;
switch (mode.control_mode) {
case as2_msgs::msg::ControlMode::ACRO:
control_mode_uint8t = 0b00100000;
break;
case as2_msgs::msg::ControlMode::ATTITUDE:
control_mode_uint8t = 0b00110000;
break;
case as2_msgs::msg::ControlMode::SPEED:
control_mode_uint8t = 0b01000000;
break;
case as2_msgs::msg::ControlMode::SPEED_IN_A_PLANE:
control_mode_uint8t = 0b01010000;
break;
case as2_msgs::msg::ControlMode::POSITION:
control_mode_uint8t = 0b01100000;
break;
case as2_msgs::msg::ControlMode::TRAJECTORY:
control_mode_uint8t = 0b01110000;
break;
case as2_msgs::msg::ControlMode::UNSET:
control_mode_uint8t = 0b00000000;
break;
case as2_msgs::msg::ControlMode::HOVER:
control_mode_uint8t = 0b00010000;
break;
default:
RCLCPP_ERROR(rclcpp::get_logger("as2_mode"), "control_mode not recognized");
break;
}
switch (mode.yaw_mode) {
case as2_msgs::msg::ControlMode::YAW_ANGLE:
control_mode_uint8t |= 0b00000000;
break;
case as2_msgs::msg::ControlMode::YAW_SPEED:
control_mode_uint8t |= 0b00000100;
break;
case as2_msgs::msg::ControlMode::NONE:
control_mode_uint8t |= 0b00001000;
break;
default:
RCLCPP_ERROR(rclcpp::get_logger("as2_mode"), "Yaw mode not recognized");
break;
}
switch (mode.reference_frame) {
case as2_msgs::msg::ControlMode::BODY_FLU_FRAME:
control_mode_uint8t |= 0b00000000;
break;
case as2_msgs::msg::ControlMode::LOCAL_ENU_FRAME:
control_mode_uint8t |= 0b00000001;
break;
case as2_msgs::msg::ControlMode::GLOBAL_LAT_LONG_ASML:
control_mode_uint8t |= 0b00000010;
break;
case as2_msgs::msg::ControlMode::UNDEFINED_FRAME:
control_mode_uint8t |= 0b00000011;
break;
default:
RCLCPP_ERROR(rclcpp::get_logger("as2_mode"), "Reference frame not recognized");
break;
}
return control_mode_uint8t;
}
as2_msgs::msg::ControlMode convertUint8tToAS2ControlMode(uint8_t control_mode_uint8t)
{
as2_msgs::msg::ControlMode mode;
// # ------------- mode codification (4 bits) ----------------------
// #
// # unset = 0 = 0b00000000
// # hover = 1 = 0b00010000
// # acro = 2 = 0b00100000
// # attitude = 3 = 0b00110000
// # speed = 4 = 0b01000000
// # speed_in_a_plane = 5 = 0b01010000
// # position = 6 = 0b01100000
// # trajectory = 7 = 0b01110000
// #
// #-------------- yaw codification --------------------------------
// #
// # angle = 0 = 0b00000000
// # speed = 1 = 0b00000100
// # none = 2 = 0b00001000
// #
// # frame codification
// #
// # local_frame_flu = 0 = 0b00000000
// # global_frame_enu = 1 = 0b00000001
// # global_frame_lla = 2 = 0b00000010
// # undefined_frame = 3 = 0b00000011
// #
// #-----------------------------------------------------------------
if ((control_mode_uint8t & 0b11110000) == 0b00000000) {
mode.control_mode = as2_msgs::msg::ControlMode::UNSET;
} else if ((control_mode_uint8t & 0b11110000) == 0b00010000) {
mode.control_mode = as2_msgs::msg::ControlMode::HOVER;
} else if ((control_mode_uint8t & 0b11110000) == 0b00100000) {
mode.control_mode = as2_msgs::msg::ControlMode::ACRO;
} else if ((control_mode_uint8t & 0b11110000) == 0b00110000) {
mode.control_mode = as2_msgs::msg::ControlMode::ATTITUDE;
} else if ((control_mode_uint8t & 0b11110000) == 0b01000000) {
mode.control_mode = as2_msgs::msg::ControlMode::SPEED;
} else if ((control_mode_uint8t & 0b11110000) == 0b01010000) {
mode.control_mode = as2_msgs::msg::ControlMode::SPEED_IN_A_PLANE;
} else if ((control_mode_uint8t & 0b11110000) == 0b01100000) {
mode.control_mode = as2_msgs::msg::ControlMode::POSITION;
} else if ((control_mode_uint8t & 0b11110000) == 0b01110000) {
mode.control_mode = as2_msgs::msg::ControlMode::TRAJECTORY;
} else {
RCLCPP_ERROR(rclcpp::get_logger("as2_mode"), "Control mode not recognized");
}
if ((control_mode_uint8t & 0b00001100) == 0b00000100) {
mode.yaw_mode = as2_msgs::msg::ControlMode::YAW_SPEED;
} else if ((control_mode_uint8t & 0b00000110) == 0b00000000) {
mode.yaw_mode = as2_msgs::msg::ControlMode::YAW_ANGLE;
} else if ((control_mode_uint8t & 0b00000110) == 0b00001000) {
mode.yaw_mode = as2_msgs::msg::ControlMode::NONE;
} else {
RCLCPP_ERROR(rclcpp::get_logger("as2_mode"), "Yaw mode not recognized");
}
if ((control_mode_uint8t & 0b00000011) == 0b00000001) {
mode.reference_frame = as2_msgs::msg::ControlMode::LOCAL_ENU_FRAME;
} else if ((control_mode_uint8t & 0b00000011) == 0b00000010) {
mode.reference_frame = as2_msgs::msg::ControlMode::GLOBAL_LAT_LONG_ASML;
} else if ((control_mode_uint8t & 0b00000011) == 0b00000000) {
mode.reference_frame = as2_msgs::msg::ControlMode::BODY_FLU_FRAME;
} else if ((control_mode_uint8t & 0b00000011) == 0b00000011) {
mode.reference_frame = as2_msgs::msg::ControlMode::UNDEFINED_FRAME;
} else {
RCLCPP_ERROR(rclcpp::get_logger("as2_mode"), "Reference frame not recognized");
}
return mode;
}
std::string controlModeToString(const as2_msgs::msg::ControlMode & mode)
{
std::stringstream ss;
switch (mode.control_mode) {
case as2_msgs::msg::ControlMode::UNSET: {
ss << "UNSET ";
return ss.str();
} break;
case as2_msgs::msg::ControlMode::HOVER: {
ss << "HOVER ";
} break;
case as2_msgs::msg::ControlMode::ACRO:
ss << "ACRO ";
break;
case as2_msgs::msg::ControlMode::ATTITUDE:
ss << "ATTITUDE ";
break;
case as2_msgs::msg::ControlMode::SPEED:
ss << "SPEED ";
break;
case as2_msgs::msg::ControlMode::SPEED_IN_A_PLANE:
ss << "SPEED_IN_A_PLANE ";
break;
case as2_msgs::msg::ControlMode::POSITION:
ss << "POSITION ";
break;
case as2_msgs::msg::ControlMode::TRAJECTORY:
ss << "TRAJECTORY ";
break;
default:
ss << "Control mode not recognized" << std::endl;
break;
}
// ss << "\t\tYaw mode: ";
switch (mode.yaw_mode) {
case as2_msgs::msg::ControlMode::YAW_SPEED:
ss << "YAW_SPEED ";
break;
case as2_msgs::msg::ControlMode::YAW_ANGLE:
ss << "YAW_ANGLE ";
break;
case as2_msgs::msg::ControlMode::NONE:
ss << "YAW_NONE ";
break;
default:
ss << "Yaw mode not recognized" << std::endl;
break;
}
// ss << "\t\tReference frame: ";
switch (mode.reference_frame) {
case as2_msgs::msg::ControlMode::LOCAL_ENU_FRAME:
ss << "LOCAL_ENU_FRAME ";
break;
case as2_msgs::msg::ControlMode::GLOBAL_LAT_LONG_ASML:
ss << "GLOBAL_LAT_LONG_ASML ";
break;
case as2_msgs::msg::ControlMode::BODY_FLU_FRAME:
ss << "BODY_FLU_FRAME ";
break;
case as2_msgs::msg::ControlMode::UNDEFINED_FRAME:
ss << "UNDEFINED_FRAME ";
break;
default:
ss << "Reference frame not recognized" << std::endl;
break;
}
return ss.str();
}
std::string controlModeToString(const uint8_t control_mode_uint8t)
{
as2_msgs::msg::ControlMode mode = convertUint8tToAS2ControlMode(control_mode_uint8t);
return controlModeToString(mode);
}
void printControlMode(const as2_msgs::msg::ControlMode & mode)
{
RCLCPP_INFO(
rclcpp::get_logger("as2_mode"), "Control mode: %s", controlModeToString(mode).c_str());
}
void printControlMode(uint8_t control_mode_uint8t)
{
printControlMode(convertUint8tToAS2ControlMode(control_mode_uint8t));
}
} // namespace control_mode
} // namespace as2