I am currently implementing rosserial with an existing project but the linker is unable to find functions I defined for rosserial:
"undefined reference to start_ros_com'"*, *undefined reference to
publish_position'
Including other self-written files like "MotorControl
" and "GlobalVariables
" workers without a problem and during compiling the compiler outputs "Compiling .pio\build\esp-wrover-kit\src\RosCom.cpp.o
", indicating that the file RosCom is included.
I tried hours of debugging, deleting .pio, restarting VSCode, restarting the PC and nothing changes the behaviour. ChatGPT and Phind are in a loop of are you sure that RosCom.h is in the correct folder and make sure the function is named correctly.
This is my first time using FreeRTOS, is my error maybe there?
├── platformio.ini
├── src
└── main.cpp
└── RosCom.cpp
└── RosCom.h
└── MotorControl.cpp
└── MotorControl.h
└── ui
└── ui files for lvgl gui
RosCom.h gets imported in main.cpp like this:
#include "MotorControl.h"
#include "ui/ui.h"
#include "RosCom.h"
and used like this:
void ROSSerialTask(void *pvParameters) {
start_ros_com(); // Initialize ROS communication
for (;;) {
// Publish current positions
publish_position();
vTaskDelay(pdMS_TO_TICKS(5));
}
}
void setup() {
Serial.begin(115200);
delay(1000);
xTaskCreatePinnedToCore(ROSSerialTask, "ROSSerialTask", 2048, NULL, 1, NULL, 0);
//other functions that worked before
}
void loop() {
lv_timer_handler(); // GUI Task Handler
delay(1);
vTaskDelete(NULL);
}
RosCom.h is defined as the following:
#ifndef ROSCOM_H
#define ROSCOM_H
#include <std_msgs/Int32MultiArray.h>
#ifdef __cplusplus
extern "C" {
#endif
void start_ros_com();
void receive_position(const std_msgs::Int32MultiArray& cmd_msg);
void publish_position();
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // ROSCOM_H
And RosCom.cpp like this:
#include <ros.h>
#include <std_msgs/Int32MultiArray.h>
#include "MotorControl.h"
#include "ui/ui.h"
#include <lvgl.h>
#include "GlobalVariables.h"
bool ros_communication_working = false;
// Forward declaration of receive_position function
void receive_position(const std_msgs::Int32MultiArray& cmd_msg);
//ros node and publisher
std_msgs::Int32MultiArray actual_position_msg;
ros::Publisher pub_actualpos("actual_position", &actual_position_msg);
ros::Subscriber<std_msgs::Int32MultiArray> sub("wanted_position", receive_position);
ros::NodeHandle nh;
// Initialize ROS communication
void start_ros_com(){
nh.initNode();
nh.subscribe(sub);
nh.advertise(pub_actualpos);
}
int wanted_position[2];
// Receiving wanted positions
void receive_position(const std_msgs::Int32MultiArray& cmd_msg){
if (cmd_msg.data_length == 2) { // Assuming you're expecting a pair of positions
wanted_position[0] = cmd_msg.data[0];
wanted_position[1] = cmd_msg.data[1];
move_motors();
} else {
Serial.println("Invalid data received for wanted positions.");
}
}
// Publish current positions
void publish_position(){
actual_position_msg.data_length = 2; // Assuming you're publishing a pair of positions
actual_position_msg.data[0] = current_position[0];
actual_position_msg.data[1] = current_position[1];
pub_actualpos.publish(&actual_position_msg);
nh.spinOnce();
//ros_communication_working = nh.connected();
if (ros_communication_working) {
lv_obj_add_state(ui_roscomcheckbox, LV_STATE_CHECKED);
Serial.println("ROSCOM Working");
} else {
lv_obj_clear_state(ui_roscomcheckbox, LV_STATE_CHECKED);
Serial.println("ROSCOM NOT Working");
}
}
platformio.ini:
[env:esp-wrover-kit]
platform = espressif32
board = esp-wrover-kit
framework = arduino
monitor_port = /dev/ttyUSB*
monitor_speed = 115200
lib_deps =
teemuatlut/TMCStepper@^0.7.3
gin66/FastAccelStepper@^0.28.3
lovyan03/LovyanGFX@^0.4.14
lvgl/lvgl@^8.3.6
frankjoshua/Rosserial Arduino Library@^0.9.1
khoek/libesp @ ^2.3.0
upload_speed = 921600
build_flags =
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
-DLV_CONF_INCLUDE_SIMPLE
-D LV_COMP_CONF_INCLUDE_SIMPLE
-I src/
-I src/ui
Your file RosCom.h
has this code in it:
#ifdef __cplusplus
extern "C" {
#endif
void start_ros_com();
void receive_position(const std_msgs::Int32MultiArray& cmd_msg);
void publish_position();
#ifdef __cplusplus
} /* extern "C" */
#endif
That tells the compiler to treat start_ros_com()
as C rather than C++.
You then define start_ros_com()
in C++ rather than C - it's in RosCom.cpp
not RosCom.c
, so when the compiler compiles that file it will treat it as C++ code.
C and C++ represent their symbol names differently. No start_ros_com()
C function was ever defined, so you get the error you're seeing.
You need to be consistent about whether a function is C or C++.
The fix is simple, don't declare the function as C code if you're not going to compile it as C code
void start_ros_com();
void receive_position(const std_msgs::Int32MultiArray& cmd_msg);
void publish_position();