Bhuman开始篇——自带的前锋角色文件及其他角色编写

Striker

        进入上篇文章提到的Options下的Roles。发现其中自带一个Striker.h文件

下面我们模拟一下比赛的过程

首先返回Options目录

进入GameControl。比赛开始进入ready状态执行ReadyState.h

/** behavior for the ready state */
option(ReadyState)
{
  /* position has been reached -> stand and wait */
  initial_state(stand)
  {
    action
    {
      theHeadControlMode = HeadControl::lookForward;
      Stand();
    }
  }
}

此时机器人头朝前且站立,play状态时执行PlayingState.h

option(PlayingState)
{
  initial_state(demo)
  {
    action
    {
      Demo();
    }
  }
}

我们找到option(Demo),发现它直接跳转到Striker.h(分析见代码注释)

/** A test striker option without common decision */
option(Striker)
{
  initial_state(start)    //初始化状态start
  {
    transition
    {
      if(state_time > 1000)        //当此状态停留时间超过1000ms,跳到turnToBall状态
        goto turnToBall;
    }
    action
    {
      theHeadControlMode = HeadControl::lookForward;   //状态跳转之前头朝前站立
      Stand();
    }
  }

  state(turnToBall)
  {
    transition     //调用相关representations接口进行判断然后跳转状态
    {
      if(theLibCodeRelease.timeSinceBallWasSeen > theBehaviorParameters.ballNotSeenTimeOut)
        goto searchForBall;
      if(std::abs(theBallModel.estimate.position.angle()) < 5_deg)
        goto walkToBall;
    }
    action        //在此状态执行走到目的地点
    {
      theHeadControlMode = HeadControl::lookForward;
      WalkToTarget(Pose2f(50.f, 50.f, 50.f), Pose2f(theBallModel.estimate.position.angle(), 0.f, 0.f));
    }
  }

  state(walkToBall)
  {
    transition
    {
      if(theLibCodeRelease.timeSinceBallWasSeen > theBehaviorParameters.ballNotSeenTimeOut)
        goto searchForBall;
      if(theBallModel.estimate.position.norm() < 500.f)
        goto alignToGoal;
    }
    action
    {
      theHeadControlMode = HeadControl::lookForward;
      WalkToTarget(Pose2f(50.f, 50.f, 50.f), theBallModel.estimate.position);    //走到球所在的位置
    }
  }

  state(alignToGoal)
  {
    transition
    {
      if(theLibCodeRelease.timeSinceBallWasSeen > theBehaviorParameters.ballNotSeenTimeOut)
        goto searchForBall;
      if(std::abs(theLibCodeRelease.angleToGoal) < 10_deg && std::abs(theBallModel.estimate.position.y()) < 100.f)
        goto alignBehindBall;
    }
    action   //走到球的后面对准球门
    {
      theHeadControlMode = HeadControl::lookForward;
      WalkToTarget(Pose2f(100.f, 100.f, 100.f), Pose2f(theLibCodeRelease.angleToGoal, theBallModel.estimate.position.x() - 400.f, theBallModel.estimate.position.y()));
    }
  }

  state(alignBehindBall)
  {
    transition
    {
      if(theLibCodeRelease.timeSinceBallWasSeen > theBehaviorParameters.ballNotSeenTimeOut)
        goto searchForBall;
      if(theLibCodeRelease.between(theBallModel.estimate.position.y(), 20.f, 50.f)
      && theLibCodeRelease.between(theBallModel.estimate.position.x(), 140.f, 170.f)
      && std::abs(theLibCodeRelease.angleToGoal) < 2_deg)
        goto kick;
    }
    action//对球
    {
      theHeadControlMode = HeadControl::lookForward; 
      WalkToTarget(Pose2f(80.f, 80.f, 80.f), Pose2f(theLibCodeRelease.angleToGoal, theBallModel.estimate.position.x() - 150.f, theBallModel.estimate.position.y() - 30.f));
    }
  }

  state(kick)
  {
    transition
    {
      if(state_time > 3000 || (state_time > 10 && action_done))
        goto start;
    }
    action //射门
    {
      theHeadControlMode = HeadControl::lookForward;
      InWalkKick(WalkKickVariant(WalkKicks::forward, Legs::left), Pose2f(theLibCodeRelease.angleToGoal, theBallModel.estimate.position.x() - 160.f, theBallModel.estimate.position.y() - 55.f));
    }
  }

  state(searchForBall)
  {
    transition
    {
      if(theLibCodeRelease.timeSinceBallWasSeen < 300)
        goto turnToBall;
    }
    action
    {
      theHeadControlMode = HeadControl::lookForward;
      WalkAtRelativeSpeed(Pose2f(1.f, 0.f, 0.f));   //原地旋转找球
    }
  }
}

