micro-ROS / micro_ros_raspberrypi_pico_sdk

Raspberry Pi Pico (RP2040) and micro-ROS integration
Apache License 2.0
181 stars 54 forks source link

Subsciber in foxy Node not getting microRos Topic #424

Closed fitocuan closed 2 years ago

fitocuan commented 2 years ago

Hi,

I have a raspberry pi pico running a float publisher. By using ros2 echo and can read the topic without issues.

However when I create a node which subscribes to this topic and prints a received message as callback, but the node do not get anything. I try to manually publish (ros2 pub) to this topic and the subscriber node did received it and process the callback.

Subscriber Node:

class MasterNode(Node):

    def __init__(self):
        super().__init__('master_node_demo')

        self.load_cell_sub = self.create_subscription(Float32,'/load_cell_reading',self.listener_loadcell_callback,1)
        self.current_weight = 9999

    def listener_loadcell_callback(self, msg):
        print("rec")
        self.current_weight = msg.data

def main(args=None):
    rclpy.init(args=args)

    master_node = MasterNode()
    rclpy.spin(master_node)

if __name__ == '__main__':
    main()`  

Raspberry pi pico MircoROS Node:

#include <stdio.h>

#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <std_msgs/msg/float32.h>
#include <std_msgs/msg/bool.h>

#include <rmw_microros/rmw_microros.h>

#include "pico/stdlib.h"
#include "pico_uart_transports.h"

#include "hx711.h"

rcl_publisher_t publisher;
std_msgs__msg__Float32 msg;

void timer_callback(rcl_timer_t *timer, int64_t last_call_time)
{
    msg.data = 0;
    rcl_ret_t ret = rcl_publish(&publisher, &msg, NULL);

}

int main()
{

    initHx711();

    rmw_uros_set_custom_transport(
        true,
        NULL,
        pico_serial_transport_open,
        pico_serial_transport_close,
        pico_serial_transport_write,
        pico_serial_transport_read
    );

    rcl_timer_t timer;
    rcl_node_t node;
    rcl_allocator_t allocator;
    rclc_support_t support;
    rclc_executor_t executor;

    allocator = rcl_get_default_allocator();

    // Wait for agent successful ping for 2 minutes.
    const int timeout_ms = 1000; 
    const uint8_t attempts = 120;

    rcl_ret_t ret = rmw_uros_ping_agent(timeout_ms, attempts);

    if (ret != RCL_RET_OK)
    {
        // Unreachable agent, exiting program.
        return ret;
    }

    rclc_support_init(&support, 0, NULL, &allocator);

    rclc_node_init_default(&node, "pico_node", "", &support);

    rclc_publisher_init_best_effort(
        &publisher,
        &node,
        ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Float32),
        "load_cell_reading");

    rclc_timer_init_default(
        &timer,
        &support,
        RCL_MS_TO_NS(100),
        timer_callback);

    rclc_executor_init(&executor, &support.context,2, &allocator);
    rclc_executor_add_timer(&executor, &timer);

    rclc_executor_add_subscription(&executor, &subscription, &led_msg, &led_subscription_callback, ON_NEW_DATA);

    while (true)
    {
        rclc_executor_spin_some(&executor, RCL_MS_TO_NS(10000));
    }
    return 0;
}
pablogs9 commented 2 years ago

The C code does not compile because subscription and led_msg are not defined.

Also, you are creating a best effort publisher and a reliable subscriber. Try to create a reliable publisher with rclc_publisher_init_default.

fitocuan commented 2 years ago

Hi,

Thank you, I have used the rclc_publisher_init_default and it now works.