我目前正在使用现有项目实现 rosserial,但链接器无法找到我为 rosserial 定义的函数: “未定义对
start_ros_com'"*, *undefined reference to
publish_position”的引用
包含其他自写文件如“
MotorControl
”和“GlobalVariables
”工人没有问题,编译时编译器输出“Compiling .pio\build\esp-wrover-kit\src\RosCom.cpp.o
”,表明包含RosCom文件。
我尝试了几个小时的调试、删除 .pio、重新启动 VSCode、重新启动 PC,但行为没有任何改变。 ChatGPT 和 Phind 处于循环中,确定 RosCom.h 位于正确的文件夹中并确保该函数命名正确。
这是我第一次使用FreeRTOS,是我的错误吗?
├── platformio.ini
├── src
└── main.cpp
└── RosCom.cpp
└── RosCom.h
└── MotorControl.cpp
└── MotorControl.h
└── ui
└── ui files for lvgl gui
RosCom.h 像这样导入到 main.cpp 中:
#include "MotorControl.h"
#include "ui/ui.h"
#include "RosCom.h"
并像这样使用:
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 定义如下:
#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
RosCom.cpp 像这样:
#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
您的文件
RosCom.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
这告诉编译器将
start_ros_com()
视为 C 而不是 C++。
然后,您可以在 C++ 而不是 C 中定义
start_ros_com()
- 它是在 RosCom.cpp
中而不是 RosCom.c
中,因此当编译器编译该文件时,它会将其视为 C++ 代码。
C 和 C++ 以不同的方式表示它们的符号名称。没有定义任何
start_ros_com()
C 函数,因此您会收到所看到的错误。
您需要对函数是 C 还是 C++ 保持一致。
修复很简单,如果您不打算将函数编译为 C 代码,请不要将其声明为 C 代码
void start_ros_com();
void receive_position(const std_msgs::Int32MultiArray& cmd_msg);
void publish_position();