控制算法模型架构设计的最佳实践_董淑成
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
说明:Stateflow子状态不同于Simulink子系统,
Simulink子系统通常都可以独立运算,而 Stateflow子状态的运算要受到父状态的制约;子 状态层次过深的话,最底层的子状态的运行会受制 于太多更高级别的状态,不利于设计和维护;跨域 父状态边界的跳转同样会引发一些非预期的动作
14
过几个独立的Chart实现;相比于并行状态,几个 Chart实现使得信号流向更清晰、明确
15
最佳实践#9“单元模块间信号的代码生成”
除系统级模型的最外层输入、输出信号之外, 输入信号的存储类定义为ImportedExtern 输出信号的存储类定义为ExportedGlobal
说明:每个模块只在代码里定义本模块需要输出
的信号为全局变量,对于输入信号,除最外层输入 之外,一律认为在其他模块中已经有定义;避免在 代码集成时发生重定义错误
16
最佳实践#10“区分Simulink/Stateflow/Embedded MATLAB”
使用Simulink设计信号流和反馈控制算法 使用Stateflow进行组合逻辑、调度器和有限状 态机设计 使用Embedded MATLAB解决矩阵运算
in engineering and science
18
12
最佳实践#6“禁用全局Goto/From以及Data Store Memory模块”
禁止使用全局Goto/From模块
– 使用Goto模块时,将Scope属性设置为local
尽量不用DataStoreMemory模块
– 不得已情况下可以使用DataStoreMemory模块
说明:全局的Goto/From隐藏了信号线的显式连接,
不利于模型的可读性,增加维护难度;对于 DataStoreMemory,类似于C语言开发中的全局变量, 只有在同一个模型内,既要对某个信号执行写操作, 又要从这个信号读数据,方可使用 DataStoreMemory
13
最佳实践#7“限制Stateflow子状态的层数”
Stateflow状态内可以包含子状态,子状态内可 以继续设计子状态 子状态的层数不宜过多,建议不超过3层 尽量不要使用穿越父状态边界的跳转(supertransition)
系统间的耦合度在不断增加
系统输入、输出信号快速增加 系统中的参数在不断增加 嵌入式软件的复杂度大幅增加
来源:NASA Study on Flight Software Complexity Report
3
嵌入式软件开发的效率曲线
随着软件代码行数的增大,开发效率快速下降
来源:Jack Ganssle:The Art of Designing Embedded Systems (Second Edition)
说明:理论上所有算法都可以通过上述三种方式
实现;选择合适的实现方式可以简化设计;三种实 现方式的选择要综合考虑实际情况
17
MathWorks
Change the world by
Accelerating the pace
of discovery, innovation, development, and learning
10
最佳实践#4“总线(Bus)模块的使用”
不要使用Mux和Demux 使用Bus模块减少信号线数量 将一些类似的信号封装为Bus,比如,一些状 态变量
说明:Mux对一组信号进行封装之后,在使用的时
候,必须通过Demux将所有被封装的信号拆解出来; 而使用Bus Creator封装的一组信号,可以在使用 时根据需要通过Bus Selector任意选择其中的一个 或者几个信号
监控单元模型复杂度
– – – – 圈复杂度 子系统深度 输入、输出个数 模块、状态数量
说明:防止模型过于复杂,一旦出现复杂度过大
的情形,要考虑进一步模块化,按照“高内聚、低 耦合”的原则分解为两个或者多个子系统进行设计
8
最佳实践#2“模型引用(Model Reference)的使用”
11
最佳实践#5“禁止使用模块优先级控制执行顺序”
不使用模型优先级控制执行顺序 使用function call或者Stateflow设计的调度器 方式显式的控制模型的执行顺序 对于执行顺序无关的模块,通过默认的方式决 定执行顺序
说明:在模型开发和变更过程中,经常会使用
“拷贝-粘贴”的方式编辑模型,这个过程中会将 模块的优先级信息一起继承下去,而多数情况下, 这种继承是非预期的
最佳实践#8“Stateflow并行状态”
Stateflow Chart最上层不使用并行状态
– 并行状态的执行顺序可以人工设定或者根据几 何位置给出 – 通常并行状态之间通过内部变量或者事件进行 信息传递 – 并行状态间信息传递的可见性不好
说明:Stateflow Chart最上层的并行状态可以通
控制算法模型架构设计的最佳实践
董 淑 成 Shucheng.dong@mathworks.cn MathWorks中国
© 2016 The MathWorks, Inc. 1
为什么要进行模型架构设计
© 2016 The MathWorks, Inc. 2
嵌入式软件的发展趋势
嵌入式软件发展的趋势 嵌入式系统的代码量正在呈指数级增加 嵌入式系统中软件实现的功能迅速增加
9
最佳实践#3“库模块的使用”
对需要多次调用的算法建立库模块(比如滤波 算法、PID算法) 对库模块进行atomic封装,并将代码生成选项 设置为reusable code 对单元级模块,不使用库文件管理
说明:区别使用Model Reference和Library
Block;Model Reference引用的是单元模块或者组 件级模型,而Library Block实现需要多次调用的 函数,比如滤波函数;Library Block在建立时可 以不设置数据类型;代码生成时,如果设置为 reusable code,只要输入、输出的数据类型一致, 那么只生成一个函数
4
复杂模型举例
Leabharlann Baidu
圈复杂度 353
5
架构设计的考虑
降低复杂度,简化设计
– 便于并行开发和重用
降低复杂度的方法
– 模块化开发
– 便于版本控制
– 便于接口管理
模块化开发的原则
– 高内聚、低耦合
6
模型架构设计之最佳实践
© 2016 The MathWorks, Inc. 7
最佳实践#1“复杂度监控”
组件级或系统级模型使用模型引用模块引用下 一级模型文件 单元级模型不再引用其他模型文件 考虑到仿真速度,将模型引用设置为加速模式
说明:单元模型以单独的文件存在,便于版本管
理,便于测试,便于后期维护;被引用的模型在代 码生成时会生成出单独的一组*.c和*.h文件,单元 模型内不再含有模型引用模块,便于代码生成后模 型和代码之间的对应