Coder Social home page Coder Social logo

ai's Introduction

Hi there 👋

#

GitHub Profile Visitors GitHub followers GitHub User's stars

Top Langs milkcocoa0902's github stats

trophy

ai's People

Contributors

milkcocoa0902 avatar

Watchers

 avatar  avatar

ai's Issues

clang-formatへの対応

  • clang-formatの設定ファイルの作成
  • コードがformatされているかの確認スクリプト
  • 全ファイルを一斉にclang-formatするスクリプトの作成

Boost.Testの導入

Boost.Testを導入し、各種driverがしっかりと動作をするかどうか確認する

PathPlannerの実装

ロボットを目標地点まで到達させるための経路生成機構が必要です.
RRT*を用いた経路生成機能を実装してください.

team infoを格納するclassの作成

チームの情報を格納するclassを作成する
格納する情報

  • チーム名
  • 得点
  • ゴーリー
  • レッドカードの数
  • イエローカードの数
  • イエローカードの残り時間
  • タイムアウトの回数
  • タイムアウトの残り時間

filterのbase class

Visionから受信したデータなどを加工する部分(Filter)のベースクラスが必要です.

ボールの状態オブザーバの実装

SSL-Visionは、時折ボールを見失ったり、そもそも誤差を含んでいたりします。
それを解決するために状態オブザーバを実装してください。

仕様

参考資料に示すような状態変数を持つボールの状態オブザーバを実装してください。

// (1)
class ball : public base<model::ball, timing::OnUpdated> {
public:
  // (2)
  using base<model::ball, timing::manual>::base;

  // (3)
  model::ball update(
    const model::ball& _ball,
    std::chrono::high_resolution_clock::time_point _time) override;
};

1. 実装するクラス

filter::base<model::ball, filter::timing::OnUpdated>から派生したものとしてください.

2. コンストラクタ

必要に応じて実装してください.
必要な値がなければ ↑↑のようにすれば良いです

  1. updateメンバ関数
    const model::ball& _ball: Visionから観測された値
    std::chrono::high_resolution_clock::time_point _time: Visionがフレームをキャプチャした時刻

実装するファイル

src
└── ai
    └── filter
        └── observer
            ├── ball.cpp
            └── ball.hpp

備考

  • クラスはai::filter::observer:名前空間にballとして実装してください。

参考資料

from

stateobserver

新しいコントローラの作成

#63 でコントローラを作成したが、位置制御に向いていないのか、思ったほどの速度を出すことができない(30[mm/s]程度)。
そこで、新たなコントローラの実装を行う

refereeBoxの情報を格納するclass

refereeBoxから送られてくる情報を格納するclassを作成してください


仕様

class refbox {
public:
  // (1)
  enum class stageName { };
  
  // (2)
  enum class gameCommand { };

  // (3)
  refbox();

  // (4)
  util::timePointType packetTmestamp() const;
  uint32_t stageTmeLeft() const;
  stageName stage() const;
  gameCommand command() const;
  teamInfo teamYellow() const;
  teamInfo teamBlue() const;
  std::tuple<double, double> ballPlacementPosition() const;

  // (5)
  void packetTmestamp(util::timePointType _timePoint);
  void stageTmeLeft(uint32_t _timeLeft);
  void stage(stageName _name);
  void command(gameCommand _command);
  void teamYellow(const teamInfo& _info);
  void teamBlue(const teamInfo& _info);
  void ballPlacementPosition(std::tuple<double, double> _position);

private:
  util::timePointType packetTmestamp_;
  uint32_t stageTmeLeft_;
  stageName stage_;
  gameCommand command_;
  teamInfo teamYellow_;
  teamInfo teamBlue_;
  std::tuple<double, double> ballPlacementPosition_;
};

1. メンバ・メソッド

(1) ステージ名の列挙体

ゲームの状態を表す列挙隊を作成してください。ゲーム名はssl-protos/refbox/referee.pb.hの中に定義されているのでそれを参照してください

(2) コマンドの列挙体

