exponenta event banner

Создание сообщений C++ для обмена данными между Simulink и операционной системой или промежуточным программным обеспечением

Чтобы создать код C++, поддерживающий обмен сообщениями между моделями верхнего уровня Simulink и внешними приложениями, используйте блоки отправки и получения библиотеки Simulink Messages & Events Library. Создание кода из топовой модели для облегчения передачи сообщений вне среды Simulink позволяет моделируемому приложению взаимодействовать в распределенной системе, использующей службу протокола внешних сообщений, обычно называемую операционной системой или промежуточным программным обеспечением (например, сообщения DDS, ROS, SOMEIP или POSIX).

Топовые модели Simulink передают сообщения следующим образом:

  • Лучшие модели содержат блоки сообщений для связи вне среды Simulink. Если верхняя модель содержит блок Send, непосредственно соединенный с корневым блоком Outport, блок преобразует свои сигналы в сообщения и передает их за пределы среды Simulink. Если верхняя модель содержит блок приема, непосредственно соединенный с корневым блоком ввода, блок преобразует принятые сообщения в сигналы.

  • Внешний протокол передачи сообщений управляет передачей сообщений в соответствии со своим собственным стандартом (политиками, которые управляют пропускной способностью, порядком доставки и другим качеством обслуживания (QoS)).

Чтобы создать сообщения C++ для обмена данными между топовыми моделями Simulink и операционной системой или промежуточным программным обеспечением, подготовьте модель, создайте код и интегрируйте этот код с выбранной операционной системой или промежуточным программным обеспечением.

Подготовка модели

Чтобы настроить модель так, чтобы она могла передавать сообщения с операционной системой или промежуточным программным обеспечением, настройте модель как модель верхнего уровня, которая имеет по крайней мере один блок сообщений (блок отправки, подключенный к корневому блоку исходящего трафика, или блок получения, подключенный к корневому блоку входящего трафика). Затем модель может подключиться к выбранной операционной системе или промежуточному программному обеспечению через блоки сообщений, как показано на рисунке:

В рамках модели порты сообщений подключаются следующим образом:

Создать код

Чтобы создать код C++ из модели:

  1. В коллекции «Приложения» щелкните Встроенный кодер.

  2. В диалоговом окне «Параметры конфигурации» задайте следующие параметры:

    • На панели «Создание кода» установите для параметра «Язык» значение C++.

    • На панели «Интерфейс» установите для параметра «Упаковка интерфейса кода» значение C++ class.

    • На панели «Шаблоны» выберите Generate an example main program.

  3. Создать код. На вкладке Код C++ нажмите кнопку Создать.

  4. Просмотр созданного кода. На вкладке Код C++ щелкните Просмотреть код.

Интегрировать код

Чтобы интегрировать созданный код C++ из модели с выбранной операционной системой или промежуточным программным обеспечением, используйте рукописный код для реализации классов отправки и получения сообщений и код приложения, использующего эти классы для передачи сообщений. В частности:

  1. При использовании собственного основного класса создайте конкретные подклассы из сгенерированных абстрактных классов, показанных на RecvData_<T>.h и SendData<T>.h. При использовании созданной основной программы-примера в файле предоставляются конкретные подклассы.

  2. Реализация функций класса SendData и RecvData вызов выбранной операционной системы или промежуточного программного обеспечения для отправки и получения сообщений.

  3. Создайте экземпляр реализованных классов сообщений отправки и получения (объекты отправки и получения).

  4. Создайте экземпляр класса модели, используя экземпляры каждого класса сообщений (объекты отправки и получения) в качестве аргументов в конструкторе модели.

  5. Отправка и получение сообщений в соответствии с требованиями приложения. Ожидается, что вы будете управлять временем жизни очередей сообщений. Необходимо, чтобы очереди находились в состоянии готовности к приему сообщений до первого шага модели.

Для интеграции:

  1. Откройте созданную основную программу-пример (или создайте собственную). При использовании созданной основной программы-примера конкретные подклассы RecvData_real_T и SendData_real_T представлены в файле. При создании собственного основного кода создайте конкретные подклассы в коде приложения:

  2. Для получения сообщений вручную запишите реализацию сгенерированного класса приема. Реализация функции класса RecvData вызов выбранной операционной системы или промежуточного программного обеспечения для получения сообщений.

    Показан пример реализации для POSIX:

    class mHMIHandlerRecvData_real_T: public RecvData_real_T {
        public:
        void RecvData(real_T* data, int32_T length, int32_T* status)
        {
            // Use POSIX API mq_receive to receive messages
            unsigned int priority = 1;
            *status = mq_receive(msgQueue, (char *)data, length, &priority);
        }
    };
    

    Создание получаемого объекта.

    static mHMIHandlerRecvData_real_T InMsgRecvData_arg;
    
  3. Для отправки сообщений вручную запишите реализацию созданного класса отправки. Реализация функции класса SendData вызов выбранной операционной системы или промежуточного программного обеспечения для отправки сообщений.

    Показан пример реализации для POSIX:

    class mHMIHandlerSendData_real_T : public SendData_real_T {
        public:
        void SendData(const real_T* data, int32_T length, int32_T* status)
        {
            // Use the POSIX API mq_send to send messages
            unsigned int priority = 1;
            *status = mq_send(msgQueue, (char*)data, length, priority);
        }
    };
    

    Создание объекта отправки.

    static mHMIHandlerSendData_real_T OutMesgSendData_arg;
    

    Создайте экземпляр класса модели, используя объекты отправки и получения в качестве аргументов в конструкторе модели.

    static mHMIHandler mHMI_Obj(InMsgRecvData_arg, OutMsgSendData_arg);
    
  4. Отправка и получение сообщений в соответствии с требованиями приложения и поддержание срока службы очереди сообщений.

    Показан пример реализации для POSIX:

    int_T main(int_T argc, const char *argv[])
    {
        // Unused arguments
        (void)(argc);
        (void)(argv);
    
        //Initialize model
        mHMI_obj.initialize();     
    
        // Open POSIX queue
         mqd_t msgQueue = mq_open("/PosixMQ_Example", O_RDONLY);
         if (msgQueue == -1)
         {
             printf("mq_open failed\n");
             exit(1);
         }     
    
        // Send and Receive messages
         while (rtmGetErrorStatus(mHMI_Obj.getRTM()) == (NULL)) {
             //perform application tasks here.
             rt_OneStep();
         }   
    
        // Close POSIX queue
         mq_close(msgQueue);     
    
        // Terminate model
         mHMI_Obj.terminat():
         return 0;
     }

Более сложный пример интеграции POSIX см. в разделе Использование рукописного кода для интеграции сообщений C++ с POSIX.

Соображения и ограничения

  • Рукописный код - единственный поддерживаемый метод интеграции.

  • Должен быть выбран параметр Generate a example main program. Приложения, для которых требуется статическая магистраль, не поддерживаются.

  • Управление прототипом функции (FPC) не может быть настроено для модели верхнего уровня, имеющей корневые порты сообщений.

Связанные темы