主要内容

使用手写代码将C ++消息与POSIX集成

此示例显示如何将生成的C ++代码与POSIX集成以促进消息通信。示例应用是一种多传感器定位系统,其设计用于估计车辆的位置。多传感器定位系统由两个组件组成:传感器(多模型)和估计模型。概述的工作流程显示如何准备每个组件,生成代码,并将生成的代码集成到系统组件之间传递消息。此示例假定您熟悉使用Simulink环境中的消息。万博1manbetx有关更多信息,请参阅生成C++消息,在Simulink与操作系统或中间件之间进行通信万博1manbetx

传感器型号

多传感器定位系统中的第一组件是传感器。定位系统使用加速度计和GPS传感器来估计车辆位置。每个传感器模型由功能块,发送块和输出端口组成。每个传感器模型通过使用POSIX消息将消息发送到估计模型。

准备模型

打开传感器型号RTWDEMO_ACCEL_SEND.RTWDEMO_GPS_SEND.

对于每个模型,执行以下步骤:

  1. 在应用程序库中,单击嵌入式编码器

  2. 在toolstrip上,设置停止时间100.秒。停止时间在估计车辆位置时定义数据收集的持续时间。

  3. 在模型中,单击以打开功能块。在块参数中,设置文件名到模型的MAT文件。设定采样时间0.01

生成代码

1.对于每个传感器型号,在“配置参数”对话框中设置以下参数:

  • 在这一点代码生成窗格,套C++. 在“高级参数”下,设置构建配置指定并添加-lrt.C ++链接器

  • 在这一点界面窗格,集合代码接口包装C ++类多实例代码错误诊断没有一个. 在“高级参数”下,选择MAT文件日志记录

2.生成代码。上C++代码选项卡,单击建造

集成代码

要将生成的C++代码从每个传感器模型与POSIX集成,手工编写发送类和生成的主程序(或创建自己的程序)。此示例提供了一个自定义的主程序,其中包含一个实现的send类。要集成每个传感器型号的代码,请将生成的主文件替换为自定义的主文件。

查看每个传感器的自定义主文件:

1.每个传感器的自定义主文件以相同的方式实现。例如,打开自定义主文件rtwdemo\u accel\u send\u ert\u main\u customized.cpp

2.查看已实现的发送类:

  • send类函数,发送数据,调用POSIXAPI(mq_发送)发送消息。

  • 为了提供对消息队列的访问,添加了POSIX消息队列作为类变量,并实现了一个set方法来设置队列。

class accelsendmodelclasssenddata_real_t:public senddata_real_t {mqd_t msgqueue;
public://使用POSIX发送消息void SendData(const real_T*data,int32_T长度,int32_T*状态){unsigned int priority=1*状态=mq_发送(msgQueue,(char*)数据、长度、优先级);}
//设置类POSIX队列void setMQ(MQD_T MQ)的方法{msgqueue = mq;}};

发送类实现后,创建发送类(发送对象)的实例。然后将发送对象连接到传感器模型,使传感器能够向估计模型发送消息。

//创建发送对象静态accelSendModelClassSendData\u real\T Out1SendData\u arg;
//将发送对象发送到传感器模型,以发送消息静态AccelsendModelClass RTOBJ(OUT1SENDDATA_ARG);

3.查看添加的POSIX队列行为函数。主函数使用这些函数打开和关闭posix队列。

MQD_T OpenMQ(const char * name,int标志,int maxmsg,int msgsize){struct mq_attrtrtr;attr.mq_flags = 0;attr.mq_maxmsg = maxmsg;attr.mq_msgsize = msgsize;
mqd_t msgqueue = mq_open(姓名,标志,0664,&attr);
如果(msgQueue<0){printf(“mq_open failed\n”);退出(1);}
返回msgqueue;}
void closemq(mqd_t msgqueue){mq_close(msgqueue);}

4.回顾主要功能。实现的主要函数使用先前定义的类和队列函数来发送消息并管理POSIX消息队列。主要功能执行以下操作:

  • 打开posix消息队列。

  • 发送消息。

  • 关闭POSIX队列。

int_t main(int_t argc,const char * argv []){//未使用的参数(void)(argc);(空虚)(argv);
//初始化rtobj.initialize()模型;
//打开posix消息队列mqd_t msgqueue = OpenMQ(“/ posixmq_accel”,O_creat | O_Wronly,2,16);Out1senddata_arg.setmq(msgquey);
//在(rtmGetErrorStatus(rtObj.getRTM())==(NULL)){rt_OneStep();}时发送消息
// matfile日志记录rt_stopdatalogging(matfile,Rtobj.getrtm() - > Rtwloginfo);
//在此处禁用rt_OneStep()
//关闭POSIX消息队列closeMQ(msgQueue);
返回0;}

估计模型

第二部分是估算模型。估计模型从传感器模型接收具有输入数据的消息,并计算车辆的估计位置。

准备模型

打开模型rtwdemo位置估算

