马上注册 登录
中文乐高 返回首页

kuuxi的个人空间 https://bbs.cmnxt.com/?34109 [收藏] [复制] [分享] [RSS]

日志

多任务(并行程序) — 何时需要多任务程序

已有 1129 次阅读2014-1-21 11:25

翻译一片来自 http://www.robotc.net/forums/viewtopic.php?f=1&t=3342 的文章

 

多任务(并行程序) 何时需要多任务程序

 

多任务是指同时执行不同的任务。让我门来看一下例子,判断是否需要多任务执行。


机器人向前行驶,知道声纳探测到距离障碍物小于30cm,机器人向右转弯、停止。
这个程序的流程如下:

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

代码

开始程序,

马达转动,向前行驶,
(译)直到声纳探测距离小于30厘米,

向右转弯,右马达副职,左马达正值,

停止行驶,

结束程序。

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif


可以看到,这个例子的程序按顺序执行,无需多同时执行多任务。

机器人巡线行走,直到距离篮筐小于20厘米时,讲求放入篮筐。
这个程序的流程如下:

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

代码:

开始程序
声纳检测距离篮筐是否小于20厘米,
光感值为暗值:
   
马达转向一个方向,

光感值为亮值:
   
马达转向另一个方向,
声纳探测到距离篮筐小于20厘米
停止马达,
控制手臂的马达启动,讲求放入篮筐,
结束程序。

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif



这个例子中,声纳探测距离和光感读取光值同时进行,我们是否需要同时执行多任务?答案是否定的,因为可以把同时发生的任务整合成一个单一的任务。代码如下:

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

Code:

task main()
{
   // do the things in this loop while the sonar sensor is > 30 cm
   while(SensorValue(sonar) > 30)
   {
      // follow line:
      if(SensorValue(lineFollower) < threshold)
      {
         // turn sligtly one direction
         motor[rightMotor] = 50;
         motor[leftMotor] = 0;
      }
      else
      {
         // turn slightly in the other direction
         motor[rightMotor] = 0;
         motor[leftMotor] = 50;
      }
   }
   
   // stop motors and dump ball into basket:
   motor[rightMotor] = 0;
   motor[leftMotor] = 0;
   motor[armMotor] = 25
   wait1Msec(1000);
   motor[armMotor] = 0;
}
 

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif



当同时发生的任务可以整合成一个单一的任务时,我们永远都不选择同时执行多任务!

什么时候同时执行多任务呢?想象一下有个机器人在房间吸尘,遇到人时要选择避让,当避让失败时,按下紧急按钮,迅速停止机器人的运行。这个流程应该什么样呢?很难设计出一步一步线性的执行步骤,因为当其他任务在执行时,需要判断紧急按钮是否被按下,从而保证一旦按下,就可以结束程序。这时候就需要设计同时执行多任务的程序。


行走流程图:

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

代码:

开始程序,
打开吸尘器,
四周行走,
如果声纳发现了人:
   
停止马达,
   
关闭吸尘器,
人离开后:
   
打开吸尘器,
   
四周行走,
循环上述流程   

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif



停止流程图:

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

代码:

开始循环:
如果紧急按钮被按下:
结束程序.
如果紧急按钮没有被按下:
继续循环,

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif



真实的程序代码如下:

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

Code:

task e_stop()
{
   while(true)
   {
      if(SensorValue(e_stopBtn) == 1)
      {
         StopAllTasks(); // this ends the program
      }
      wait1Msec(10);  // this prevents the current task from hogging the CPU
   }
}


task main()
{
   StartTask(e_stop);
   while(true)
   {
      if(SensorValue(sonar) <= 10)
      {
         motor[rightMotor] = 0;
         motor[leftMotor] = 0;
         motor[vacuumMotor] = 0;
      }
      else
      {
         // code for driving around room here
      }
      wait1Msec(10);  // this prevents the current task from hogging the CPU
   }
}

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif

http://www.robotc.net/forums/images/spacer.gif



尽管避让人的行为和捡起物品的行为同时发生,但他们可以整合到一个单一的任务中。而制动紧急按钮是一个单独的任务,和主要任务并行。另外要注意到‘wait1Msec’命令,如果没有这个命令,其中的一个任务有可能会独占CPU,阻止另一个任务的执行。


要记住main task()执行的是主要任务,主要任务停止时,其他任务也必须停止。在吸尘这个例子中,主要任务永远不会停止,除非制动了紧急按钮。

这是一个很好的关于多任务的例子,当然还有很多关于的多任务的重要和危险的概念在这里没有介绍。希望有人更深入的去研究这方面的知识.


记住:
99%
的程序不要执行多任务!
并且
99.9%
多任务程序错误是因为错误的使用了多任务程序!!


_________________
Bence Feher

Undergraduate Intern - NREC, Robotics Academy
ROBOTC - Testing/Documentation/Developer

Computer Science, Japanese, East Asian Studies
University of Pittsburgh, Konan University
甲南大学

路过

雷人

握手

鲜花

鸡蛋

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 马上注册

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

GMT+8, 2024-5-14 01:58 , Processed in 0.054834 second(s), 17 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

返回顶部