6.1.3. 被控对象模型

为实现 Eq.3.2 中描述的被控对象模型并与控制器数学模型相连接,分解后的被控对象原理框图如 图 6.31

../_images/sys_plant.png

图 6.3 被控对象原理框图

模型头文件plant.h中的内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#ifndef PLANT_H__
#define PLANT_H__
//==================================================================/
// A test case for fmi simulation tools
// Copyright (c) 2019 马玉海
// All rights reserved.
//
// Version 1.0
//==================================================================/

#include "interface.h"

#define FMI_MODEL_AUTHOR "MA Yuhai"
#define FMI_MODEL_NAME "plant"
#define FMI_MODEL_DISCRIPTION "a plant model"
#define FMI_PORT_POSTFIX ""    /* 指定端口后缀,避免在某些仿真工具中的命名冲突 */

// resource file definition if any
#define FMI_RESOURCE_ITEM 0    /* 外部资源文件数量为零,列表被忽略 */
#if FMI_RESOURCE_ITEM>0 && defined EN_RES_ACCESS
const char *resource_file_list[FMI_RESOURCE_ITEM] = {
    };
#endif

#define FMI_TASK_ITEM 0    /* 定时任务数量为零,触发函数被忽略 */
// task definition if any in the unit of [ms]
void task_30ms_start_0ms(void);

// define interface variables by an fmi object
// one statement per line, no extra semicolons allowed
// do not modify internal variables
typedef struct st_fmi_object_t{
    // internal variables
    FMI_IN double fmi_time_current;
    FMI_IN double fmi_time_step;
#if FMI_RESOURCE_ITEM>0
    FMI_PRM fmi_str_ptr fmi_file_list [FMI_RESOURCE_ITEM]; // do not delete the spaces around []
#endif

    // interface variables
    FMI_IN Stru_Data_Controller_To_Plant st_data_controller_to_plant;
    FMI_OUT Stru_Data_Plant_To_Controller st_data_plant_to_controller;
}st_fmi_object;

#endif // PLANT_H__

模型源文件plant.cpp中的内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "plant.h"

double x;
double v;
double F;

void* fmi_instantiate(void)
{
    st_fmi_object *p =
        (st_fmi_object *)calloc(1, sizeof(st_fmi_object));
    if (!p) {
        fprintf(stderr, "fmi_instantiate failed in model plant!\n");
        exit(EXIT_FAILURE);
    }

    return p;
}

int fmi_initialize(void *fmi_object)
{
    st_fmi_object *p = (st_fmi_object *)fmi_object;

    x = p->st_data_controller_to_plant.x_0;
    v = p->st_data_controller_to_plant.v_0;

    return 0;
}

int fmi_doStep(void *fmi_object)
{
    st_fmi_object *p = (st_fmi_object *)fmi_object;
    const double m = 0.1;

    F = p->st_data_controller_to_plant.F;

    v += F / m * p->fmi_time_step;    /* 当前时间、步长会由仿真工具更新 */
    x += v * p->fmi_time_step;

    p->st_data_plant_to_controller.x = x;
    p->st_data_plant_to_controller.v = v;

    return 0;
}

int fmi_reset(void *fmi_object)
{
    st_fmi_object *p = (st_fmi_object *)fmi_object;
    IO_PORT_FLUSH(Stru_Data_Plant_To_Controller, st_data_plant_to_controller);
    return 0;
}

void fmi_freeInstance(void *fmi_object)
{
    st_fmi_object *p = (st_fmi_object *)fmi_object;

    free(p);
}

Footnotes

1

可参考示例模型plant_1,查看构建后的代码及接口是否添加了期望的后缀。