Как опубликовать Int16MultiArray из arduino rosserial

#c #arduino #ros

Вопрос:

Я пытаюсь опубликовать Int16MultiArray для пакета ros mecanum_drive: https://github.com/dudasdavid/mecanum_drive

Моя проблема в том, что я не могу опубликовать массив из своего arduino. (Я использую крошечный 4.1)

 #include <std_msgs/Int16MultiArray.h>

ros::NodeHandle nh;
std_msgs::Int16MultiArray wheel_ticks;
ros::Publisher wheel_ticks_pub("wheel_ticks", amp;wheel_ticks);
void setup() {
  nh.getHardware()->setBaud(115200); //was 115200
  nh.initNode();              // init ROS
  nh.advertise(wheel_ticks_pub);
}

void loop() {
  // put your main code here, to run repeatedly:
 //I have tried the code below which uploads to the arduino, but rostopic then says that it dosnt contain any data
 /*
 short value[4] = {0,100,0,0};
 wheel_ticks.data = value;
 */

 //I also tryed the code below which uploads, but then the teensy looses its serial port (arduino port says"[no_device] Serial(Teensy4.1)": 
 /*
 wheel_ticks.data[0] = 10;
 wheel_ticks.data[1] = 5;
 */

 //below gives this error: cannot convert '<brace-enclosed initializer list>' to 'std_msgs::Int16MultiArray::_data_type* {aka short int*}' in assignment
 /*
 wheel_ticks.data = {0,0,0,1};
 */
 wheel_ticks_pub.publish(amp;wheel_ticks);

nh.spinOnce();      
}
 

Все, что я пробовал, либо не загружалось, загружалось, но с перепутанным сериалом, либо с его загрузкой и эхом ростопика, говорящим, что оно пустое.

Спасибо, что посмотрели на это, я надеюсь, вы сможете помочь!

Ответ №1:

Очень специфическим ограничением массивов rosserial is является наличие дополнительного поля, специально предназначенного для длины данных. Это необходимо, так как поле данных реализовано в виде указателя, поэтому у него нет действительно хорошего способа получить длину данных. Тип сообщения на самом деле выглядит так

 class Int16MultiArray{
    Header header;
    int data_length;
    int16_t * data;
};
 

Итак, все, что вам нужно сделать, это задать поле данных перед отправкой сообщения

 #include <std_msgs/Int16MultiArray.h>

ros::NodeHandle nh;
std_msgs::Int16MultiArray wheel_ticks;
ros::Publisher wheel_ticks_pub("wheel_ticks", amp;wheel_ticks);
void setup() {
  nh.getHardware()->setBaud(115200); //was 115200
  nh.initNode();              // init ROS
  nh.advertise(wheel_ticks_pub);
}
void loop() {
 
  short value[4] = {0,100,0,0};
  wheel_ticks.data = value;
  wheel_ticks.data_length = 4;
 
  wheel_ticks_pub.publish(amp;wheel_ticks);

  nh.spinOnce();      
}
 

Комментарии:

1. Большое спасибо, это все исправило! Большое спасибо! Я пытаюсь понять это уже 2 дня!

2. @nbaddorf рад, что это сработало. Не стесняйтесь принять ответ, если вы считаете, что он достаточно ответил на вопрос.