概述
本帖最后由 史上最强 于 2012-8-12 21:24 编辑
下面我对Stateflow做一个简要介绍。Stateflow是基于有限状态机,对于事件的建模工具。说多了大家也不爱听,我就讲一会儿用的上几个要点,一个时刻必须停留在某个状态中(图中的长方形)。
图1.jpg (22.31 KB, 下载次数: 101)
2012-8-12 21:13 上传
下面我讲一下Simulink框图的意思,左边的阶跃函数相当于超声波传感器,0s到10s为50,也就是传感器离物体比较远。20s到30s的时候为10,也就是传感器离物体比较近。30s到80s的时候为50,也就是距离变远了。然后经过一个Chart模块,输出两个电机的转速,分别给示波器看波形。我想这个流程大家也看懂了。其中Step函数的参数以及波形如图3, 图4, 图5所示。
图3.jpg (28.9 KB, 下载次数: 99)
2012-8-12 21:13 上传
图4.jpg (28.78 KB, 下载次数: 99)
2012-8-12 21:13 上传
图5.jpg (21.15 KB, 下载次数: 100)
2012-8-12 21:13 上传
然后就是今天的重头戏Chart模块了,其中图1的Chart就是Stateflow,点开后如图2所示。首先数据从左上角的箭头进到Straight_line状态中并停留在状态中,进入状态的时候并修改输出变量MotorL与MotorR为50,也就是转速为50。当传感器数值小于20的时候,进行状态转移,移动到Turn_right状态中,并修改输出变量MotorL与MotorR进行转弯。延时59s后(这个我是为了测试方便,实际自己变成可以改成0.5s,或者经过测试),也就是第60s的时候转移到Straight_line状态中。其中输出变量就是MotorL和MotorR。输入变量是Sensor。大家可以从图1中看到。
图2.jpg (62.79 KB, 下载次数: 101)
2012-8-12 21:21 上传
测试80s后输出的数据如图6,图7所示。
图6.jpg (28.01 KB, 下载次数: 99)
2012-8-12 21:13 上传
图7.jpg (22.42 KB, 下载次数: 100)
2012-8-12 21:13 上传
状态机不仅仅可以这样串行工作,也可以进行并行工作。没有人提问相关问题,我也就不再建模解决了。
现在可以验证说明我的模型的正确性后,把输入输出模块去掉,连接NXT硬件模块,如图8所示,然后Crit+B就可以生成代码了
图8.jpg (33.83 KB, 下载次数: 99)
2012-8-12 21:13 上传
结语:Stateflow这种状态机的建模,比C语言要简练许多,我可以生成标准C文件让大家看看生成代码的简练程度。Simulink建模的好处就是建立模型简单,底层驱动不用自己编写,有现成的模块。下面附上状态机的代码,会发现MATLAB生成的代码规范性很强,而且效率很高。(代码看着长的原因有数据初始化,还有就是都是注释)
/*
* File: Chart.c
*
* Code generated for Simulink model 'Chart'.
*
* Model version : 1.3
* Simulink Coder version : 8.2 (R2012a) 29-Dec-2011
* TLC version : 8.2 (Dec 29 2011)
* C/C++ source code generated on : Sun Aug 12 20:57:10 2012
*
* Target selection: ert.tlc
* Embedded hardware selection: 32-bit Generic
* Code generation objective: Execution efficiency
* Validation result: Not run
*/
#include "Chart.h"
#include "Chart_private.h"
/* Named constants for Chart: '/Chart' */
#define Chart_IN_Straight_line ((uint8_T)1U)
#define Chart_IN_Turn_right ((uint8_T)2U)
/* Block signals (auto storage) */
BlockIO_Chart Chart_B;
/* Block states (auto storage) */
D_Work_Chart Chart_DWork;
/* External inputs (root inport signals with auto storage) */
ExternalInputs_Chart Chart_U;
/* External outputs (root outports fed by signals with auto storage) */
ExternalOutputs_Chart Chart_Y;
/* Real-time model */
RT_MODEL_Chart Chart_M_;
RT_MODEL_Chart *const Chart_M = &Chart_M_;
/* Model step function */
void Chart_step(void)
{
/* Chart: '/Chart' incorporates:
* Inport: '/Sensor'
*/
Chart_DWork.presentTicks = Chart_M->Timing.clockTick0;
Chart_DWork.elapsedTicks = Chart_DWork.presentTicks -
Chart_DWork.previousTicks;
Chart_DWork.previousTicks = Chart_DWork.presentTicks;
if ((uint32_T)Chart_DWork.temporalCounter_i1 + Chart_DWork.elapsedTicks <= 63U)
{
Chart_DWork.temporalCounter_i1 = (uint8_T)((uint32_T)
Chart_DWork.temporalCounter_i1 + Chart_DWork.elapsedTicks);
} else {
Chart_DWork.temporalCounter_i1 = 63U;
}
/* Gateway: Chart */
/* During: Chart */
if (Chart_DWork.is_active_c1_Chart == 0) {
/* Entry: Chart */
Chart_DWork.is_active_c1_Chart = 1U;
/* Entry Internal: Chart */
/* Transition: ':10' */
Chart_DWork.is_c1_Chart = Chart_IN_Straight_line;
/* Entry 'Straight_line': ':1' */
Chart_B.MotorL = 50.0;
Chart_B.MotorR = 50.0;
} else if (Chart_DWork.is_c1_Chart == Chart_IN_Straight_line) {
/* During 'Straight_line': ':1' */
if (Chart_U.Sensor < 20.0) {
/* Transition: ':5' */
Chart_DWork.is_c1_Chart = Chart_IN_Turn_right;
Chart_DWork.temporalCounter_i1 = 0U;
/* Entry 'Turn_right': ':2' */
Chart_B.MotorL = 30.0;
Chart_B.MotorR = 0.0;
}
} else {
/* During 'Turn_right': ':2' */
if (Chart_DWork.temporalCounter_i1 >= 37U) {
/* Transition: ':4' */
Chart_DWork.is_c1_Chart = Chart_IN_Straight_line;
/* Entry 'Straight_line': ':1' */
Chart_B.MotorL = 50.0;
Chart_B.MotorR = 50.0;
}
}
/* End of Chart: '/Chart' */
/* Outport: '/MotorL' */
Chart_Y.MotorL = Chart_B.MotorL;
/* Outport: '/MotorR' */
Chart_Y.MotorR = Chart_B.MotorR;
/* Update absolute time for base rate */
/* The "clockTick0" counts the number of times the code of this task has
* been executed. The resolution of this integer timer is 1.6, which is the step size
* of the task. Size of "clockTick0" ensures timer will not overflow during the
* application lifespan selected.
*/
Chart_M->Timing.clockTick0++;
}
/* Model initialize function */
void Chart_initialize(void)
{
/* Registration code */
/* initialize real-time model */
(void) memset((void *)Chart_M, 0,
sizeof(RT_MODEL_Chart));
/* block I/O */
(void) memset(((void *) &Chart_B), 0,
sizeof(BlockIO_Chart));
/* states (dwork) */
(void) memset((void *)&Chart_DWork, 0,
sizeof(D_Work_Chart));
/* external inputs */
Chart_U.Sensor = 0.0;
/* external outputs */
(void) memset((void *)&Chart_Y, 0,
sizeof(ExternalOutputs_Chart));
/* InitializeConditions for Chart: '/Chart' */
Chart_DWork.is_active_c1_Chart = 0U;
Chart_DWork.is_c1_Chart = 0U;
Chart_B.MotorL = 0.0;
Chart_B.MotorR = 0.0;
Chart_DWork.presentTicks = 0U;
Chart_DWork.elapsedTicks = 0U;
Chart_DWork.previousTicks = 0U;
/* Enable for Chart: '/Chart' */
Chart_DWork.presentTicks = Chart_M->Timing.clockTick0;
Chart_DWork.previousTicks = Chart_DWork.presentTicks;
}
/* Model terminate function */
void Chart_terminate(void)
{
/* (no terminate code required) */
}
/*
* File trailer for generated code.
*
* [EOF]
*/复制代码
最后
以上就是超级小海豚为你收集整理的matlab augstate,【原创】MATLAB初体验三(stateflow建模)的全部内容,希望文章能够帮你解决matlab augstate,【原创】MATLAB初体验三(stateflow建模)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复