找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 12786|回复: 5

【原创】MATLAB初体验三(stateflow建模)

[复制链接]
发表于 2012-8-12 21:16:20 | 显示全部楼层 |阅读模式
本帖最后由 史上最强 于 2012-8-12 21:24 编辑

上一贴介绍了MATLAB语句的一些好处。http://bbs.cmnxt.com/thread-8647-1-1.html
下面我对Stateflow做一个简要介绍。Stateflow是基于有限状态机,对于事件的建模工具。说多了大家也不爱听,我就讲一会儿用的上几个要点,一个时刻必须停留在某个状态中(图中的长方形)。
  下面是我通过 http://bbs.cmnxt.com/thread-8561-1-1.html 轻枫Psy 提问做的一个Simulink程序,如图1所示。
图1.jpg
  下面我讲一下Simulink框图的意思,左边的阶跃函数相当于超声波传感器,0s到10s为50,也就是传感器离物体比较远。20s到30s的时候为10,也就是传感器离物体比较近。30s到80s的时候为50,也就是距离变远了。然后经过一个Chart模块,输出两个电机的转速,分别给示波器看波形。我想这个流程大家也看懂了。其中Step函数的参数以及波形如图3, 图4, 图5所示。
图3.jpg
图4.jpg
图5.jpg
  然后就是今天的重头戏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
  测试80s后输出的数据如图6,图7所示。
图6.jpg
图7.jpg
  状态机不仅仅可以这样串行工作,也可以进行并行工作。没有人提问相关问题,我也就不再建模解决了。
  现在可以验证说明我的模型的正确性后,把输入输出模块去掉,连接NXT硬件模块,如图8所示,然后Crit+B就可以生成代码了