ゲームコマンドを表す列挙体を作成してください。コマンド名はl-protos/refbox/referee.pb.hの中に定義されているのでそれを参照してください

(3) コンストラクタ

メンバを初期化するためのコンストラクタを設定してください。

(4) getter

各メンバの値を取得するためのgetterを設定してください。

(5) setter

各メンバに値を格納するためのsetterを設定してください。

2. 実装するファイル

ai-
├── src
│   └── ai
│       └── model
│           ├── refbox.cpp
│           └── refbox.hpp
└── test
    └── model
        └── refbox.cpp

3. 備考

クラスはai::model名前空間にrefboxとして実装してください

ロボットとの通信に関して考える

ロボットと戦略システムを通信させる上での手段(パケットフォーマット, プロトコル, 機材.....)に関して議論する.

  • フォーマットどうする?
    • ロボットのID
    • 移動速度や移動方向などの指令情報  
    • CRC(16bit or 32bit ?)
  • 双方向通信したい?
    • やってるチームが少ないのでTDPのネタになるかも()
    • するならロボットから情報をフィードバックできる
    • どんな情報を返してもらう?バッテリー残量とかセンサの値とか?
    • やるならどうする?ZigBeeだときつい?Wi-Fi?
  • Wi-Fi or ZigBee or ..... ?
    • Wi-FiならUDPだろうか?TCPだとハンドシェイク周りで遅くなりそう
    • UDPだとパケロスとかが怖い(そのためのCRC)
    • 双方向通信したいならWi-Fiのほうがいい?(大会では1CHしか割り当ててもらえないから)  

みたいな、こんなのどう?みたいなことあげてって議論する感じの

ボールを指定位置にけるアクション

指定した位置にボールを蹴るためのactionを実装したい.

最低限の仕様は以下の通り

仕様

class kick : public base{
  public:
    using base::base;  // (1)
    void kickTo(double _x, double _y);  // (2)
    model::command execute();  /// (3)

  private:
    // (4)
    double x_;
    double y_;
};

1. コンストラクタ

特に必要でない場合は指定のものを使用してください.action::base::base() で受け取っている以外のパラメータが必要な場合は適宜実装してください.

2. kickTo()

ボールを蹴る位置を指定するための関数です.

3. execute()

実際に処理を行うための関数です.

4. メンバ

double x_; : ボールの目標位置のx座標
double y_; : ボールの目標位置のy座標

実装するファイル

src
└── ai
    └── game
        └── action
            ├── kick.cpp
            └── kick.hpp

備考

  • クラスはai::game::action名前空間に実装してください
  • 処理が終わった場合には finished_true をセットするようにしてください

目標

  • ロボット・ボール・目標位置が一直線で結ばれていたらそのまま蹴ることができる
  • 上の場合で,ロボットが目標位置を向いてない場合には振り向いて蹴ることができる
  • 一直線に結ばれていない場合,回り込んで蹴ることができる

関連ファイル

  • 参考
    • ai/game/action/move.(hpp | cpp)
    • ai/game/action/getBall.(hpp | cpp)
  • 各モデル
    • ai/model/ball.(hpp | cpp)
    • ai/model/robot.(hpp | cpp)
    • ai/model/world.(hpp | cpp)
  • command
    • ai/model/command.(hpp | cpp)
  • チームカラー
    • ai/model/teamColor.hpp

grSimへデータを送信するためのsender

grSim上のロボットへ命令を送るためのクラスが必要です.


仕様

クラスは少なくとも以下に示すメンバ関数, データメンバを持つ.

// (1)
class grsim final : public base {
public:
  // (2)
  grsim(boost::asio::io_service& _ioService, const std::string& _grsimAddr, uint16_t _port);

  // (3)
  void sendCommand(const model::command& _command) override;

private:
  // (4)
  util::multicast::sender udpSender_;
};

1. grsimクラス

クラスは #62sender::baseから派生したものとする. また, このクラスが他のクラスから継承されないようにfinal指定子を付けておく.

