ロボコン向けロボット制御について
先端小型の鷹羽です。会社始まる前にやり切りたかったので急ぎで書いてます。読みずらいと思うけど許してね。
はじめに
この記事は私みたいにロボットどころか全然何も知らない、実習で触ったことですらあやふやでcadも基本操作のみ、加工もちょっと旋盤やったくらい、言語も名前しか知らない、基板なんて何もわからんみたいな状態からロボコン始めた人向けに書いてます。
私は制御は全然得意じゃなく、大会でもほかのメンバーに任せっきりだったので詳しいことはわかりませんが、コーディングとかの話じゃなく知識面の話を多少できたらいいかと思います。ほんとに序盤も序盤、詳しい内容というよりは概念を知ってもらう目的なのですでに知識がある人は読まなくていいです。
目次
通信について
通信って言われてなんとなくイメージつきますか?通信にはいろんな種類があり、ブルートゥースみたいなのやwifiなどの無線からケーブルを使った有線接続まで様々あります。ネットワークの授業がしたいわけではないのでここではロボコンでよく使う通信について紹介します。使い方とかってより軽く知ったほうがいい知識面の話です。
シリアル、パラレル通信
シリアル、パラレルと聞いて何かわかりますか?人によっては習ったり聞いたことがあるかもです。通信というのはほぼこの二つに分けられて、簡単に言えば一つの線のみを使うのがシリアル、複数の線を使うのをパラレルといいます。これだけ聞くとパラレルのほうが早そうな感じしますし、実際昔はそうでした。ですが現代においては昔に比べマイコンの処理性能が格段に向上し、高速域だとケーブル間の速度のずれやケーブル同士の放射ノイズが発生すること、またポートを複数占有することなどが弱点となり、シリアル通信のほうが一般に使用されています。以降紹介するのもすべてシリアル通信に分類されます。
UART
かなり有名な部類なので聞いたことあるかもしれません。非常にシンプルな通信方式で、TX(送信)とRX(受信)の二つの線を使って通信する方式です。arduinoのシリアルモニタなどもこの方式で通信しています。シリアルモニタ使ったことある人ならわかると思いますが、9600baudとか115200baudとかを設定しないと文字化けしたり、通信できなかったりしますよね。これは通信の速度で、お互いに同じ歩調でないと通信できないためこれらを事前に決めて共有しておく必要があります。
単一機器にしか接続できないことや速度がほかの通信に比べ多少劣る点、ノイズにかなり弱いことなどがありきちんとした通信がしたい場合にはあまり使用されません。
I2C
これも非常によく使われます。センサモジュールとかも大抵はこれを使います。SDA(Serial Data)とSCL(Serial Clock)の二つの線を使って通信します。uartと違い、通信自体にはSDAを使い、SCLは名前の通りクロック、つまりは速度を合わせるための線があります。デバイスごとに上限速度を決める必要こそありますが、厳密に合わせずとも通信が可能です。最大の特徴としては一つのマイコンから複数の機器を扱えることです。マスター、スレーブという風に機器が分けられ、要はマイコンがマスター、センサなどがスレーブにあたります。arduinoだとA4、A5がI2C用のポートになりますが、並列に接続することで最大128台接続できることです。ただ機器などが持つコンデンサ特性のせいで切り替えが遅れることなどから現実的には10個くらいが限界です。それ以上通信したいときにはプルアップ抵抗を小さくする、マルチプレクサなどを使いポートを分けることなどで台数を増やせます。速度はそこまで早いほうではなく、また基板内の通信を想定した規格のためノイズに弱いことが欠点です。
SPI
就職試験で受けそうな名前してますがこっちはSerial Peripheral Interface、直列周辺機器インターフェースって意味です。クロック線のSCK、マスターからスレーブに信号を送るMOSI(最近はSDIっていうらしい)、スレーブからマスターに信号を送るMISO(SDO)、どのスレーブと通信するか選ぶためのCSと四つも線をつなぐ必要がありますが、I2Cなどに比べ非常に高速で、数十Mbpsでの通信が可能です。またCSをスレーブの数分だけ増やせば複数の機器と通信が可能です。ただ線の数が多いこと、また規格が厳格でなく機器によってクロックのタイミングが異なることがあることが欠点です。デイジーチェーンって方法使うとCSの線の数をなんとかできるんですが複雑な処理が必要になります。
CAN
CAN_H、CAN_Lの二つの線を使い、簡単に言えば二つの線の電位差をみる、差動信号って方式で通信します。SPIほどじゃないですが1Mbpsほどの高速な通信が可能で、ノイズに非常に強く、また線の数が少なく複数の機器に同時接続できます。通信が若干複雑なこと、コントローラIC(MCP2561とか)がないと通信できないことなどが欠点として挙げられますが非常に優秀な通信方式で、最近のモータとかは結構これが使われてます。
制御工学について
制御工学って言われてピンときますか?たぶんこれから習うと思うんですが、授業だけで理解するのも難しいですし、習うの待ってたら大会終わっちゃうので軽く解説します。式とは出しません。gitとかでライブラリ見たり、ネットで調べるとかなり開設乗ってるので必要になったら調べてください。
制御工学とは
調べて一番上に出てきたのは"「機械やシステムを、目的に合わせて思い通りに動かすための仕組み」を研究する学問"ってことらしいです。簡単に言えばロボットを動かすとき、(0,0)の地点から(0,10)に動かしたいとします。ロボットにy10まで動けといって動いたらいいですが、加速度しか指定できないときどうしますか?加速度のみを動かせるスティックでぴったりに動かすのは至難ですが、制御工学ではy10に動けって指示したら勝手に動くための計算を勉強します。こういうのをコントローラって呼んで、入力に合わせコントローラで計算し、出力するような感じです。全体を統合して制御系って言います。
古典制御と現代制御
制御工学は主に二つの分野に分けられ、古典制御というのは一つの入力、一つの出力を扱う分野、現代制御ってのは複数の入出力が関係する制御対象を行列とかを使って扱う分野です。この世界にあるものはほぼ全部様々な要因が関係するため現代制御の方策で制御系が組めればいいんですが、現代制御は非常に複雑で、かなりの知識がないと組めませんし調整とかも簡単にはいきません。なのでロボコンでは基本的に古典制御が使用されます。
フィードバック制御
センサなどの入力を使って、今の状態を見ながら、つまりはフィードをバックしながら制御する方式です。制御工学ではブロック図を使って制御系を表現しますが、それでみると輪っかの形になってることから閉ループとかとも言います。フィードバックせず、計算上での予測のみで動くやり方をフィードフォワードといい、基本的にはこれらどちらもを組み合わせて制御を行います。
遅れ
制御工学において、指令通りに全部が動くなら完璧な制御が誰にだって行えます。ですが現実にはそうではなく、指示した通りに動かず、そのため制御がうまくいかないことが多くあります。その主な原因となるものは遅れです。簡単に言えば入力が出力に反映されるまでのタイムラグであり、これがあるせいでシステムがどんどん力を強くして目標を通り過ぎてしまったりします。
デッドタイム
指令を出してから反応が始まるまでの待ち時間のことです。例えばホースにつないだ蛇口をひねったとき、すぐに水が出るのではなくホースを通って出口までつく間の待ち時間などです。この時ホースの出口、またはさらにその先にしかセンサがない場合、制御系からすると「入力を加えたのに何の反応もない」となってしまい、さらに蛇口を解放します。すると少しの入力しか加えてなくてもとんでもない量を放水することになったりします。
一次遅れ系
制御系はシステムを微分方程式で表したときの形で〇次遅れ系と呼ばれます。一次遅れというのは一時微分方程式で表され、簡単に言えば指令の直後は勢いよく反応し、目標に近づくにつれ減速する制御系です。コンデンサの動きとかがこういった形になり、これらはあとで説明する発振という状態になりません。ロボットなどを制御する際、ほぼすべての場合においてロボットの関節は一次遅れでなく次に説明する二次遅れの形になります。
二次遅れ系
二次微分方程式で表され、簡単に言えば慣性とばね、二つの力が加わっている状態の制御系です。ブレーキをかけたとしてすぐには止まれないため、ゲイン(修正する力の強さの倍率)の調整が不十分だと目標を通り過ぎるオーバーシュート、そして発振を起こすことがあります。
ロボットにおいての遅れ
先ほど言ったようにロボットの関節などはほとんどすべての場合二次遅れになります。なぜならほとんどすべての場合関節には慣性が乗り、モータのギアボックス、出力軸からタイヤなどへの接続など様々な部分がたわみ、ばねとしての特性を持つからです。またギアの遊びや通信の遅れ、制御の周期など様々なものがデッドタイムになります。その為ロボットの制御系を構築する際は、それらを考えた制御系を組む必要があるのです。
発振
システムが制御不能になり、出力が激しく揺れ続けて止まらなくなる状態のことです。通常のフィードバック制御ではセンサからの現在の状態に合わせ指令を調節します。しかし様々な遅れが発生することで指令が間に合わなかったり、デッドタイムのせいで値を増やしすぎることでオーバーシュートが起きます。二次遅れの場合、行き過ぎたことで発生するマイナスの指令とは別にシステム自体が持つ慣性、ばねの特性があります。それらが重なることでいつまでも目標値にたどり着かず、それどころか暴走し始めることが起きます。これらは主にゲインが強すぎることなどで発生しやすく、ゲインの値を適切に設定すること、また後述のフィルタを使用することで対策をとることができます。
PIDについて
フィードバック制御とかについて軽く説明しましたが、じゃあ実際にロボットに組み込む制御ってどんなものなんでしょうか。ロボコンで多分一番広く使われている制御がPID制御です。
目標値と現在地の差を$
e(t)
$、モータへの指令を$
u(t)
$としたとき、PID制御は$$
u(t) = K_p e(t) + K_i \int_{0}^{t} e(\tau)\ d\tau + K_d \frac{de(t)}{dt}
$$と表すことができます。
P項
PIDというのはそもそもP項、I項、D項の三つを使ってロボットを制御する方式です。まずはP項について説明します。
PとはProportional、つまり比例という意味です。さっきの数式の$
K_p e(t)
$の部分です。$
K_p
$ってのはP項のゲインという意味です。要するに目標と距離が離れれば離れるほど強く、近づけば近づくほど弱い力をかける制御です。この要素のみを使ったP制御というものもあり、慣性が支配的でない制御系などでは実用できますが、たいていのロボットでは大きな慣性などが働くため発振したり、ゲインを弱く設定しすぎて目標の前で止まってしまい残留偏差が残ってしまいます。
D項
最初の数式の$
K_d \frac{de(t)}{dt}
$の部分です。DというのはDerivative、つまりは微分です。変化率に対し比例し、立ち上がりの部分を抑制し、かつ目標値周辺ではマイナス方向に力を加え、オーバーシュートを抑える役割があります。Dのことを疑似粘性とも言います。この項があることで、Pゲインは過度に小さな値にならず、高速な動作が可能になります。
I項
最初の数式の$
K_i \int_{0}^{t} e(\tau)\ d\tau
$の部分です。IというのはIntegral、つまりは積分です。P項では残留偏差が残るという話をしたと思いますが、ゲインが強くても例えば一定方向に重力がかかる制御系などでは、そういった外力と出力が釣り合うことで目標とは違う位置で停止してしまうことがあります。I項は時間に比例して強くなるため、わずかなずれを修正することができます。ちなみに$t$ではなく$\tau$なのは積分の式で表す都合上のものらしいです。
PID制御
これら三つの項目を使用し、PID制御は行われています。一般的な制御でも広く用いられており、ライブラリなどがかなり充実していることや調べてもすぐに情報が出ることから扱いやすい制御であるといえます。ゲインを適切に設定することで高速な動作が実現できます。しかしゲインの設定が甘いと発振を起こしますし、ゲインの設定にはいくつかの注意点があります。
ゲインチューニング
PIDに限らず、ゲインというのは値の範囲が決まったものではありません。モータのスペック、減速比、重量、慣性、エンコーダの分解能など様々な要因で大きく変化し、100が適切な値の場合もあれば0.01が適切な値の場合もあります。またマイコンの制御周期が早すぎることで発振を起こす場合もあり、今のロボットの状態や特性を見て様々なパラメータを試すことが必要です。
基本的にはPゲインを最初に試し、ほかのゲインは初め0にします。一般にDゲインはPゲインの10分の1程度が多いのでそのあたりを基準にDゲインも設定し、ある程度高速な動作を目指すならPゲインをさらに強めます。Iゲインは基本大きな値を設定しません。場合によっては0でも構わないです。
ロボットでのPID
アルディーノでPIDを実際に使う際は、以下のような感じの書き方をします。
double kp = 1.0;
double ki = 0.1;
double kd = 0.01;
double integral = 0;
double prev_error = 0;
unsigned long prev_time = 0;
double target = 100;
void setup() {
Serial.begin(9600);
}
void loop() {
double current = readSensor(); // センサ値
unsigned long now = millis();
double dt = (now - prev_time) / 1000.0;
prev_time = now;
double error = target - current;
integral += error * dt;
double derivative = (error - prev_error) / dt;
double u = kp * error
+ ki * integral
+ kd * derivative;
prev_error = error;
motorOutput(u);
}
ただ自分でこんな書かなくても様々な機能が入ったライブラリもありますし、このコードはAIに書かせましたが同じようにchatgptにでも書けと言えばごく簡単なPIDなら実装できます。なのでどちらかといえばコーディングの側面でなく、使い方みたいな部分を理解すべきだと思います。ちなみに私は全く理解せずに使ってて非常に痛い目を見ました。さぼらずに勉強するようにしましょう。また、このコードでは毎回dt(時間の間隔)を計算していますが、ロボコンの現場では一定の間隔(例えば1msごと)で正確にこの計算を繰り返す定周期実行が重要になります。計算のタイミングがバラバラだと、微分も積分も値が狂ってしまうからです。
実際ロボットに組み込むとして、例えば慣性などはある程度事前にわかってると思います。そういう部分をPIDで制御するのは面倒で、かつPIDはずれを見て直す関係で遅れが出たり、様々な問題が発生します。その為フィードフォワードと組み合わせて使うような使用方法が一般的です。またロボットの特性などでどうしても発振を起こす場合は次に説明するフィルタを使用したりします。
フィルタについて
フィルタっていうとどんなものかイメージつきますか?すごく単純に言えばエアコンについてるものと大差はないです。つまりは入力された値に対して、一様に処理を加えるものをフィルタといいます。一般にノイズを除去するために使用されますが、制御の分野でも使用されます。
ノイズについて
ある程度イメージわくかもですが、例えば加速度センサ、あれの中身は簡単に言うとばねの先端に鉄球がついてて、その縮みを測ってるような感じです。だから中で振動を起こしてふらふらしたりなどで、得られる数値はギザギザの形になります。あとはアナログで信号を送るようなセンサでも、電源電圧の微細な動きなどは全部そのままマイコンに伝わります。これらはすべてノイズになり、ロボットの正確な動きを阻害します。これらを何とかするために、フィルタは使用されます。
ローパスフィルタ
名前の通り、低い周波数を通し高い周波数をカットするフィルタです。つまりはノイズによって発生する細かなギザギザを除去する役割があります。PIDの出力部分などにも使用されます。
移動平均フィルタ
過去n回分の平均をとって、それを入力として扱うフィルタです。非常に簡単なフィルタで、突発的に大きな異常値が出る場合に有効です。
ノッチフィルタ
特定の周波数域だけを抑制するフィルタです。ロボットなどには共振周波数というものがあり、その周波数域に入ると発振してしまう、ということがよくあります。ノッチフィルタをかけることで共振周波数を抑制し、発振を抑えることができます。その為PIDと合わせてよく使用されます。
カルマンフィルタ
プログラム上でロボットの物理モデルを立て、それにより予測した値とセンサからの値を組み合わせるフィルタです。非常に複雑で、かつロボットの様々な性質を把握する必要がありますが、非常に強力なフィルタです。
フィルタの問題
ここまで書いた内容を見ると、フィルタというのは万能なように思えるかもしれません。ですがフィルタには避けられない問題があり、それはフィルタを強くかけるほど遅れが発生するということです。ローパスフィルタが一番わかりやすいですが、ローパスと一次遅れは数式的に完全に同じです。移動平均などもわかりやすいでしょう。平均化するためには何回分かの数値を保存する必要があるので、つまりはnを大きくするほど鈍くなるということです。フィルタをかけ、きれいな値が得られればいいというものではなく、適切な割合を考えて使用する必要があります。
行列について
行列って聞いたことありますか?分類としては大学数学に入るものなんですが、ロボットの分野ではかなり頻出のものです。さわりだけならそう難しいものではないので、制御に取り組むために学んでみましょう。
なぜ行列を使うのか
行列ってのは基本的には新しい概念を持ってくるような、ないと成立しない概念というよりは数字の新しい表し方、みたいなものです。だったら普通の数字で計算しろと思うかもですが行列を使うことには様々なメリットがあります。例えばロボットを制御するとき、基本的には指定した座標に動く位置制御を行います。例えば直交座標アームのように、x、y、zに各軸が直接対応していれば計算は簡単です。しかし円筒座標系アームのように、座標に直接対応しない軸が存在する場合には座標に表現しなおす必要がありますよね。そういった場合に行列が用いられます。行列は
\begin{eqnarray}
\left(
\begin{array}{cc}
a & b \\
c & d
\end{array}
\right)
\end{eqnarray}
みたいな形で表現でき、ここに数値をまとめることで計算を集約できます。細かい内容がわからないと計算はできないですが一年のしょっぱなから習うと思うので計算自体はそこで学んでください。
運動学モデル
ロボットを制御するために座標を計算する、と先ほど言いましたが、運動学モデルというのはそういったロボットの軸と座標の関係を式にしたものです。
順運動学
軸の角度から座標を求めるモデルを順運動学モデルといいます。ロボットにおいてはエンコーダなどから得た値をもとに現在座標を求めたりもしますが、基本的には次の逆運動学モデルのほうが使われます。
逆運動学
目標座標から軸の角度を求めるモデルです。これを使うことによって、例えば(10,20,30)の座標に動かしたいとき、それぞれの軸やモータの適切な角度、回転数などを算出できます。基本的には順運動学モデルを立て、そこから逆算されることが多いですがたいていのロボットであれば調べればモデルは出ます。代表的なものをいくつか紹介します。
車輪ロボットのモデル
私が想定する一番の読者、先端小型の人はキャチロボがメインなので車輪を用いたロボットは作らないかもしれませんが、運動学モデルについて理解するのには便利なので解説します。ここに書いてる形は教科書とかに乗ってるような公式の形ですが、実際にはタイヤの直径とかの係数が必要になります。
四輪ロボット
四輪ではありますが実質的には対向二輪型として扱います。
$v_L$、$v_R$が左右のタイヤの速度、$v$が機体の速度、$\omega$が旋回速度、$d$は左右のタイヤ間の距離、つまりトレッドの半分です。
こういう車体が車体の中心位置で回転することを超信地旋回といいます。
\begin{eqnarray}
\left(
\begin{array}{c}
v_L \\
v_R
\end{array}
\right)
=
\left(
\begin{array}{cc}
1 & -d \\
1 & d
\end{array}
\right)
\left(
\begin{array}{c}
v \\
\omega
\end{array}
\right)
\end{eqnarray}
3輪オムニ
オムニホイール自体知らないという人もいるかもですね。オムニホイールとは車輪の円周上に小さな樽型のフリーローラーが配置された特殊なホイールです。真横に移動することができる点が最大の特徴で、四輪でなく車体を120°間隔で囲うように配置した三輪でも全方向に動くことができます。
$v_1$、$v_2$、$v_3$が各タイヤの速度、$v_x$、$v_y$がx、y方向の速度で$R$は機体中心から各タイヤまでの距離です
\begin{eqnarray}
\left(
\begin{array}{c}
v_1 \\
v_2 \\
v_3
\end{array}
\right)
=
\left(
\begin{array}{ccc}
-1 & 0 & R \\
1/2 & -\sqrt{3}/2 & R \\
1/2 & \sqrt{3}/2 & R
\end{array}
\right)
\left(
\begin{array}{c}
v_x \\
v_y \\
\omega
\end{array}
\right)
\end{eqnarray}
4輪メカナム
メカナムホイールもオムニと同じような特殊なホイールで、同じく真横方向への移動が可能なものです。
$L$は中心からタイヤまでの前後距離、$W$が左右距離です。
\begin{eqnarray}
\left(
\begin{array}{c}
v_1 \\
v_2 \\
v_3 \\
v_4
\end{array}
\right)
=
\left(
\begin{array}{ccc}
1 & -1 & -(L+W) \\
1 & 1 & (L+W) \\
1 & 1 & -(L+W) \\
1 & -1 & (L+W)
\end{array}
\right)
\left(
\begin{array}{c}
v_x \\
v_y \\
\omega
\end{array}
\right)
\end{eqnarray}
アームロボットのモデル
本題のアームロボットです。ここに書くのはよくある代表的なものですが実際には様々なアームロボットがあり、軸配置もまた様々です。それらに合わせた形を立てる必要があります。
直交座標系アーム
各軸が各座標に対応しているのでまあ立てるまでもないくらいのものです。$d_x$、$d_y$、$d_z$がそれぞれの軸の移動量です。
\begin{eqnarray}
\left(
\begin{array}{c}
x \\
y \\
z
\end{array}
\right)
=
\left(
\begin{array}{ccc}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1
\end{array}
\right)
\left(
\begin{array}{c}
d_x \\
d_y \\
d_z
\end{array}
\right)
\end{eqnarray}
円筒座標系アーム
直交の軸と中心の旋回軸を併せ持ったアームです。$r$が半径方向の伸び、$z$が高さ、$\theta$が旋回角度です。
\begin{eqnarray}
\left(
\begin{array}{c}
x \\
y \\
z
\end{array}
\right)
=
\left(
\begin{array}{c}
r \cos \theta \\
r \sin \theta \\
z
\end{array}
\right)
\end{eqnarray}
多関節アーム
アームロボットといって一番思い浮かぶ形状です。軸数がほかのアームロボットに比べ多くなりやすく、また一つの座標に対しても複数の姿勢が存在すること、動かすことができない地点があることから特異点回避と呼ばれるプロセスが必要になることから、制御が難しいアームであるといえます。ここに書く式では基本的な3つの軸しか計算に入れてませんが、これでは手先の向く方向が制御できません。ワークをつかむことを考えたらあと2つ、理想的には3つの軸が必要になります。$\theta_1$~$\theta_3$が各軸の角度、$l_1$~$l_3$が各リンクの長さです。
\begin{eqnarray}
\left(
\begin{array}{c}
x \\
y \\
z
\end{array}
\right)
=
\left(
\begin{array}{c}
(l_1 \cos \theta_2 + l_2 \cos (\theta_2 + \theta_3)) \cos \theta_1 \\
(l_1 \cos \theta_2 + l_2 \cos (\theta_2 + \theta_3)) \sin \theta_1 \\
l_1 \sin \theta_2 + l_2 \sin (\theta_2 + \theta_3)
\end{array}
\right)
\end{eqnarray}
ロボコンでの制御について
理論的な部分だけわかってても実際に実装するのではまた話が変わってきます。現実に存在するロボットを制御するうえでかかわってくる部分というのは多岐にわたり、ノイズとかはすでに書いたので他に私が実際困ったこととかを書きます。
サンプリング周期について
理論上、制御を行う周期は早ければ早いほどいいですが、現実にはマイコン、センサ、escなどには限界があります。マイコンでは早いものだと1Mhzなどの周期で制御をまわすことができますが、こういった要素が発振に繋がることもあり、実際私も直面しました。使用する機器の処理速度や回路のコンデンサ特性、計算に入れていない微細なデッドタイムなどが存在するため、ある程度抑えた制御周期を設定する必要があります。
モータの分解能について
タイミングベルトなどを使い、バックラッシなくメカを組んだとしても、完全に角度を合わせることは不可能です。なぜならモータ、そしてそこに取り付けられたエンコーダには分解能の限界があるからです。それらをより細かくするには減速機を組む必要がありますが、ギアやタイミングベルトを使えばバックラッシや遅れがどうしても発生します。つまりは使用するモータなどによって可能な精度というのはある程度限界が存在します。たいていのロボコン、少なくともキャチロボではそこまでの精度が求められる場面は少ないため、ある程度現実的に可能な範疇の精度を目指すようにしましょう。ロボマスモータとかの高性能なモータ使ってればほぼこの問題は発生しません。主にサーボモータみたいなものでの話ですかね。
人力PIDについて
私が2026キャチロボで実際にやらかしたのですが、制御が大会本番に間に合わず、苦肉の策で行った対処法です。要はほぼ全く制御を組まずに操作し、操縦者の感覚のみで目標位置にアームを動かす方法です。正直言ってゴミみたいな方法ではありますが、動かない機体で大会を迎えるよりはるかにマシな方法です。そして非常に効果的でもあります。現に私たちはこの方法でベスト16にまで入ることができてます。操縦者には大きな負担がかかりますし、当然確実性もクソもないので推奨は全くできません。可能な限り大会期間に制御が間に合うようスケジュールを組むべきですが、緊急時の対処法としてはこういう方策もあります。
メカの話
制御とメカは切っても切り離せないものです。というかロボコンという競技においてすべての分野は深くかかわってきます。私がメカの人間ということもあるので、制御にかかわってくるメカの話を書いていこうと思います。
ギアについて
ギアは設計から考えると動力を思った位置に配置したり、モータトルクを増強できたりと夢のようなものですが、制御から見たら悪夢のようなものかもしれません。ギアを使えばバックラッシが出ます。重ねれば重ねるほどそれは大きくなり、デッドタイムが発生することで制御が難しくなること、またバックラッシが大きくなれば制御ではどうにもならないがたつきが発生することになります。またシャフトのたわみやプラ、3Dプリントのギアなどの伸縮により弾性特性を持つことにもつながります。高精度な制御をしたいのであればあまり使わない、あるいは剛性的な対策を十分に組む必要があります。
慣性について
ロボットは"動く"ものなので、当然慣性が生まれます。制御するうえで慣性は可能な限り小さいほうがいいもので、そのためには重心配置に気を使う必要があります。つまりは回転中心に重心があれば慣性は小さくなるので、可能な限りそういう重心配置を目指すべきだということです。また重心の位置だけでなく、単に軽くすることも非常に効果的です。ロボット全体の軽量化、可動部の重量低減などは制御性の向上においてとても効果的に働きます。
リミットスイッチについて
モータについたエンコーダなどはモータの鉄心、つまりは一番高速で動く部分に取り付けられている場合が多いです。その為減速機込みで考えれば非常に高精度に動作するわけですが、エンコーダには回転回数を測る機能が備わっていないという問題があります。インクリメンタルエンコーダが使われていれば鉄心が一回転する範囲では角度がわかりますが、減速機を通じて出力される以上出力軸が一周するまでにエンコーダは何度も回転することになり、自己位置はほぼわからなくなります。エンコーダが一周するたびにカウントしたりすることでこの問題を解決するのですが、動作する中でずれが生じたり電源をつけていない間の動きで様々な問題が発生したりします。
この問題に対する対処法は様々ありますが、よくある方法は出力軸にもエンコーダをつける方法とリミットスイッチを使用する方法です。個人的にはエンコーダはちょっと面倒なのでリミットスイッチをお勧めします。
おわりに
長々と書いてますがはっきり言って大した内容は書いてないです。まあ私が制御に全く明るくなく、大したことが言えないというのが大きいですが、制御という分野がそれだけ奥深いものだということでもあります。そして制御班として活動する人にはこれらの知識に加えコーディングスキルも求められるわけです。しかも制御はメカが完成しないと手が付けられない領域でもあります。制御はおそらく一番大変な分野だと思います。ですがロボットを動かすうえで必ず必要になる要素なので、やる気と根気をもって勉強していきましょう。私も最近は趣味のロボットを制御するため勉強中です。一緒に頑張りましょう。