representations下的调用:the + str(Name).对象名,例如

theLibCodeRelease.timeSinceBallWasSeen   
调用的是LibCodeRelease下的timeSinceBallWasSeen对象

CABSL结构

            若有不详之处,参考pdf第六章的第一节cabsl

            该结构是以图的结构表示,Option()第一个参数为图的名字,一般与文件名相同; 第二或以后的参数为变量,一般可省略

  1. common_transition: 最高优先级转换,不管在其中图的哪个节点状态,满足条件一定跳出到指定位置,可跳出图
  2. initial_state(stateName): 进入图的初始状态的状态名,与state区别不大
  3. state(stateName): 状态,只能通过goto语句跳转(以下符号部分为state中的结构)
  • transition:图节点的连接部分,通过条件是否满足跳转到其他状态,通常是if  条件  goto 状态
  • action:进入此状态的行为,执行部分,通常是Options下的图或行为接口调用(需在Options新建文件下声明)

例如上面的原地找球的action: WalkAtRelativeSpeed(Pose2f(1.f, 0.f, 0.f))

    执行的是WalkAtRelativeSpeed.h文件。其中Pose2f(1.f, 0.f, 0.f)为第一个参数,该文件的结构为

option(WalkAtRelativeSpeed, (const Pose2f&) speed) //传入参数为一个Pose2f对象
{
  /** Set the motion request. */
  initial_state(setRequest)
  {
    transition
    {
      if(theMotionInfo.motion == MotionRequest::walk)
        goto requestIsExecuted;
    }
    action
    {
      theMotionRequest.motion = MotionRequest::walk;
      theMotionRequest.walkRequest.mode = WalkRequest::relativeSpeedMode;
      theMotionRequest.walkRequest.speed = speed;
      theMotionRequest.walkRequest.walkKickRequest = WalkRequest::WalkKickRequest();
    }
  }

  /** The motion process has started executing the request. */
  target_state(requestIsExecuted)
  {
    transition
    {
      if(theMotionInfo.motion != MotionRequest::walk)
        goto setRequest;
    }
    action
    {
      theMotionRequest.motion = MotionRequest::walk;
      theMotionRequest.walkRequest.mode = WalkRequest::relativeSpeedMode;
      theMotionRequest.walkRequest.speed = speed;
      theMotionRequest.walkRequest.walkKickRequest = WalkRequest::WalkKickRequest();
    }
  }
}

优先级高的图的切换可强行关闭优先级低的图里面的state进程

添加角色文件

        在Roles目录可以添加其他的角色文件,只需在上面的options.h文件中添加include即可,上篇文章中提到。

重新编译已改好的项目

        进入bhuman下的Make/Linux, 若没有语法错误,右击打开终端执行 make SimRobotmake Nao 即可重新编译

                make SimRobot是编译仿真的环境,即可让其在SimRobot下运行。

                make Nao是编译实体机器人,能够在机器人上运行。    


猜你喜欢

转载自blog.csdn.net/qq_34062822/article/details/80328661