2. コンストラクタ

  • boost::asio::io_service& _ioService
    • (4) のudpSender_のコンストラクタで必要になる
    • <boost/asio.hpp>をincludeすると使える
  • const std::string& _grsimAddr
    • grSimが動いているマシンのIPアドレス
    • (4) のudpSender_のコンストラクタで必要になる
  • uint16_t _port
    • grSimがコマンドを受け付けているポート
    • (4) のudpSender_のコンストラクタで必要になる

3. model::commandを送信するメンバ関数

引数で受け取ったcommand"ssl-protos/grsim/packet.pb.h"をincludeすると使えるようになるssl_protos::grsim::Packetクラスでシリアライズし, udpSender_を使って送信する.
送信は以下のようなコードで行うことができる.

ssl_protos::grsim::Packet packet{};

// ここでpacketにデータをセットする

// 送信バッファと, それに書き込むstreamクラスのオブジェクトを作成
boost::asio::streambuf buf;
std::ostream os(&buf);

// packetをシリアライズし, 結果をos経由でbufに書き込む
packet.SerializeToOstream(&os);

// bufを送信
udpSender_.send(buf.data());

4. UDPソケットを使ったデータの送信を行うクラス

コンストラクタの初期化リストで_ioService_grsimAddr, _portを渡して初期化してください.

実装するファイル

ai
├── src
│   └── ai
│       └── sender
│           ├── grsim.cpp
│           └── grsim.hpp
└── test
    └── sender
        └── grsim.cpp

その他

  • クラスはai::sender名前空間内にgrsimで実装してください
  • grSimのロボットにドリブルバー速度というパラメータは存在しないので, 0だったらfalse, それ以外だったらtrueという感じで大丈夫です
  • キックパワーも今回は適当で(そのままキャスト&代入)大丈夫です
  • もしgrSimを動かすことができたら, 実装したgrsimクラスの動作確認をやってみると楽しいかもしれません (みんなより一歩早くロボット動かせるぞ!!!)

デバッグで明らかにおかしい挙動をする

Slackで話したとおりイエローの0がブルーの0に向かってく挙動をします。
Masterから変更したのはmain.cppの以下の関数のみです

void mainLoop() {
    std::cout << "game start!!" << std::endl;
    ai::util::TimePointType prevTime{};

    game::action::move move(world_, false, 0);

    while (running_) {
      try {
        const auto currentTime = util::ClockType::now();
        if (currentTime - prevTime < cycle) {
          std::this_thread::sleep_for(1ms);
        } else {
          std::unique_lock<std::shared_timed_mutex> lock(mutex_);
          const auto prevCmd = refbox_.command();
          world_             = updaterWorld_.value();
          refbox_            = updaterRefbox_.value();

          const auto currentCmd  = refbox_.command();
          const auto penaltyKick = teamColor_ == model::teamColor::Yellow
                                       ? model::refbox::gameCommand::PreparePenaltyYellow
                                       : model::refbox::gameCommand::PreparePenaltyBlue;

          // stopgameとpenalty_kickでは速度を落として安定制御
          if (currentCmd != prevCmd) {
            if (currentCmd == model::refbox::gameCommand::Stop ||
                /*current_cmd == model::refbox::game_command::ball_placement_yellow ||
                  current_cmd == model::refbox::game_command::ball_placement_blue ||*/
                (prevCmd == penaltyKick &&
                 currentCmd == model::refbox::gameCommand::NormalStart) ||
                currentCmd == model::refbox::gameCommand::PreparePenaltyYellow ||
                currentCmd == model::refbox::gameCommand::PreparePenaltyBlue) {
              driver_.velocityLimit(500);
            } else if (currentCmd == model::refbox::gameCommand::BallPlacementYellow ||
                       currentCmd == model::refbox::gameCommand::BallPlacementBlue) {
              driver_.velocityLimit(1000);
            } else {
              driver_.velocityLimit(std::numeric_limits<double>::max());
            }
          }

          const auto visibleRobots =
              static_cast<bool>(teamColor_) ? world_.robotsYellow() : world_.robotsBlue();
          prevTime = currentTime;

          // witten by suiheki20181104
          move.moveTo(3000, 3000, 0);
          auto model_tmp = move.execute();
          driver_.updateCommand(model_tmp);
        }
      } catch (const std::exception& e) {
        std::cout << boost::format("exception at game_thread\n\t%1%") % e.what() << std::endl;
      } catch (...) {
        std::cout << "unknown exception at game_thread" << std::endl;
      }
    }
  }

