现在的位置: 首页 > 专题 > 机器人 > Robotics Studio > 设计中心 > 文档 > 专题 > 机器人 > 正文

Robotics Studio学习教程:第二十二天——让相扑机器人动起来!

2014年05月09日 Robotics Studio, 文档, 机器人 ⁄ 转载:原文链接 ⁄ 共 4143字 ⁄ 字号 暂无评论 ⁄ 阅读 1,242 次
Robotics Studio学习教程

Robotics Studio学习教程

继之前分享的一篇《Robotics Studio学习教程:第二十一天——相扑机器人可以看到什么?》, 我们将继续分享下一篇《Robotics Studio学习教程:第二十二天——让相扑机器人动起来!》,让我继续开始我们学习Visual Programming Language,以及使用Robotics Studio学习开发机器人应用的道路吧。

 

[Robotics Studio] Sumo[IV] - 冲啊~相扑机器人 -- Day22

 

是的, 一旦我们知道辨识影像的结果, 相信对于如何改良 Tracking 就有底了吧!

昨天就是在:

result = ProcessImage(cameraFrame.Size.Width, cameraFrame.Size.Height, cameraFrame.Frame);

这一行之后把画面画出来的, 所以你知道 ProcessImage 函式就是用来辨识敌人的位置,  你可以在 ProcessImage 函式当中找到:

  1.   // only process bottom half of the image
  2.   for (int y = height / 2; y < height; y++)

这表示原本只处理画面下半部的影像, 因为上半部是比较远的影像, 但其实你可以改为处理全部的影像:
像下面这样

  1.   for (int y = 0; y < height; y++)

就可以处理全部的影像啰.

接着就可以看 HandleProcessedImage 函式, 我在原本的程序当中加入批注:

  1.  /// <summary>
  2.  /// 根據辨認的影像結果來反應動作
  3.  /// </summary>
  4.  /// <param name="result"></param>
  5.  /// <returns>回傳是否有根據影像處理做出反應動作</returns>
  6.   private bool HandleProcessedImage(ImageProcessResult result)
  7.   {
  8.      bool processImage = false;
  9.      if (result != null)
  10.      {
  11.          _state.ImageResult = result;

  12.          if (_state.SumoMode < SumoMode.Pending)
  13.              return false;

  14.          if ((_state.SumoMode >= SumoMode.Tracking) &&
  15.              (result.TimeStamp > _state.LastImage))
  16.          {
  17.              processImage = true;
  18.              _state.LastImage = result.TimeStamp;
  19.          }

  20.          // 假如處理影像的目標超過 50 個點, 表示應該像是敵人了..
  21.          if (result.Area > 50)
  22.          {
  23.              if (processImage)
  24.                  _state.SumoMode = SumoMode.Tracking;

  25.              if (result.XMean < 0x48)
  26.              {
  27.                 // 敵人在左邊, 向左邊衝
  28.                  LogVerbose(LogGroups.Console, "Enemy to the left: " + result.XMean);
  29.                  if (processImage)
  30.                      InternalDrivingMilliseconds(250, 400, 400.0);
  31.                  _robotPort.RoombaSetLeds(irobot.RoombaLedBits.Off, 0, 255);
  32.              }
  33.              else if (result.XMean > 0x68)
  34.              {
  35.                  // 敵人在右邊, 向右邊衝
  36.                  LogVerbose(LogGroups.Console, "Enemy to the right: " + result.XMean);
  37.                  if (processImage)
  38.                      InternalDrivingMilliseconds(400, 250, 400.0);
  39.                  _robotPort.RoombaSetLeds(irobot.RoombaLedBits.CreateAdvance, 0, 0);
  40.              }
  41.              else
  42.              {
  43.                  // 敵人在正前方, 往前面衝
  44.                  LogVerbose(LogGroups.Console, "Enemy Dead Ahead!: " + result.XMean);
  45.                  if (processImage)
  46.                      InternalDrivingMilliseconds(300, 300, 500.0);
  47.                  _robotPort.RoombaSetLeds(irobot.RoombaLedBits.CreatePlay, 0, 0);
  48.              }
  49.          }
  50.          else
  51.          {
  52.              // 沒發現敵人, 切回鬼混模式
  53.              if ((processImage) && _state.SumoMode == SumoMode.Tracking)
  54.              {
  55.                  _state.SumoMode = SumoMode.Wander;
  56.                  _state.NextModeCheck = DateTime.Now;
  57.                  LogVerbose(LogGroups.Console, "Enemy Not Visible");
  58.              }            _robotPort.RoombaSetLeds(irobot.RoombaLedBits.CreatePlay | irobot.RoombaLedBits.CreateAdvance, 0, 255);
  59.          }

  60.      }
  61.      return processImage;
  62.  }

 

如果你喜欢造成高一点的伤害力, 就是把那个 InternalDrivingMilliseconds 的前两个参数加大, 你会发现你的机器人比较冲动, 暴力许多,  当然也就比较有可能冲过界线...

关于 Tracking mode 还有一部分的 code 是存在 TimerHandler 当中, 有需要的话也要修改:

  1.  ...
  2.  else if (_state.SumoMode == SumoMode.Tracking)
  3.  {
  4.      // 繼續追上敵人
  5.      LogVerbose(LogGroups.Console, "Continue Tracking");

  6.      if ((_state.LeftSpeed + _state.RightSpeed) == 400)
  7.         InternalDrivingMilliseconds(100, 100, 250.0);
  8.      if ((_state.Direction & Direction.Left) == Direction.Left)
  9.          InternalDrivingMilliseconds(100, 300, 250.0);
  10.      else if ((_state.Direction & Direction.Right) == Direction.Right) // 原本是 Direction.Left, 應該是 bug, 改為 Direction.Right
  11.          InternalDrivingMilliseconds(300, 100, 250.0);
  12.      else
  13.          InternalDrivingMilliseconds(250, 250, 250.0);

  14.  }
  15.  ...

 

其他像是想改 Contact mode 就要看 RobotUpdateBumpersHandler 函式, 还有 TimerHandler 的一小部分函式,

想改 AvoidBoundary mode 就看 RobotUpdateFloorSensorsHandler, TimerHandler,RobotUpdateFoolrSensorsHandler 当中也有关于切换到 Blind mode 的程序代码.

如果你想加模式, 当然也是可以, 不过我到目前为止也没写出甚么必胜的密技...

不过这个相扑机器人程序还算是可以玩上一阵子的范例, 也提供足够学习的技巧,  相信只要具备基本的 CCR, DSS 认知, 这个范例并不难以理解, 也应该可以加以修改.

可惜的是写程序能做的变化就是只能跑来跑去, 如果实体机器人也可以改变, 相信就可以做出更多的变化,  也可以加上新的传感器来做不一样的事情啰 (比如说, 前后左右都加上 Camera , 我看敌人往哪儿跑...哈哈).

 

让我们继续一下章教程:

《Robotics Studio学习教程:第二十三天——控制虚拟的KUKA LBR3机器人手臂》

fgx

分享到:

Wopus问答

×