图8.jpg
  结语:Stateflow这种状态机的建模,比C语言要简练许多,我可以生成标准C文件让大家看看生成代码的简练程度。Simulink建模的好处就是建立模型简单,底层驱动不用自己编写,有现成的模块。下面附上状态机的代码,会发现MATLAB生成的代码规范性很强,而且效率很高。(代码看着长的原因有数据初始化,还有就是都是注释)
  1. /*
  2. * File: Chart.c
  3. *
  4. * Code generated for Simulink model 'Chart'.
  5. *
  6. * Model version                  : 1.3
  7. * Simulink Coder version         : 8.2 (R2012a) 29-Dec-2011
  8. * TLC version                    : 8.2 (Dec 29 2011)
  9. * C/C++ source code generated on : Sun Aug 12 20:57:10 2012
  10. *
  11. * Target selection: ert.tlc
  12. * Embedded hardware selection: 32-bit Generic
  13. * Code generation objective: Execution efficiency
  14. * Validation result: Not run
  15. */

  16. #include "Chart.h"
  17. #include "Chart_private.h"

  18. /* Named constants for Chart: '<Root>/Chart' */
  19. #define Chart_IN_Straight_line         ((uint8_T)1U)
  20. #define Chart_IN_Turn_right            ((uint8_T)2U)

  21. /* Block signals (auto storage) */
  22. BlockIO_Chart Chart_B;

  23. /* Block states (auto storage) */
  24. D_Work_Chart Chart_DWork;

  25. /* External inputs (root inport signals with auto storage) */
  26. ExternalInputs_Chart Chart_U;

  27. /* External outputs (root outports fed by signals with auto storage) */
  28. ExternalOutputs_Chart Chart_Y;

  29. /* Real-time model */
  30. RT_MODEL_Chart Chart_M_;
  31. RT_MODEL_Chart *const Chart_M = &Chart_M_;

  32. /* Model step function */
  33. void Chart_step(void)
  34. {
  35.   /* Chart: '<Root>/Chart' incorporates:
  36.    *  Inport: '<Root>/Sensor'
  37.    */
  38.   Chart_DWork.presentTicks = Chart_M->Timing.clockTick0;
  39.   Chart_DWork.elapsedTicks = Chart_DWork.presentTicks -
  40.     Chart_DWork.previousTicks;
  41.   Chart_DWork.previousTicks = Chart_DWork.presentTicks;
  42.   if ((uint32_T)Chart_DWork.temporalCounter_i1 + Chart_DWork.elapsedTicks <= 63U)
  43.   {
  44.     Chart_DWork.temporalCounter_i1 = (uint8_T)((uint32_T)
  45.       Chart_DWork.temporalCounter_i1 + Chart_DWork.elapsedTicks);
  46.   } else {
  47.     Chart_DWork.temporalCounter_i1 = 63U;
  48.   }

  49.   /* Gateway: Chart */
  50.   /* During: Chart */
  51.   if (Chart_DWork.is_active_c1_Chart == 0) {
  52.     /* Entry: Chart */
  53.     Chart_DWork.is_active_c1_Chart = 1U;

  54.     /* Entry Internal: Chart */
  55.     /* Transition: '<S1>:10' */
  56.     Chart_DWork.is_c1_Chart = Chart_IN_Straight_line;

  57.     /* Entry 'Straight_line': '<S1>:1' */
  58.     Chart_B.MotorL = 50.0;
  59.     Chart_B.MotorR = 50.0;
  60.   } else if (Chart_DWork.is_c1_Chart == Chart_IN_Straight_line) {
  61.     /* During 'Straight_line': '<S1>:1' */
  62.     if (Chart_U.Sensor < 20.0) {
  63.       /* Transition: '<S1>:5' */
  64.       Chart_DWork.is_c1_Chart = Chart_IN_Turn_right;
  65.       Chart_DWork.temporalCounter_i1 = 0U;

  66.       /* Entry 'Turn_right': '<S1>:2' */
  67.       Chart_B.MotorL = 30.0;
  68.       Chart_B.MotorR = 0.0;
  69.     }
  70.   } else {
  71.     /* During 'Turn_right': '<S1>:2' */
  72.     if (Chart_DWork.temporalCounter_i1 >= 37U) {
  73.       /* Transition: '<S1>:4' */
  74.       Chart_DWork.is_c1_Chart = Chart_IN_Straight_line;

  75.       /* Entry 'Straight_line': '<S1>:1' */
  76.       Chart_B.MotorL = 50.0;
  77.       Chart_B.MotorR = 50.0;
  78.     }
  79.   }

  80.   /* End of Chart: '<Root>/Chart' */

  81.   /* Outport: '<Root>/MotorL' */
  82.   Chart_Y.MotorL = Chart_B.MotorL;

  83.   /* Outport: '<Root>/MotorR' */
  84.   Chart_Y.MotorR = Chart_B.MotorR;

  85.   /* Update absolute time for base rate */
  86.   /* The "clockTick0" counts the number of times the code of this task has
  87.    * been executed. The resolution of this integer timer is 1.6, which is the step size
  88.    * of the task. Size of "clockTick0" ensures timer will not overflow during the
  89.    * application lifespan selected.
  90.    */
  91.   Chart_M->Timing.clockTick0++;
  92. }

  93. /* Model initialize function */
  94. void Chart_initialize(void)
  95. {
  96.   /* Registration code */

  97.   /* initialize real-time model */
  98.   (void) memset((void *)Chart_M, 0,
  99.                 sizeof(RT_MODEL_Chart));

  100.   /* block I/O */
  101.   (void) memset(((void *) &Chart_B), 0,
  102.                 sizeof(BlockIO_Chart));

  103.   /* states (dwork) */
  104.   (void) memset((void *)&Chart_DWork, 0,
  105.                 sizeof(D_Work_Chart));

  106.   /* external inputs */
  107.   Chart_U.Sensor = 0.0;

  108.   /* external outputs */
  109.   (void) memset((void *)&Chart_Y, 0,
  110.                 sizeof(ExternalOutputs_Chart));

  111.   /* InitializeConditions for Chart: '<Root>/Chart' */
  112.   Chart_DWork.is_active_c1_Chart = 0U;
  113.   Chart_DWork.is_c1_Chart = 0U;
  114.   Chart_B.MotorL = 0.0;
  115.   Chart_B.MotorR = 0.0;
  116.   Chart_DWork.presentTicks = 0U;
  117.   Chart_DWork.elapsedTicks = 0U;
  118.   Chart_DWork.previousTicks = 0U;

  119.   /* Enable for Chart: '<Root>/Chart' */
  120.   Chart_DWork.presentTicks = Chart_M->Timing.clockTick0;
  121.   Chart_DWork.previousTicks = Chart_DWork.presentTicks;
  122. }

  123. /* Model terminate function */
  124. void Chart_terminate(void)
  125. {
  126.   /* (no terminate code required) */
  127. }

  128. /*
  129. * File trailer for generated code.
  130. *
  131. * [EOF]
  132. */
复制代码
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2014-5-15 21:27:44 | 显示全部楼层
您好,我的matlab可以给NXT下载程序,但是不可以在线调试,就是不可以看到波形,应该如何解决。刚接触,词穷,还请大神指导。谢谢了。
360软件小助手截图20140515212641.png
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2013-12-4 20:11:05 | 显示全部楼层
大神啊,因为这个对matlab感兴趣了
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2013-3-18 22:07:03 | 显示全部楼层
楼主似乎还没有讲到如何自动选择pid参数的问题
继续期待
我最近也再积极研究这个问题
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2012-11-13 14:31:36 | 显示全部楼层
很着迷,有空弄弄个。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2012-8-12 21:41:16 | 显示全部楼层
{:soso_e163:},LEGO设计很好的教程{:soso_e183:}
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

手机版|中文乐高 ( 桂ICP备13001575号-7 )

GMT+8, 2024-11-23 16:14 , Processed in 0.087364 second(s), 25 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表