boost::variantの廃止

ai::controller::base にて、 boost::variant が使用されたままになっている
これを、 std::variant に変更したい

ボールを扱うactionの作成

ボールを処理するためのactionを作成してください。


仕様

最低限、以下を実装してください。

class getBall: public base{
private:
  // (1)   
  position target_;

public:
  using base::base; 
  setTarget(cosnt position _target);  // (2)
  model::command execute() override;  // (3)
};

1. メンバ

position target_ ... 狙う位置

2. setTarget()

狙う位置を設定する

3. execute()

動作処理

実装するファイル

src
└── ai
    └── game
        └── action
            ├── getBall.cpp
            └── getBall.hpp

必要な動作

  • 向かってくるボールをとる
  • 離れていくボールに回り込む
  • 目標地点に蹴る
  • 目の前に敵がいたらチップキックをする

備考

  • クラスはai::game::actiongetBallとして実装してください

壁用のaction

ディフェンスエリア手前にロボットを数台置いて壁を作るのがrobocupでは主流となっている。
そこで、壁用のactionを作成する必要がある。
基本的には move と同様の構成のactionとなるが、ボールを蹴るという点が両者の最大の違いとなる。

仕様

最低限の仕様は以下の通り

class clear : public base{
private:
  // (1)
  model::command::position pos_;
  model::command::KickFlag kick_;
  
public:
  using base::base;
  void moveTo(model::command::position _pos); // (2)
  void kickType(model::command::kickType _kick, double _power); // (3)
  model::command execute() override; // (4)
};

1. メンバ

model::command::position pos_ : 移動先の座標
model::command::KickFlag kick_ : キックタイプとパワーのtuple. キックタイプは model::command::kickType を参照

2. moveTo()関数

引数に移動先の座標を受け取るので、それをメンバに登録してください。

3. kickType()関数

引数にキックタイプとパワーを受け取るので、それをtuple化してメンバに格納してください

4. execute()関数

実際にactionを定義する関数です。
基本的な処理内容は action::move::execute() と変わりませんが、commandにキック指令を登録するようにしてください。
また、向く方向はボールの方向です。ただし、ゴールの方向には向かないものと考えてください。(ひとまずはこれは気にしなくてもいいかも)

実装するファイル

src
└── ai
    └── game
        └── action
            ├── clear.cpp
            └── clear.hpp

備考

  • クラスは ai::game::action 名前空間に登録してください

関連ファイル

  • 参考
    • ai/game/action/move.(hpp | cpp)
  • 各モデル
    • ai/model/ball.(hpp | cpp)
    • ai/model/robot.(hpp | cpp)
    • ai/model/world.(hpp | cpp)
  • command
    • ai/model/command.(hpp | cpp)
  • チームカラー
    • ai/model/teamColor.hpp

チームカラーを表現する型

チームカラーを表現する型を作成する.


仕様

/// チームカラーを表現する列挙型
enum class teamColor {
  blue,
  yellow,
};

1. メンバ

メンバはblue, yellowの各チーム色から構成されます

2. 実装するファイル

以下の階層にそれぞれ列挙型とテストケースを実装してください

ai
├──src
│   └──ai
│       └──model
│            └──teamColor.hpp
│
└test
  └──model
     └──teamColor.cpp

3. 備考

namespaceはai::modelに設置してください.

CRC-16のライブラリの作成

関連 #11

#11 では仮りとされているが、ロボットと通信するパケット内にCRCが用いられることだろう。
そこで、CRC16、特にCRC-16-IBMの計算をするライブラリを作成する。

フィールドを表すclassの実装

フィールドの情報を表すためのclassを実装してください


仕様

