Skip to content

How to use SHM in mico-ROS (Using docker) #206

Open

Description

@victor-velezmoro

Issue template

  • Hardware description: docker, Ubuntu 22.04
  • RTOS:
  • Installation type:
  • Version or commit hash: humble

Steps to reproduce the issue

Hey, i have created a publisher and subscriber chain with micro-ROS nodes in a docker container , to analyze latencies. It works fine when i use the Agent. Now i want to use SHM. Therefore, i added "-DUCLIENT_PROFILE_SHARED_MEMORY=ON" to my colcon.meta. Do i still have to build the agent and the other steps like:

ros2 run micro_ros_setup build_firmware.sh
source install/local_setup.bash
ros2 run micro_ros_setup create_agent_ws.sh
ros2 run micro_ros_setup build_agent.sh
source install/local_setup.bash
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888 -v6

I am not using a microcontroller, does this still work.? I want to see how big the latency is with and without the Agent. I am using Cyclone DDS, is this maybe the problem?

All nodes are in the same container.

Are there any modifications I forgot to do ?

Expected behavior

Actual behavior

Additional information

Activity

  1. pablogs9 commented on Sep 4, 2023

    @pablogs9
    Member

    Cyclone DDS is not compatible with micro-ROS. Please recheck with Fast DDS.

  2. victor-velezmoro commented on Sep 4, 2023

    @victor-velezmoro
    Author

    Thanks for the answer. I now tried Fast DDS. With the Agent running, the communication works (but using the Agent). If I launch the nodes without the Agent, the nodes abort after a short time.
    This i the error message i get:

    root@docker-desktop:/microros_ws# ros2 run micro_ros_demos_rclc LIDAR
    [ERROR 1693841179.668659857]: [rclc_init] Error in rcl_init: error not set, at ./src/rcl/init.c:218
    
    Failed status on line 66: 1. Aborting.
    

    In line 66 of my code is this:
    RCCHECK(rclc_support_init(&support, argc, argv, &allocator));

    and i use the default allocator:

    rcl_allocator_t allocator = rcl_get_default_allocator();
    rclc_support_t support;
    

    All nodes are sourced and run on rmw_microxrcedds:

    source /opt/ros/humble/setup.bash
    source install/local_setup.bash
    export RMW_IMPLEMENTATION=rmw_microxrcedds
    ros2 run micro_ros_demos_rclc LIDAR
    

    Any idea why is does not work ?

  3. victor-velezmoro commented on Sep 4, 2023

    @victor-velezmoro
    Author

    i did not change the code of my nodes for the use of SHM. Do i have to do that ?
    this is e.g. the code for my publisher node at the beginning of the chain:

    #include <rcl/rcl.h>
    #include <rcl/error_handling.h>
    #include <rclc/rclc.h>
    #include <rclc/executor.h>
    #include <errno.h>
    #include <std_msgs/msg/string.h>
    #include <sys/time.h>
    #include <stdio.h>
    #include <time.h>
    #include <math.h>
    #include <string.h>
    
    #define ARRAY_LEN 200
    
    #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){printf("Failed status on line %d: %d. Aborting.\n",__LINE__,(int)temp_rc); return 1;}}
    #define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){printf("Failed status on line %d: %d. Continuing.\n",__LINE__,(int)temp_rc);}}
    
    rcl_publisher_t publisher;
    rcl_timer_t timer;
    std_msgs__msg__String msg;
    int msg_count = 0;  // Variable to hold the current message count
    
    FILE* pub_file;
    
    void get_timestamp(char* timestamp, size_t size)
    {
        struct timeval tv;
        
        // Get the current time
        gettimeofday(&tv, NULL);
        
        // Convert the time to microseconds
        unsigned long long current_time_microseconds = (unsigned long long)(tv.tv_sec) * 1000000 + tv.tv_usec;
        
        snprintf(timestamp, size, "%llu", current_time_microseconds);
    }
    
    void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
    {
        if (timer != NULL) {
            snprintf(msg.data.data, ARRAY_LEN, "%d", msg_count++); // Fill msg.data with incrementing numbers
            msg.data.size = strlen(msg.data.data);
            msg.data.capacity = ARRAY_LEN;
    
            RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
    
            char timestamp_pub[26];
            get_timestamp(timestamp_pub, sizeof(timestamp_pub));
    
            int res = fprintf(pub_file, "%s - %s\n", msg.data.data, timestamp_pub);
            if (res < 0) {
            perror("Failed to write to micro_pub.csv");
            } else {
            fflush(pub_file);
            }
    
            printf("Publishing (Controller, '%s'): ' %s'\n", timestamp_pub, msg.data.data);
        }
    }
    
    int main(int argc, const char * const * argv)
    {
    	rcl_allocator_t allocator = rcl_get_default_allocator();
    	rclc_support_t support;
    
    	RCCHECK(rclc_support_init(&support, argc, argv, &allocator));
    
    	rcl_node_t node;
    	RCCHECK(rclc_node_init_default(&node, "string_node", "", &support));
    
    	RCCHECK(rclc_publisher_init_best_effort(
    		&publisher,
    		&node,
    		ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, String),
    		"/sensor_data"));
    
    	const unsigned int timer_timeout_ms = 100;
    	RCCHECK(rclc_timer_init_default(
    		&timer,
    		&support,
    		RCL_MS_TO_NS(timer_timeout_ms),
    		timer_callback));
    
    	rclc_executor_t executor = rclc_executor_get_zero_initialized_executor();
    
    	RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
    	RCCHECK(rclc_executor_add_timer(&executor, &timer));
    
    	msg.data.data = (char * ) malloc(ARRAY_LEN * sizeof(char));
    	msg.data.size = 0;
    	msg.data.capacity = ARRAY_LEN;
    
        if (msg.data.data == NULL) {
        fprintf(stderr, "Failed to allocate memory for msg.\n");
        return 1;
        }
    
        pub_file = fopen("/microros_ws/src/_csv_files/lidar_sensor_pub.csv", "w");
        if (pub_file == NULL) {
            perror("Failed to open micro_pub.csv");
            return 1;
        }
        fprintf(pub_file, "Lidar-PUB\n");
    
    	rclc_executor_spin(&executor);
    
    	fclose(pub_file);
    
    	RCCHECK(rcl_publisher_fini(&publisher, &node));
    	RCCHECK(rcl_timer_fini(&timer));
    	RCCHECK(rcl_node_fini(&node));
    
    	return 0;
    }
    
    
  4. pablogs9 commented on Sep 5, 2023

    @pablogs9
    Member

    The micro-ROS client needs an agent to init the session, the SHM mechanism is a way of communicating entities inside an up-and-running XRCE session (that needs an agent to be valid).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions