-
Notifications
You must be signed in to change notification settings - Fork 24
Operation mode manager implementation #656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These files should probably not be a part of this PR, as they are part of a separate PR?
| void declare_parameters() | ||
| { | ||
| this->declare_parameter<std::string>("topics.wrench_input", ""); | ||
| this->declare_parameter<std::string>("topics.killswitch", ""); | ||
| this->declare_parameter<std::string>("topics.operation_mode", ""); | ||
|
|
||
| wrench_input_topic_ = | ||
| this->get_parameter("topics.wrench_input").as_string(); | ||
| killswitch_topic_ = | ||
| this->get_parameter("topics.killswitch").as_string(); | ||
| operation_mode_topic_ = | ||
| this->get_parameter("topics.operation_mode").as_string(); | ||
| } | ||
|
|
||
| void setup_publishers() | ||
| { | ||
| wrench_pub_ = | ||
| this->create_publisher<geometry_msgs::msg::WrenchStamped>( | ||
| wrench_input_topic_, rclcpp::SensorDataQoS()); | ||
|
|
||
| killswitch_pub_ = | ||
| this->create_publisher<std_msgs::msg::Bool>( | ||
| killswitch_topic_, rclcpp::QoS(2).reliable()); | ||
|
|
||
| mode_pub_ = | ||
| this->create_publisher<vortex_msgs::msg::OperationMode>( | ||
| operation_mode_topic_, rclcpp::QoS(2).reliable()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of keeping the topics as member variables I would just get them in the setup_publishers method
void declare_parameters()
{
this->declare_parameter<std::string>("topics.wrench_input");
this->declare_parameter<std::string>("topics.killswitch");
this->declare_parameter<std::string>("topics.operation_mode");
}
void setup_publishers()
{
const auto wrench_input_topic =
this->get_parameter("topics.wrench_input").as_string();
const auto killswitch_topic =
this->get_parameter("topics.killswitch").as_string();
const auto operation_mode_topic =
this->get_parameter("topics.operation_mode").as_string();
wrench_pub_ =
this->create_publisher<geometry_msgs::msg::WrenchStamped>(
wrench_input_topic, rclcpp::SensorDataQoS());
killswitch_pub_ =
this->create_publisher<std_msgs::msg::Bool>(
killswitch_topic, rclcpp::QoS(2).reliable());
mode_pub_ =
this->create_publisher<vortex_msgs::msg::OperationMode>(
operation_mode_topic, rclcpp::QoS(2).reliable());
...Also, there are some QoS definitions in vortex utils ros 👍
jorgenfj
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First round of review.
Consider splitting into header and source file, and move declarations into the header file.
Also use spdlog for logging instead of rclcpp. Spdlog gives more readable timestamps. You can look at the dp_adapt_backs_controller package for how to import and use spdlog.
|
|
||
| void declare_parameters() | ||
| { | ||
| this->declare_parameter<std::string>("topics.wrench_input", ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should avoid using default values for ros parameters
| std::string wrench_input_topic_; | ||
| std::string killswitch_topic_; | ||
| std::string operation_mode_topic_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should not be member varaibles since they are only used once
| killswitch_(true), | ||
| mode_(vortex_msgs::srv::OperationModeSRV::Request::MANUAL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can these values be set from ros parameters and retrieved from the config file in this package?
| // Initial killswitch = true | ||
| std_msgs::msg::Bool msg; | ||
| msg.data = true; | ||
| killswitch_pub_->publish(msg); | ||
|
|
||
| // Initial mode = MANUAL | ||
| vortex_msgs::msg::OperationMode mode_msg; | ||
| mode_msg.mode = vortex_msgs::srv::OperationModeSRV::Request::MANUAL; | ||
| mode_pub_->publish(mode_msg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should read from the member variables
| // Publish killswitch status | ||
| std_msgs::msg::Bool killswitch_msg; | ||
| killswitch_msg.data = killswitch_; | ||
| killswitch_pub_->publish(killswitch_msg); | ||
|
|
||
| // Publish operation mode | ||
| vortex_msgs::msg::OperationMode mode_msg; | ||
| mode_msg.mode = mode_; | ||
| mode_pub_->publish(mode_msg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make these helper functions
auv_setup/launch/orca.launch.py
Outdated
| output="screen", | ||
| output="screen",killswitch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this?
| std::string software_mode_{}; | ||
| uint8_t software_mode_{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make mode more strongly typed I would consider making an enum class for it, and make a convertion which can be used in the callback. Something like
enum class Mode : uint8_t {manual, autonomous, reference};
// Mode type instead of raw uint8
Mode software_mode_{};
// Free function (not part of the node class)
Mode convert_from_ros(const vortex_msgs::msg::OperationMode& mode_msg) {
switch (mode_msg.mode) {
case vortex_msgs::msg::OperationMode::MANUAL:
return Mode::manual;
case vortex_msgs::msg::OperationMode::AUTONOMOUS:
return Mode::autonomous;
case vortex_msgs::msg::OperationMode::REFERENCE:
return Mode::reference;
}
assert(false && "Unknown operation mode");
}
// Callback
void DPAdaptBacksControllerNode::software_mode_callback(
const vortex_msgs::msg::OperationMode::SharedPtr msg) {
software_mode_ = convert_from_ros(*msg);
// Either A) make a to_string helper function or B) use magic_enum to convert enum to string
spdlog::info("Software mode: {}", magic_enum::enum_name(software_mode_));
if (software_mode_ == Mode::autonomous || software_mode_ == Mode::reference) {
pose_d_ = pose_;
}
}Note the part about printing enum name. This feedback goes for other places in the code as well where mode is just stored as a raw integer
| self.operation_mode_client = self.create_client(OperationModeSRV, 'set_operation_mode') | ||
|
|
||
| while not self.operation_mode_client.wait_for_service(timeout_sec=1.0): | ||
| self.get_logger().info('Operation Mode service not available, waiting...') | ||
|
|
||
| self.toggle_killswitch_client = self.create_client(ToggleKillswitch, 'toggle_killswitch') | ||
|
|
||
| while not self.toggle_killswitch_client.wait_for_service(timeout_sec=1.0): | ||
| self.get_logger().info('Toggle Killswitch service not available, waiting...') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make a set_services (to keep the naming consistent). Alternatively find a more fitting prefix than "set" for both that and self.set_publishers_and_subscribers()
| modes = {OperationMode.AUTONOMOUS:"Autonomous", OperationMode.MANUAL:"Manual", OperationMode.REFERENCE:"Reference"} | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to rely on Enum here than dictionary + string
| self._killswitch = 0 | ||
| self._mode = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use bool for killswitch, and would advise use the enum (see comment in utils, and the comment in dp controller) for mode
| wrench_input_topic, rclcpp::SensorDataQoS()); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sensor_data_profile in vortex_utils_ros?
| [this]( | ||
| const std::shared_ptr<vortex_msgs::srv::ToggleKillswitch::Request> request, | ||
| std::shared_ptr<vortex_msgs::srv::ToggleKillswitch::Response> response) | ||
| { | ||
| (void)request; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefer
const std::shared_ptr<vortex_msgs::srv::ToggleKillswitch::Request> /*request*/,
std::shared_ptr<vortex_msgs::srv::ToggleKillswitch::Response> responsewhen not using a parameter, instead of (void).... Alternatively follow F.9
Added service node:
operation_mode_manager.cpp
Changed joystick interface to make use of the manager
Added Operation mode service request type, aswell as message type to use for the operation mode topic
Changed various dp controls to accomodate these changes.
Added operation mode manager to orca.launch.py
Also added operation mode to stonefish_sim in this pull request:
vortexntnu/vortex-stonefish-sim#18