class field {
private:
  uint32_t length_;
  uint32_t width_;
  uint32_t centerRadius_;
  uint32_t goalWidth_;
  uint32_t penaltyLength_;
  uint32_t penaltyWidth_;

public:
  // (1)
  field();

  // (2)
  uint32_t length() const;
  uint32_t width() const;
  uint32_t centerRadius() const;
  uint32_t goalWidth() const;
  uint32_t penaltyLength() const;
  uint32_t penaltyWidth() const;

  // (3)
  void length(uint32_t _length);
  void width(uint32_t _width);
  void centerRadius(uint32_t _centerRadius);
  void goalWidth(uint32_t _goalWidth);
  void penaltyLength(uint32_t _penaltyLength);
  void penaltyWidth(uint32_t _penaltyWidth);

  // (4)
  double xMax() const;
  double xMin() const;
  double yMax() const;
  double yMin() const;
};

1. コンストラクタ

各データメンバを初期化するためのコンストラクタを実装してください

2. Getter

各データメンバの値を取得するためのGetterメソッドを実装してください

3. Setter

対応するデータメンバに対してデータを格納するためのSetterメソッドを実装してください

4. 座標変換

フィールドの中心を原点とした時に, フィールド端の座標を取得するためのメソッドを実装してください.
例えばxMax()は次のように実装されます.

double xMax()const{
  return (length / 2);
}

実装するファイル

ai
├── src
│   └── ai
│       └── model
│           ├── field.cpp
│           └── field.hpp
└── test
    └── model
        └── field.cpp

備考

  • classはai::model名前空間にfieldを実装してください

Wercker

Werckerを使用してpush時に自動でbuildテストするようにする

driverの実装

コマンドを送信したり、ssl-visionからデータを受信したりするためのdriverが必要です
(詳細仕様は省く)

ABPに対応する

ABP(=Autonomous Ball Placement )に対応したい
ABPとは,セットプレイに移行する際にロボットによって指定座標にボールを配置するような行為を指す.
配置座標が与えられるため, その座標にボールを持っていけるようなActionを作成してほしい

仕様

class AutonomousBallPlacement : public base {
public:
  // (1)
  AutonomousBallPlacement(const model::world& _world, bool _isYellow, uint32_t _id, Eigen::Vector2d _target);

  // (2)
  enum class runningState { 
        Move, // ボール前まで移動
        Hold,  // ボールを持つ
        Place, // ボールを指定位置まで運ぶ
        Wait,  // ボールの回転を止めるためドリブルバーを止めて停止
        Leave,  // ボールから離れる
        Finished // 動作終了(停止)
  };

  // (3)
  enum class placeMode { 
        Pull, 
        Push
  };

  // (4)
  model::command execute() override;

private:
  // (5)
  runningState state_;
  placeMode mode_;
  bool waitFlag_;
  bool roundFlag_;
  util::TimePointType begin_;
  util::TimePointType now_;
  Eigen::Vector2d target_;
  Eigen::Vector2d abpTarget_;
  double firstBallx_;
  double firstBally_;
};

(1) コンストラクタ

_target には,ボールを配置する座標を指定してください

(2) enum runningState

処理の進行具合を表すステートマシンです.

(3) enum placeMode

配置する際にpull(引っ張る)かpush(押していく)かを指定するための列挙体です.

(4) execute()関数

実際の処理を記述してください

(5) メンバ

runningState state_; 現在の進行具合です
placeMode mode_; どうやって目的地まで持っていくか
bool waitFlag_; 待つ?
bool roundFlag_; 回り込む?
util::TimePointType begin_; 開始時刻
util::TimePointType now_; 現在時刻
Eigen::Vector2d target_; 移動目標位置
Eigen::Vector2d abpTarget_; 最終的な目的地
double firstBallx_; ボールが最初にあったx座標
double firstBally_; ボールが最初にあったy座標

実装するファイル

src
└── ai
    └── game
        └── action
            ├── abp.cpp
            └── abp.hpp

備考

  • クラスは ai::game::action 名前空間に登録してください

