【Nao V6】Behavior Control ——Goalkeeper

前言

~

正文

KeeperCatchBallCard

每隔100ms检测一次球可能穿过来的方向,对应的手举起来,时刻准备扑倒,若会碰到门柱,则禁止扑倒

KeeperSearchForBallCard

触发条件:当整个队伍都看不到球时
先检查一下球有没有在脚边,若没有再走到一个最好的地方检查自己的半场

KeeperClearBallCard

触发条件:需要keeper把球踢出去时

ReturnToGoalCard

触发条件:当keeper在penalt box之后时
需要立即返回

GuardGoalCard

触发条件:默认
计算球最有可能进的位置,站在那

示例

实现一个简化版的GuardGoalCard。
让keeper站在球分别与两球柱连成的直线的角平分线上。
球距离过远时,则让keeper休息。

/**
 * @file CodeReleaseGuardGoalCard.cpp
 *
 * This file states the default behavior that make keeper stand in a proper position.
 *
 * @author CC
 */

#include "Representations/BehaviorControl/FieldBall.h"
#include "Representations/BehaviorControl/Skills.h"
#include "Representations/Configuration/FieldDimensions.h"
#include "Representations/Modeling/RobotPose.h"
#include "Tools/BehaviorControl/Framework/Card/Card.h"
#include "Tools/BehaviorControl/Framework/Card/CabslCard.h"
#include <cmath>

#define mymax(a,b) (((a) > (b)) ? (a) : (b))
#define mymin(a,b) (((a) < (b)) ? (a) : (b))

CARD(CodeReleaseGuardGoalCard,
{,
  CALLS(Activity),
  CALLS(LookForward),
  CALLS(WalkToTarget),
  CALLS(SpecialAction),
  CALLS(Say),
  REQUIRES(FieldBall),
  REQUIRES(FieldDimensions),
  REQUIRES(RobotPose),
  DEFINES_PARAMETERS(
  {,
    (float)(0.8f) walkSpeed,
    (Angle)(15_deg) ballAlignThreshold,
    (float)(3800.f) maxAlertLen,
    (float)(200.f) spaceX,
    (float)(120.f) spaceY,
  }),
});

class CodeReleaseGuardGoalCard : public CodeReleaseGuardGoalCardBase
{
  bool preconditions() const override
  {
    return true;
  }

  bool postconditions() const override
  {
    return true;
  }
  
  Pose2f calFittingPose()
  {
    float angle1,angle2,angle;
    if (fabs(theFieldDimensions.xPosOwnGoalPost-theFieldBall.positionOnField.x()) > 1e-4)
    {
        angle1 = (float)atan2((theFieldDimensions.yPosRightGoal-theFieldBall.positionOnField.y()),(theFieldDimensions.xPosOwnGoalPost-theFieldBall.positionOnField.x()));
	angle2 = (float)atan2((theFieldDimensions.yPosLeftGoal-theFieldBall.positionOnField.y()),(theFieldDimensions.xPosOwnGoalPost-theFieldBall.positionOnField.x()));
    }
    else
    {
        angle1 = angle2 = 1.57f;
    }
    angle = (angle1+angle2)/2;
    float ratio = (float)tan(angle);
    float x1,y1,x2,y2,x,y;
    x2 = theFieldDimensions.xPosOwnPenaltyArea - spaceX;
    y2 = ratio*(x2-theFieldBall.positionOnField.x())+theFieldBall.positionOnField.y();
    if (ratio < 0)
    {
        y1 = theFieldDimensions.yPosRightPenaltyArea + spaceY;
        x1 = (y1 - theFieldBall.positionOnField.y())/ratio + theFieldBall.positionOnField.x();
        x = mymin(x1,x2);
        y = mymax(y1,y2);
    }
    else
    {
        y1 = theFieldDimensions.yPosLeftPenaltyArea - spaceY;
        x1 = (y1 - theFieldBall.positionOnField.y())/ratio + theFieldBall.positionOnField.x();
        x = mymin(x1,x2);
        y = mymin(y1,y2);
    }
    return theRobotPose.inversePose * Vector2f(x, y);
    
  }
  void execute() override
  {
    theActivitySkill(BehaviorStatus::codeReleaseGuardGoal);//需要去BehaviorStatus.h文件夹下添加codeReleaseGuardGoal状态
    theLookForwardSkill();
    if (theFieldBall.distanceToOwnPenaltyArea > maxAlertLen)
    {
        theSaySkill("none of my business");
	theSpecialActionSkill(SpecialActionRequest::playDead);
    }
    else
    {
        theSaySkill("I am in");
        Pose2f pos = calFittingPose();
        if (std::abs(theFieldBall.positionRelative.angle()) > ballAlignThreshold)
        {
            theWalkToTargetSkill(Pose2f(walkSpeed, walkSpeed, walkSpeed), Pose2f(theFieldBall.positionRelative.angle(), 0.f, 0.f));
        }
        else
        {
            theWalkToTargetSkill(Pose2f(walkSpeed, walkSpeed, walkSpeed), Pose2f(theFieldBall.positionRelative.angle(), pos.translation.x(), pos.translation.y()));
        }
    }
  }
};

MAKE_CARD(CodeReleaseGuardGoalCard);

仿真一下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值