  1. 在应用程序库中,单击嵌入式编码器

  2. 在toolstrip上,设置停止时间100.秒。

  3. 在模型中,单击以打开每个输入端口。在块参数中,设置数据类型双重的端口尺寸3.,及采样时间0.01

  4. 单击打开每个消息接收块。清除使用内部队列参数使能模型使用POSIX消息队列。

  5. 单击以打开功能块。该块实现估计算法。

生成代码

1.在“配置参数”对话框中,设置以下参数:

  • 在这一点代码生成窗格,套C++. 在“高级参数”下,设置构建配置指定并添加-lrt.C ++链接器

  • 在这一点界面窗格,套代码接口包装C ++类和集合多实例代码错误诊断没有一个. 在“高级参数”下,选择MAT文件日志记录

2.生成代码。上C++代码选项卡,单击建造

集成代码

为了将生成的C++代码与POSIX的估计模型集成,手写实现接收类和生成的主程序(或者创建自己的程序)。估计模型接收来自传感器模型的消息,并计算车辆的估计位置。此示例提供了一个定制的主程序,其中包含一个实现的receive类。要集成估算模型中的代码,请将生成的主文件替换为自定义的主文件。

查看自定义主文件:

1.打开自定义主文件RTWDEMO_POS_ESTIMATE_ERT_MAIN_CUSTOMIZED.cpp.

2.审查已实施的接收类:

  • 接收类函数,recvdata.,调用POSIXAPI(mq_接收)接收消息。

  • 为了提供对消息队列的访问,添加了POSIX消息队列作为类变量,并实现了一个set方法来设置队列。

类位置估计模型ClassRecvdata_real_T:public RecvData_real_T{mqd_T msgQueue;
公共://使用POSIX API MQ_RECEIVE接收消息void recvdata(real_t * data,int32_t长度,int32_t * status){//添加接收数据逻辑这里无符号int priority = 1;* status = mq_receive(msgqueue,(char *)数据,长度和优先级);}
//设置类POSIX队列void setMQ(MQD_T MQ)的方法{msgqueue = mq;}};

在接收类实现之后,为每个传感器模型创建接收类(接收对象)的实例。然后将接收对象附加到估计模型,以使模型能够接收来自每个传感器的消息。

//在recvdata_arg中创建接收对象静态位置估计模型类recvdata_real_T;静态位置估计模型类Recvdata_real_T InRecvdata_arg;
//将接收对象附加到估计模型以接收消息静态位置估计模型类rtObj(InRecVData_arg,InRecVData_arg);

3.查看添加的POSIX队列行为函数。主函数使用这些函数打开,关闭,并取消posix队列。

MQD_T OpenMQ(const char * name,int标志,int maxmsg,int msgsize){struct mq_attrtrtr;attr.mq_flags = 0;attr.mq_maxmsg = maxmsg;attr.mq_msgsize = msgsize;
mqd_t msgqueue = mq_open(姓名,标志,0664,&attr);
如果(msgQueue<0){printf(“mq_open failed\n”);退出(1);}
返回msgqueue;}
void closemq(mqd_t msgqueue){mq_close(msgqueue);}
void unlinkmq(const char * name){if(mq_unlink(name)<0){printf(“mq_unlink失败\ n”);出口(1);}}

4.回顾主要功能。实现的主要函数使用先前定义的类和队列函数来接收消息并管理POSIX队列。主要功能执行以下操作:

  • 打开posix消息队列。

  • 收到消息。

  • 关闭POSIX队列。

int_t main(int_t argc,const char * argv []){//未使用的参数(void)(argc);(空虚)(argv);
//初始化rtobj.initialize()模型;
//打开POSIX消息队列mqd_t msgQueueAccel=openMQ(“/PosixMQ_accel”,O|CREAT | O|RDONLY,2,16);mqd_t msgQueueGPS=openMQ(“/PosixMQ_gpspos”,O|CREAT | O|RDONLY,2,16);
In1RecvData_arg.SetMQ(msgQueueAccel);In2RecvData_arg.SetMQ(msgQueueGPS);
//在(rtmGetErrorStatus(rtObj.getRTM())==(NULL)){rt_OneStep();}时接收消息
// matfile日志记录rt_stopdatalogging(matfile,Rtobj.getrtm() - > Rtwloginfo);
//在此处禁用rt_OneStep()
//关闭POSIX消息队列closeMQ(msgQueueAccel);closeMQ(msgQueueGPS);
unlinkmq(“/ posixmq_accel”);unlinkmq(“/ posixmq_gpspos”);
返回0;}

执行多传感器定位系统

要执行多传感器定位系统,请重建并运行所有模型的可执行文件。要查看结果,请运行提供的生成脚本rtwdemo\u定位\u系统\u脚本. 此图显示了一个结果示例。