関連ファイル

  • 参考
    • ai/game/action/move.(hpp | cpp)
    • ai/game/action/getBall.(hpp | cpp)
  • 各モデル
    • ai/model/ball.(hpp | cpp)
    • ai/model/robot.(hpp | cpp)
    • ai/model/world.(hpp | cpp)
  • command
    • ai/model/command.(hpp | cpp)
  • チームカラー
    • ai/model/teamColor.hpp

敵ロボットをマーキングするためのアクション

敵ロボットをマーキングするためのアクションを作成してください


仕様

最低限、以下を実装してください

class marking: public base{
private:
  // (1)   
  uint32_t id_;

public:
  using base::base; 
  markRobot(cosnt uint32_t _id);  // (2)
  model::command execute() override;  // (3)
};

1. メンバ

uint32_t id_ ... マーキング対象のロボットのid

2. markRobot(cosnt uint32_t _id);

マークするロボットをセットするための処理

3. execute()

動作処理

実装するファイル

src
└── ai
    └── game
        └── action
            ├── marking.cpp
            └── marking.hpp

必要な動作

  • パスカット
  • シュートのカット

SSL-Visionから得られたデータを格納するclass

SSL-Visionから得られたデータを格納するclassを作成してください


仕様

class world {
  // (1)
  mutable std::mutex mutex_;

  // (2)
  model::field field_;
  model::ball ball_;
  std::unordered_map<unsigned int, model::robot> robots_blue_;
  std::unordered_map<unsigned int, model::robot> robots_yellow_;

public:
  // (3)
  model::field field() const;
  model::ball ball() const;
  std::unordered_map<unsigned int, model::robot> robots_blue() const;
  std::unordered_map<unsigned int, model::robot> robots_yellow() const;

  // (4)
  void update(const ssl_protos::vision::Packet& packet);
};

1. std::mutex

std::mutex及びstd::lock_guardを使い, 内部リソース(2)へのアクセスを排他的にしてください.
mutex_にはmutable指定子を付け, constなメンバ関数からも変更できるようにしてください.

2. 内部で保持するパラメータ

以下の4つのパラメータを保持してください.

model::field field_;: フィールドのサイス等
model::ball ball_;: フィールド上のボール
std::unordered_map<unsigned int, model::robot> robots_blue_;: フィールド上の青ロボット
std::unordered_map<unsigned int, model::robot> robots_yellow_;: フィールド上の黃ロボット

3. getter

(2)で挙げた値を取得するためのgetterを実装してください.
値をreturnする前に, std::lock_guardを使ってmutex_をロックしてください.

4. 内部状態の更新

(2)で挙げた内部のパラメータを更新するためのメンバ関数update()を実装してください.
簡単な処理の流れは以下のとおりです.

  1. 引数でVisionからのパケット(protobufのパース済み)を受け取る
  2. パケットにdetectionが含まれていればball_, robots_blue_, robots_yellow_を更新する
  3. パケットにgeometryが含まれていればfield_を更新する

(3)と同様に, 内部の値を更新する前にstd::lock_guardを使ってmutex_をロックしてください.

実装するファイル

├── src
│   └── ai
│       └── model
│           ├── world.cpp
│           └── world.hpp
└── test
    └── model
        └── world.cpp

備考

  • クラスはai::model名前空間内にworldで実装してください

環境を構築する

環境を構築する上で「ここんとこちょっとうまくいかないみたい」なことがあったらこの板に書き込んでください
(Issueに慣れるのも兼れればいいな)

ロボットの状態オブザーバの実装

参考資料: #71 を参照のこと

仕様


// (1)
class robot : public base<model::robot, timing::Manual> {
public:
  // (2)
  using base<model::robot, timing::Manual>::base;

  // (3)
  void observe(const model::command::velocity _u,
               std::chrono::high_resolution_clock::time_point _time);
};

1. 実装するクラス

#45 のfilter::base<model::robot, filter::timing::Manual>から派生したものとしてください.

2. コンストラクタ

必要に応じて実装してください.
必要な値がなければ ↑↑↑のようにすれば良いです.

3. observeメンバ関数

