micro-ROS-Agent
micro-ROS-Agent copied to clipboard
How to use SHM in mico-ROS (Using docker)
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
Cyclone DDS is not compatible with micro-ROS. Please recheck with Fast DDS.
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 ?
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;
}
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).