1
$\begingroup$

I’m recently started working with micro-ros and also tested the publisher and subscriber with Arduino Due, but I want to add multi subscriber in my Arduino code (at-least two). but it’s not working try to add one more subscriber.

Note- one single subscriber code is working good.

Arduino Code -

#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/int16.h>
#include <tutorial_interfaces/msg/sphere.h>

rcl_subscription_t subscriber;
std_msgs__msg__Int16 msg;
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;

#define LED_PIN 13

#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)){}}
//
//int pwm1 = 0;
//int pwm2 = 0;

void error_loop() {
while (1) {
digitalWrite(LED_PIN, HIGH);
delay(100);
digitalWrite(LED_PIN, LOW);
}
}

void subscription_callback_1(const void * msgin)
{
const std_msgs__msg__Int16 * msg = (const std_msgs__msg__Int16 *)msgin;
int pwm1 = int(msg->data);
move_left_wheel(pwm1);
}

void subscription_callback_2(const void * msgin)
{
const std_msgs__msg__Int16 * msg = (const std_msgs__msg__Int16 *)msgin;
int pwm2 = int(msg->data);
move_right_wheel(pwm2);
}

void setup() {
// put your setup code here, to run once:

set_microros_transports();

pinMode(7, OUTPUT); //dir1
pinMode(8, OUTPUT); //pwm1
pinMode(9, OUTPUT); //dir2
pinMode(10, OUTPUT); //pwm2

pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);

delay(2000);

allocator = rcl_get_default_allocator();

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

// create node
RCCHECK(rclc_node_init_default(&node, “micro_ros_arduino_node”, “”, &support));

// create subscriber
RCCHECK(rclc_subscription_init_default(
&subscriber,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int16),
“/pwm1”));

RCCHECK(rclc_subscription_init_default(
&subscriber,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int16),
“/pwm2”));

// create executor
RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &msg, &subscription_callback_1, ON_NEW_DATA));
RCCHECK(rclc_executor_init(&executor, &support.context, 2, &allocator));
RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &msg, &subscription_callback_2, ON_NEW_DATA));

}

void move_left_wheel(int pwm) {

if (pwm < 0) {

digitalWrite(7, LOW);
}
else {

digitalWrite(7, HIGH);
}

analogWrite(8, abs(pwm));

}

void move_right_wheel(int pwm) {

if (pwm > 0) {

digitalWrite(9, LOW);
}
else {

digitalWrite(9, HIGH);
}

analogWrite(10, abs(pwm));

}

void loop() {

// delay(100);
RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));

}

I’m not getting idea where, I’m doing wrong. please check my code.

$\endgroup$
6
  • $\begingroup$ Not really familiar with the rclc, but quick glance at the code tells me, that you're initializing two executors into the same variable (erasing the first one in the process). I'd suggest to delete the second call to rclc_executor_init and increment the number of handles to 2 in the first executor_init call. $\endgroup$ Commented Sep 27, 2023 at 7:38
  • $\begingroup$ // create executor RCCHECK(rclc_executor_init(&executor, &support.context, 2, &allocator)); RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &msg, &subscription_callback_1, ON_NEW_DATA)); RCCHECK(rclc_executor_add_subscription(&executor, &subscriber, &msg, &subscription_callback_2, ON_NEW_DATA)); $\endgroup$ Commented Sep 27, 2023 at 7:56
  • $\begingroup$ @StanislavSvědiroh, I try it and it also showing the both the topic name using ros2 topic list command. but none of them of topic are not responding. $\endgroup$ Commented Sep 27, 2023 at 7:59
  • $\begingroup$ On the second look, you also need to have two different subscriber objects. See how you initialize the first one to /pwm1 topic and immediately rewrite it to /pwm2. See this code for reference: github.com/robolaunch/cloudy/blob/… $\endgroup$ Commented Sep 27, 2023 at 8:04
  • $\begingroup$ @StanislavSvědiroh Thank you, Now it's working fine.. $\endgroup$ Commented Sep 27, 2023 at 9:49

1 Answer 1

0
$\begingroup$

Looking at the code, I see two issues that prevent it from working correctly. You're overriding the executor and subscriber variables as you're using them repeatedly in both rclc_executor_init and rclc_executor_add_subscription calls.

What you really need to do is to create a separate variable for each subscriber. Also in your case there is no need to define two separate executors - one with two handles is enough.

// create subscribers
RCCHECK(rclc_subscription_init_default(
&subscriber_1,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int16),
“/pwm1”));

RCCHECK(rclc_subscription_init_default(
&subscriber_2,
&node,
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int16),
“/pwm2”));

// create executor
RCCHECK(rclc_executor_init(&executor, &support.context, 2, &allocator));
RCCHECK(rclc_executor_add_subscription(&executor, &subscriber_1, &msg, &subscription_callback_1, ON_NEW_DATA));
RCCHECK(rclc_executor_add_subscription(&executor, &subscriber_2, &msg, &subscription_callback_2, ON_NEW_DATA));

would be the correct way to go about things here.

You can also look at this code for reference: here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.