ROS2 cmd_vel subscriber & odometry publisher - subscription callback never called
I am writing a motor controller package in C++ that subscribes to /cmd_vel and publishes to /odom. The node runs correctly and rqt_graph shows the subscription and publishers are connected. The problem is the callback function for /cmd_vel subscriber never gets called at all. The run() function is called in the constructor, which results in odom_loop() being called to calculate and build odometry messages. The cmdvel_loop() function just has code used for testing in it. Is the while loop in the run() function causing the callback function to never be called? Does this require a multithreaded executor to handle my run() loop that publishes odometry and another thread to handle the /cmd_vel subscription callback? Or would simply moving the run() function call into the sub callback and removing the while loop fix the issue?
I have the code that works with ROS1, and I used the general idea of that for this version. The code is 500 lines long so I will show the general structure:
namespace mc{
mc::mc : Node("driver")
// set parameters & initialize
variables
run()
}
void mc::cmdvel_callback(const
geometry_msgs::msg::Twist::SharedPtr
twist_msg)
{
// wheel speed (m/s)
float right_speed = twist_msg->linear.x + track_width *
twist_msg->angular.z / 2.0;
float left_speed = twist_msg->linear.x - track_width *
twist_msg->angular.z / 2.0;
// send motor commands to mc
}
void mc::cmdvel_loop()
{
//test code
}
int mc::run(){
// connect to serial port
while (rclcpp::ok())
{
cmdvel_loop();
odom_loop(); // reads encoder count & publishes odometry
}
}
return 0;
{
int main(int argc, char* argv[])
{
rclcpp::init(argc, argv);
rclcpp::executors::SingleThreadedExecutor exec;
rclcpp::NodeOptions options;
auto node = std::make_shared<mc::mc>();
exec.add_node(node);
exec.spin();
rclcpp::shutdown();
return 0;
}