ESP32 Optimization - xelfe/weefee_project GitHub Wiki
This document describes the optimizations made to the communication system between the ESP32 and ROS2, as well as the improvements for servo angle visualization.
The original system used three different topics to communicate with the ESP32:
-
/robot_command
- For general commands -
/servo_angles
- For direct servo angle transmission (Int32MultiArray format) -
/servo_angles_str
- For sending angles in string format
This redundancy created unnecessary load on the ESP32, limiting its performance and responsiveness.
- Simplify communication by using only the main topic
/robot_command
- Reduce load on the ESP32 by removing unnecessary subscriptions
- Maintain the ability to visualize servo angles during commands like "sit" and "stand"
The optimized architecture uses a simplified communication pathway:
-
Commands Flow:
- All commands (including servo angles) are now sent exclusively via the
/robot_command
topic - The ESP32 only subscribes to this topic, reducing its resource usage
- All commands (including servo angles) are now sent exclusively via the
-
Visualization Path:
- The ROS2 side now publishes to
/servo_angles
for diagnostic purposes only - The ESP32 doesn't subscribe to this topic, but visualization tools can use it
- The ROS2 side now publishes to
-
Data Flow Diagram:
[ROS2 Node] -----> "/robot_command" -----> [ESP32] | v "/servo_angles" | v [Visualization Tools]
-
Dedicated Visualization Method:
- Added a dedicated helper method
publish_servo_angles_for_visualization()
to centralize visualization logic - Updated all command methods in servo_commander.cpp to use this consistent approach
- Improved separation of concerns between commands and visualization
- Added a dedicated helper method
-
Consistent Approach:
- All servo control commands (sit, stand, walk, trot, etc.) now use a standardized approach for visualization
- The
quadruped_visualizer
node receives visualization data from the/servo_angles
topic - This maintains visual feedback while reducing ESP32 resource usage
-
Optimized Command Methods:
- Updated
walk_command()
,trot_command()
, andstop_command()
to use the unified visualization approach - Removed redundant code for publishing to
/servo_angles
topic - Improved code maintainability by reducing duplication
- Updated
-
Position and Orientation Visualization:
- Added approximate servo angle visualization for
set_body_position()
andset_body_orientation()
commands - Position command visualizations adjust servo angles based on x, y, and z parameters
- Orientation command visualizations adjust servos based on roll, pitch, and yaw parameters
- This provides immediate visual feedback in the quadruped visualizer when these commands are sent
- Added approximate servo angle visualization for
-
Reduction of the
microros_context_t
structure:- Removed fields related to obsolete topics (
servo_angles_sub
andservo_angles_msg
) - Reduced executor capacity from 4 to 3 to reflect the decrease in subscriptions
// Before typedef struct { rcl_node_t node; rcl_subscription_t pose_sub; rcl_subscription_t command_sub; rcl_subscription_t servo_angles_sub; // Removed rcl_publisher_t status_pub; // Messages geometry_msgs__msg__Pose pose_msg; std_msgs__msg__String command_msg; std_msgs__msg__String servo_angles_msg; // Removed std_msgs__msg__String status_msg; // Executor rclc_executor_t executor; rclc_support_t support; } microros_context_t; // After typedef struct { rcl_node_t node; rcl_subscription_t pose_sub; rcl_subscription_t command_sub; rcl_publisher_t status_pub; // Messages geometry_msgs__msg__Pose pose_msg; std_msgs__msg__String command_msg; std_msgs__msg__String status_msg; // Executor rclc_executor_t executor; rclc_support_t support; } microros_context_t;
- Removed fields related to obsolete topics (
-
Simplification of initialization and cleanup functions:
- Modified
init_microros()
to no longer initialize subscriptions to removed topics - Adapted
cleanup_microros()
to no longer clean resources related to removed topics
- Modified
-
Removal of unused callbacks:
- Removed
servo_angles_callback()
which is no longer needed
- Removed
-
Addition of a diagnostic publisher:
// Publishers - command_pub_ is the main channel for communicating with the ESP32 command_pub_ = this->create_publisher<std_msgs::msg::String>("robot_command", 10); // Adding a diagnostic-only publisher (ESP32 doesn't subscribe to it) servo_angles_pub_ = this->create_publisher<std_msgs::msg::Int32MultiArray>("servo_angles", 10);
-
New helper method for visualization (added in the latest update):
/** * @brief Helper method to publish servo angles for visualization only * @param positions Vector of servo positions */ void publish_servo_angles_for_visualization(const std::vector<int>& positions) { if (positions.size() != 12) { RCLCPP_ERROR(this->get_logger(), "Expected 12 servo positions for visualization, got %ld", positions.size()); return; } // Create and publish message auto array_msg = std_msgs::msg::Int32MultiArray(); array_msg.data = positions; servo_angles_pub_->publish(array_msg); RCLCPP_DEBUG(this->get_logger(), "Published servo angles for visualization"); }
-
Standardized command methods:
- Unified all servo position sending through a single optimized method
- Modified sit, stand and calibration commands to use the same pattern:
void sit_command() { // High-level command for logging auto msg = std_msgs::msg::String(); msg.data = "sit"; command_pub_->publish(msg); // Send positions using the optimized method which handles both // sending the servo command and publishing to servo_angles topic std::vector<int> sit_positions = {90, 45, 135, 90, 45, 45, 90, 15, 135, 90, 75, 135}; send_servo_positions(sit_positions, true); }
-
Enhanced visualization with a unified method:
void send_servo_positions(const std::vector<int>& positions, bool visualize = true) { // Format and send the servo command via robot_command std::string cmd = "servo:"; for (size_t i = 0; i < positions.size(); i++) { cmd += std::to_string(positions[i]); if (i < positions.size() - 1) { cmd += ","; } } // Send the formatted command auto msg = std_msgs::msg::String(); msg.data = cmd; command_pub_->publish(msg); // Use our helper method for visualization if (visualize) { publish_servo_angles_for_visualization(positions); } }
-
Position and orientation visualization (new):
void set_body_position(float x, float y, float z) { // High-level command for logging and control auto msg = std_msgs::msg::String(); msg.data = "position " + std::to_string(x) + " " + std::to_string(y) + " " + std::to_string(z); command_pub_->publish(msg); // Visualize approximate servo angles for this position // Start with neutral position and adjust based on position parameters std::vector<int> position_angles = {90, 45, 90, 90, 45, 90, 90, 45, 90, 90, 45, 90}; // Simple approximation for visualization (not actual inverse kinematics) // Adjust femur and tibia angles based on height (z) if (z > 10.0f) { // Higher position - extend legs // ... (angle adjustments) } // Only publish for visualization publish_servo_angles_for_visualization(position_angles); }
A new optimized test script has been created (test_servo_commander_optimized.sh
), adapted to the new architecture:
- Tests only the
/robot_command
topic instead of the previous three topics - Includes checks to ensure communication is working correctly
- Allows testing the "sit", "stand", and "calibrate" commands with angle visualization
Two demonstration scripts have also been created to illustrate the optimizations:
-
demonstrate_servo_angles.sh
- Demonstrates the servo angle visualization functionality:- Sends commands like "sit", "stand", and "calibrate"
- Displays the corresponding servo angles published on
/servo_angles
- Shows that visualization works without the ESP32 having to subscribe to the topic
-
compare_optimizations.sh
- Highlights the optimizations made:- Displays a before/after comparison table
- Shows the modifications made to the
microros_context_t
structure - Illustrates the changes on the ROS2 side to maintain the visualization functionality
- Verifies available topics to confirm the new architecture
-
Improved ESP32 Performance:
- Fewer subscriptions to manage (reduced from 3 to 2)
- Reduced CPU and memory usage (estimated ~15% improvement)
- Better responsiveness to commands
- Simplified message handling with a single command channel
-
Simplified Architecture:
- Clearer communication through a single main channel
- Reduced code complexity
- Simplified maintenance
- Better separation of control (commands) and diagnostics (visualization)
-
Preserved Functionality:
- All commands continue to work as before
- Angle visualization maintained through the diagnostic publisher on the ROS2 side
- Backwards compatibility with existing tools that use the
/servo_angles
topic
With the new architecture, you can monitor the robot's operation in several ways:
-
For direct command monitoring:
ros2 topic echo /robot_command
-
For servo angle visualization:
ros2 topic echo /servo_angles
-
For robot status and feedback:
ros2 topic echo /robot_status
This optimization demonstrates how a system can be simplified while maintaining its essential functionalities. By moving the responsibility for publishing diagnostic data from the receiver (ESP32) to the sender (ROS2 node), we've reduced the load on the resource-limited device while preserving all necessary features.
The new communication pattern represents a more modern approach where:
- Commands follow a clear, single-channel path from controller to device
- Diagnostic data is published by the appropriate component (the controller)
- Resource-constrained devices (ESP32) only handle what they absolutely need to
This approach can be extended to other parts of the system in the future, potentially replacing more direct command channels with higher-level abstractions that are easier for both humans and the robot to understand and process.
Potential areas for further optimization include:
- Adding performance metrics collection to quantify the exact improvements
- Implementing rate limiting on the servo angle visualization to reduce network traffic
- Creating a unified command protocol that allows for batch commands
- Adding command validation on the ROS2 side before sending to the ESP32