首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在C++中使用posix和信号符号的ROS服务和串行通信?

如何在C++中使用posix和信号符号的ROS服务和串行通信?
EN

Stack Overflow用户
提问于 2022-02-20 17:54:32
回答 1查看 322关注 0票数 1

我对C/C++中的并发和并行编程很陌生,所以我需要在我的项目中得到一些帮助。

我希望在C++中使用POSIX和信号量运行多个进程。所以程序的结构应该是下面的结构。首先,我打开串口( Raspberry PI 4的串行通信)。当串行打开时,两个进程正在运行

首先,主线程自动运行并执行以下操作:线程请求ODOM更新(来自微控制器的压力和IMU )并发布它们。同样,每0.3秒检查调制解调器收件箱,如果有新的东西,它就会发布。

另一个仅根据ROS服务的要求检测到调制解调器收件箱中有新消息,请停止(在第一个主进程上)并在串行端口上执行(发布)。然后,第一个过程恢复正常工作。

因此,我首先尝试做一些类似于这些的伪C++代码,但我需要帮助,因为我对并发性和并行性还不熟悉。就是这里

代码语言:javascript
复制
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t mutex;

void* thread(void* arg) { //function which act like thread

   //Main Thread
   // Here code for ASK ODOM UPDATE..
   // Here code for CHECK MODEM INBOX...
   sem_wait(&mutex); //wait state
   
   // ENTER in the second Process
   // Here code for the second process which run on DEMAND..
   // ROS SERVICES
   
   // Here code for CHECK The MODEM INBOX and HALT the First Process
   // Here code for EXECUTE on SERIAL PORT(PUBLISH)
   sleep(0.1); //critical section 
   printf("\nCompleted...\n"); //comming out from Critical section
   sem_post(&mutex);
}

main() {
   sem_init(&mutex, 0, 1);
   pthread_t th1,th2;
   pthread_create(&th1,NULL,thread,NULL);
   sleep(1);
   pthread_create(&th2,NULL,thread,NULL);
   //Join threads with the main thread
   pthread_join(th1,NULL);
   pthread_join(th2,NULL);
   sem_destroy(&mutex);
}

因此,我不确定这是在C++上实现的正确方法。在实现方面有什么帮助,或者对实际的C++代码有帮助吗?谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-22 11:43:54

幸运的是,ROS允许您决定要使用什么样的线程模型(http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning)。

您可以使用ros::AsyncSpinner

主线程启动在后台运行的AsyncSpinner,侦听ROS消息,并在自己的线程中调用ROS回调函数。

然后,您的主线程关心您的串口连接,并转发/发布消息。在伪代码中,它可以如下所示:

代码语言:javascript
复制
#include <ros/ros.h>
#include <mutex>
#include <std_msgs/Float32.h>

std::mutex mutex_;

void callback(std_msgs::Float32ConstPtr msg) {
    // reentrant preprocessing
    {
        std::lock_guard<std::mutex> guard( mutex_ );
        // work with serial port
    }
    // reentrant posprocessing
}

int main(int argc, char* argv[]) {
    ros::init(argc, argv, "name");
    ros::NodeHandle node("~");
    ros::Subscriber sub = node.subscribe("/test", 1, callback);

    ros::AsyncSpinner spinner(1);
    spinner.start();

    while(ros::ok()) {
        // reentrant preprocessing
        {
            std::lock_guard<std::mutex> guard(mutex_);
            // work with serial port
        }
        // reentrant postprocessing
    }
}

您可以看到关键的代码块。在这里,两个线程都是同步的,即一次只有一个线程处于关键路径。

我使用了C++互斥锁,因为它是C++ std的方式,但是您当然可以更改它。

此外,您也可以在主线程中等待串口消息,以减少芯片上的热产生。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71197161

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档