const model::command::velocity _u: 制御入力量
std::chrono::high_resolution_clock::time_point _time: Controllerが命令を生成した時刻
状態オブザーバを更新するメンバ関数です.

実装するファイル

src
└── ai
    └── filter
        └── observer
            ├── robot.cpp
            └── robot.hpp

備考

クラスはai::filter::observer名前空間内に実装してください
ここでの状態は (位置, 速度, 加速度) です

位置制御時のオーバーシュート

RRTでの経路生成か速度生成器での生成に問題があるのか、とてもオーバーシュートしている。
もう少しちゃんと目標位置にたどり着きたいのでこれを修正したい

関連ファイル

src/ai/controller/decision/velGen.cpp

ロボットへ送る命令のデータ型

ロボットへ送るデータを表現するclassを実装してください.
なお, #11 の結果に依存しない一般的な部分を実装します.


仕様

class command {
public:
  // (1)
  enum class kickType { none, straight, tip };

  struct position {
    double x;
    double y;
    double theta;
  };

  struct velocity {
    double vx;
    double vy;
    double omega;
  };

  using Setpoint  = std::variant<position, velocity>;
  using KickFlag = std::tuple<kickType, double>;

  // (2)
  explicit command(uint32_t _id);

  // (3)
  uint32_t id() const;
  int32_t dribble() const;
  KickFlag kick() const;
  const Setpoint& setpoint() const;

  void dribble(int dribble);
  void kick(const KickFlag& _kick);
  void position(const position& _position);
  void velocity(const velocity& _velocity);

private:
  // (4)
  uint32_t id_;
  int32_t dribble_;
  KickFlag kick_;
  Setpoint_t setpoint_;
};

1. 位置, 速度の構造体と型安全共用体, キック種類の列挙型

位置と速度に関する処理を型レベルで別々に扱いたいので, それぞれを表現する構造体を宣言します.
また, 位置または速度という状態を表現するために, 型安全共用体ライブラリのstd::variantを使用します.

2. コンストラクタ

クラスのデータメンバid_はコンストラクタからのみ設定できるようにします.
値を一つだけ受け取るので, command c = 1; のような初期化ができないようにexplicit をつけてください.

3. getterとsetter

各データメンバの値を取得するためのgetterと, id_を除くデータメンバに値を設定するためのsetterを実装してください.

4. クラスに持たせるパラメータ

uint32_t id_;: ロボットのID
int32_t dribble_; ドリブルバーのパワー
KickFlag kick;: キックフラグ
Setpoint setpoint_;: 目標位置または目標速度

実装するファイル

ai-
├── src
│   └── ai
│       └── model
│           ├── command.cpp
│           └── command.hpp
└── test
    └── model
        └── command.cpp

備考

クラスはai::model名前空間内にcommandで実装してください

robotのモデルを作成する

ロボットの状態を保管するモデルを作成する。

保存する状態は、 (位置、速度、加速度) に加えて (移動方向、回転(角)速度)

ロボットを制御するための機構(controller)の実装

ロボットの制御を行うクラスが必要です.


仕様

// (1)
class very_cool_name : public base {
public:
  // (2)
  very_cool_name(double interval, ...);

  // (3)
  velocity_t update(const model::robot& _robot, const position& _setpoint) override;
  velocity_t update(const model::robot& _robot, const velocity& _setpoint) override;
};

1. 実装するクラス

何かかっこいい名前を付けてください.
クラスは後述するcontroller::baseから派生したものとしてください.

2. コンストラクタ

  • double interval
    • 制御周期 [s]?

その他必要なパラメータがあれば, 2つ目の引数以降で受け取ってください.

3. 目標値から操作量を計算するメンバ関数

目標値setpointから操作量を計算するメンバ関数.
目標値として位置が渡された場合と速度が渡された場合の2種類を実装してください.

第1引数のrobotは, そのループが実行されるときのロボットの状態です.

実装するファイル

ai
└── src
    └── ai
        └── controller
            ├── base.cpp
            ├── base.hpp
            ├── very_cool_name.cpp
            └── very_cool_name.hpp

その他

  • クラスはai::controller名前空間内に実装してください

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.