micro-ROS / micro_ros_renesas_demos

Demo code for Renesas e2 studio
Apache License 2.0
4 stars 5 forks source link

micro_ros_udp_freertos example #110

Closed samiamlabs closed 1 year ago

samiamlabs commented 1 year ago

Issue template

Steps to reproduce the issue

My understanding from reading the README.md and doing some guesswork is that I should be able to:

  1. Start micro_ros_udp_freertos on you board using e2studio.
  2. Connect the ethernet port on the board to a network switch on the same network as my laptop.
  3. Start the agent on my laptop using docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 8888 -v6

Expected behavior

See the topic published by the board in the agent's container.

Actual behavior

No topic or node shows up in the agent's container. A red LED sometimes starts flashing after a while on the board.

Additional information

Had quite a lot of trouble with getting e2studio to work properly on Linux. Hard to figure out that you were supposed to have no newer FSP than 3.5 and had to install the Toolchain manually on my system for example. I currently can only enter debug after starting the editor with sudo.

Acuadros95 commented 1 year ago

You need to configure ther agent IP on the board:

Also, check your DHCP configuration and configure it accordingly.

samiamlabs commented 1 year ago

The agent IP fix did it, thanks @Acuadros95!

If you want, I would be willing to help put together a guide for how to get e2studio running and deploy the ethernet UDP example.

This took me almost a whole day of frustration with e2studio and the help of several people on forums when it could have taken less than an hour with a guide. I almost gave up at some points...

It can't just be me who is frustrated with the annoying behavior serial ports have in docker containers (and in general) and want to upgrade to ethernet.

Would be nice with a proper Getting Started link here also: https://micro.ros.org/docs/overview/hardware/

Acuadros95 commented 1 year ago

If you want, I would be willing to help put together a guide for how to get e2studio running and deploy the ethernet UDP example.

Of course! Feel free to open a PR to this repository with instructions on how to setup everything.

When your contributions is merged we will add a Getting Started link to the instructions on the https://micro.ros.org/docs/overview/hardware/ page.

As a suggestion, you can add a link to this documentation, or improve it if you thing its not clear enough: FSP Board pack installation on Renesas e2 studio

I am closing the issue, but we can keep discussing this topic here until a PR is open.

samiamlabs commented 1 year ago

Great!

I feel like it would be nice to have some more functionality demonstrated in the example code. both a publisher and subscriber to the example code rather than just a publisher also.

Maybe something like this:

#include "./utils.h"

#include <time.h>

#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <std_msgs/msg/int32.h>

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){bool l = true; while(1){set_led_status(LED_RED, l = !l); sleep_ms(100);}}}

void microros_app(void);

rcl_publisher_t publisher;
rcl_subscription_t subscriber;
std_msgs__msg__Int32 msg;
std_msgs__msg__Int32 recv_msg;

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{
    (void) last_call_time;
    if (timer != NULL) {
        rcl_publish(&publisher, &msg, NULL);
        msg.data++;
    }
}

void subscription_callback(const void * msgin)
{
    const std_msgs__msg__Int32 * new_msg = (const std_msgs__msg__Int32 *)msgin;
    msg.data = new_msg->data;
}

void microros_app(void)
{
    rcl_allocator_t allocator = rcl_get_default_allocator();

    //create init_options
    rclc_support_t support;
    rclc_support_init(&support, 0, NULL, &allocator);

    // create nodes
    rcl_node_t node;
    RCCHECK(rclc_node_init_default(&node, "my_renesas_node", "", &support));

    // create publisher
    RCCHECK(rclc_publisher_init_default(
        &publisher,
        &node,
        ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
        "int_publisher"));

    // create subscriber
    RCCHECK(rclc_subscription_init_default(
        &subscriber,
        &node,
        ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
        "int_subscriber"));

    // create timer,
    rcl_timer_t timer;
    const unsigned int timer_timeout = 1000;
    RCCHECK(rclc_timer_init_default(
        &timer,
        &support,
        RCL_MS_TO_NS(timer_timeout),
        timer_callback));

    // create executor
    rclc_executor_t executor = rclc_executor_get_zero_initialized_executor();
    RCCHECK(rclc_executor_init(&executor, &support.context, 2, &allocator));
    RCCHECK(rclc_executor_add_timer(&executor, &timer));
    RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &recv_msg, &subscription_callback, ON_NEW_DATA));

    msg.data = 0;

    rclc_executor_spin(&executor);

    RCCHECK(rcl_subscription_fini(&subscriber, &node));
    RCCHECK(rcl_publisher_fini(&publisher, &node));
    RCCHECK(rcl_node_fini(&node));
}

Or maybe a subscription that toggles an LED on the board.

Good to point out that the 2 in rclc_executor_init is the number of callbacks you can register (or whatever the correct way of saying what I mean is). Coming from a normal ROS2 background, that does not feel very intuitive in my opinion.