Skip to content

Micro ros listen topics #476

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
OtaviodaCruz opened this issue Sep 14, 2021 · 7 comments
Closed

Micro ros listen topics #476

OtaviodaCruz opened this issue Sep 14, 2021 · 7 comments

Comments

@OtaviodaCruz
Copy link

Hi, I'm doing a project that consists of assembling a robotic platform (mainly at the software level) that aims to be used as a basis for future research.
My initial proposal for the project is expressed in the image below
Captura de tela de 2021-09-13 22-58-22
Ok. I was doing an initial evaluation of the micro ros library to use in my project, for that I implemented some examples.
I'm currently trying to implement a logic where my arduino listens for a topic (/velocity, red arrows) to then perform the engine moves.
But I couldn't find any reference to implement in my arduino something like ros2 topic echo (...). The questions are: is this possible from micro ros? Is micro rose a viable tool for my project? Do you have a guide for a similar project that I can use as a reference?

Thanks in advance

@Acuadros95
Copy link
Contributor

Hello @OtaviodaCruz,

What you want is a subscriber inside of your arduino code, you can find an example here: link.
For details on the code, check the pub/sub tutorial in our website: link.

@OtaviodaCruz
Copy link
Author

Hi, sorry for the delay.

I haven't been able to test it yet, but when I quickly preview the provided code, I believe in printf("Received:% d \ n", msg-> data);
wherever a call function for sending the PWM signal to the motors might come.

I had gone through this example before, but as it deletes all the prints, I didn't realize it. Sorry.

As soon as i take the test i send feedback.

I'm going to use the context to ask another question. As I am using the micro ROS via serial the messages are exchanged via serial (obviously). I imagine in some package format set by the lib.
In this aspect, if I use a println('Something') will that break the working logic or was the library set up considering the exchange of other serial messages (not related to ROS) in the implementation?

Thanks.

@Acuadros95
Copy link
Contributor

micro ROS takes over the serial port, so it's not a good idea to use it for debug. Maybe you can use other serial port or change the status of the board led.

Also, take care using printf on Arduino, you should use Serial.println(...) directly.

@OtaviodaCruz
Copy link
Author

OtaviodaCruz commented Oct 13, 2021

Hi, sorry for the delay. I'm in a short period of time.

Well, I finally got to test it and it worked, here's a test implementation used, for future reference:

#include <micro_ros_arduino.h>
#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.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)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}

#define LED_PIN 13

rcl_subscription_t subscriberMotorControl;
std_msgs__msg__Int32 msgSubscriber;
rcl_node_t nodeMotorControl;
rclc_executor_t executor1;

rcl_allocator_t allocator;
rclc_support_t support;


rcl_publisher_t publisherEncoder;
std_msgs__msg__Int32 msg_Encoder;
rcl_timer_t timer_Encoder;
rcl_node_t nodeEncoder;
rclc_executor_t executor2 ;

rcl_node_t nodeUltrassonic;
rcl_publisher_t publisherUltrassonic;
std_msgs__msg__Int32 msg_Ultrassonic;
rcl_timer_t timer_Ultrassonic;
rclc_executor_t executor3 ;

void timer_Ultrassonic_Callback(rcl_timer_t * timer, int64_t last_call_time)
{
  (void) last_call_time;
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisherUltrassonic, &msg_Ultrassonic, NULL));
    msg_Ultrassonic.data++;
  }
}

void timer_Encoder_Callback(rcl_timer_t * timer, int64_t last_call_time)
{
  (void) last_call_time;
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisherEncoder, &msg_Encoder, NULL));
    msg_Encoder.data++;
  }
}

void subscriber_MotorControl_callback(const void * msgin)
{
 
  const std_msgs__msg__Int32 * msg = (const std_msgs__msg__Int32 *)msgin;
   
}

void setup() {
  
// --------------------------------------- All--------------------
  
  set_microros_transports();
  pinMode(13, OUTPUT);
  delay(2000);
  allocator = rcl_get_default_allocator();

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

//------------------------------------------------Encoder---------------------
  
  // init node
  RCCHECK(rclc_node_init_default(&nodeEncoder, "nodeEncoder", "", &support));

  // init publisher
  RCCHECK(rclc_publisher_init_default(
    &publisherEncoder,
    &nodeEncoder,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "nodeEncoder"));

  // init timer
  RCCHECK(rclc_timer_init_default(
    &timer_Encoder,
    &support,
    RCL_MS_TO_NS(1000),
    timer_Encoder_Callback));

  // create and init executor
  executor2 = rclc_executor_get_zero_initialized_executor();
  RCCHECK(rclc_executor_init(&executor2, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_timer(&executor2, &timer_Encoder));

//------------------------------------------------Ultrassonic---------------------
  // init node
  RCCHECK(rclc_node_init_default(&nodeUltrassonic, "nodeUltrassonic", "", &support));

  // init publisher
  RCCHECK(rclc_publisher_init_default(
    &publisherUltrassonic,
    &nodeUltrassonic,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "nodeUltrassonic"));
  
  // init timer
  RCCHECK(rclc_timer_init_default(
    &timer_Ultrassonic,
    &support,
    RCL_MS_TO_NS(1000),
    timer_Ultrassonic_Callback));
    
  // init executor
  executor3 = rclc_executor_get_zero_initialized_executor();
  RCCHECK(rclc_executor_init(&executor3, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_timer(&executor3, &timer_Ultrassonic));
    
//-----------------------------------------SUBSCRIBE---------------------

  // init node
  RCCHECK(rclc_node_init_default(&nodeMotorControl, "nodeMotorControl", "", &support));

  // init subscriber
  RCCHECK(rclc_subscription_init_default(
    &subscriberMotorControl,
    &nodeMotorControl,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "subscriberMotorControl"));

  // init executor
  RCCHECK(rclc_executor_init(&executor1, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_subscription(&executor1, &subscriberMotorControl, &msgSubscriber, &subscriber_MotorControl_callback, ON_NEW_DATA));

}

void loop() {

  RCCHECK(rclc_executor_spin_some(&executor1, RCL_MS_TO_NS(100)));
  RCCHECK(rclc_executor_spin_some(&executor2, RCL_MS_TO_NS(100)));
  RCCHECK(rclc_executor_spin_some(&executor3, RCL_MS_TO_NS(100)));

}

I would like to complete by asking one more thing, would my arduino be able to discover nodes or topics created by the PC, that is, is it possible for the agent to discover nodes (or topics) created by the client?
Thanks for the support.

@Acuadros95
Copy link
Contributor

Just to clarify your question, the client would be the Arduino board, and the agent is the PC.

We have a graph implementation on our rmw layer that tries to cover this functionality. Its still a experimental approach, but you can try it out enabling RMW_UXRCE_GRAPH (detail) on the respective colcon.meta file and rebuilding the library.

But maybe there are alternatives, what do you want to do exactly?

@OtaviodaCruz
Copy link
Author

Exactly, I'm sorry, I spelled it wrong earlier. The customer would be the Arduino board and the PC agent.

In this case, the reason is out of curiosity (haha), I believe that in my project I won't need it, but it's good to know about the existence or not of this functionality.

Thanks for all the help, you guys have good support.

@Acuadros95
Copy link
Contributor

Glad to help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants