----------------------------------------------------------------
Hotal プログラム仕様
2022年1月10日から
例 https://drone-ai.blogspot.com/2022/03/blog-post_30.html
----------------------------------------------------------------
(1)プログラムはステートメント(命令文)の並びから構成される。ステートメントは1行に書かれ、複数の行にまたがることはできない。ステートメントの塊はブロックである。ブロックは、それを一つのプログラムとして実行できる。ただし、空行は無視される。1行の中に'#'があると、それも含めそれより右側の記述は無視される。インデントは、空白で行われることが前提である。
(2)実行可能ステートメントは1行から成り立ち、loop、if、マクロを除き、順に実行される。
1,代入文:変数 = 式(評価される、演算子と変数、値を返す関数から成立している)
2,if文
3,loop文
4,関数(実行される)
5.マクロ
のいずれかである。
(3)数値
数値はすべて倍精度数で把握される。小数は小数点を使って表される。浮動小数点は正しく処理されない。
(4)変数
変数は、$から始まる文字列でなければならない。$以降は、アルファベット、数字、'_'アンダーラインのいずれかでなければならない。文字列を変数に入れることはできない。値は全て倍精度である。
例. $abcdef, $e123, $abc_d123 など
変数は、最初に現れたところで定義される。同じものが再定義されると、値が無条件に上書きされる
(5)関数
関数は、'^'で始まり、名前、引数をつなげたものである。引数は '('と')'に挟まれる。実引数がない場合も'()'が必要である。関数名は変数名の規則に準じる。引数が複数ある場合は、カンマで区切る。関数は、値を返す機能と機体に関わる何らかの動作を実行するものとがある。また、その両方の場合もある。
(注1) 複数の値を返す関数(getPropellaRpmなど)は、その関数自体は値を返さない(ゼロが返される)が、実行後に、その関数名に '_0', '_1', '_2',・・・がついた一連の変数に値が保存される。次に実行されるときには、上書きされてしまう。持続的に使いたい場合は、それまでに別な名前の変数に代入、保存しておくなどの処理が必要。配列を返す関数が代入文の左辺にある場合、その値はゼロになってしまう。
(6)マクロ
マクロは、プログラムの中(位置はどこでも良い)で定義され
defmacro マクロ名
の行から始まり
endmacro
の行で終わっているブロックである。その部分は、メインの実行行には含まれず、無視される。マクロを呼び出すには、
@マクロ名
と書いた行をメインプログラムの中に置くことにより、その位置でマクロ全体が実行される。何度呼び出されてもよい。マクロの内容は通常の実行ブロックと同じである。変数も、名前空間はないので、同じ名前の変数は、メインと共通になる。変数を区別するためには、変数名の頭にマクロ名をつけるなどの工夫が必要になる。マクロの中で、再帰的にそのマクロを呼び出してもよいが、マクロの中で同じ、あるいは別のマクロを定義してはならない。マクロを正常に呼び出すことができなくなる。
(7)if文
if文は、ステートメントを空白で分解したときに最初にifが記載され、次に論理式が現れるものである論理式が真の場合は、対応するendifか対応するelseのいずれか最初に現れたところまでが実行される。論理式が偽の場合は対応するendifの前に、対応するelseがあれば、そのelseからendifまでが、実行される。elseがなければ、endif以降のブロックの実行に移る。
(8)論理式
論理式は ==, <=, >=, <, >, !=の演算子を持ち。両辺いずれも式として評価され、数値的値の比較が行われ、真偽が判定される。論理式は、現状では単独でしか評価できない。いずれ、論理式も評価できるようにしたい。
(9)loop文
loop文は、ステートメントを空白で分解したときに、最初の項がloopであるもの。続いて、論理式が与えられる。論理式が真である限り、対応するendloopのステートメントまでが繰り返される。論理式が偽になったばあいは、endloopの次のステートメントからの実行に移る。
(10)今の段階で、実行、評価が可能な関数(今後さらに拡張される)
^throttle():
スロットルレベルを指定する。引数にスロットルレベル(%)を与える。0が最小。100は、ESCのキャリブレーションで、MAXで設定された電圧レベルになる。
^sleep():
実行を引数秒だけ中断する。秒は実数(小数可)で与える。
^pidbase():
PIDの基底値を与える(実数)。3つの値をそれぞれ引数とする
^pidscale():
PIDのスケール値を与える(整数)。スケールは、50がちょうど、PIDの規定値と同じになるように調整される。3つの値をそれぞれ引数とする。内部的には倍精度で処理されるが、実際の速度調整時にはまた整数化されて処理。PIDスケールは、configファイルで、一定高度にならないと実行されない設定もあるので注意。
^motorSpeedAjustment():
モータースピードの修正値を与える。引数に四つのモーターの修正値を与える。
^getHight():
その瞬間の高度を整数で取得する。超音波距離センサー HCSR04を使っている
^getAverageHight():
4ループ分の平均高度を得る HCSR04を使っている
^print():
引数の内容を標準出力する。引数は、文字列または変数を+でつなげることができる。変数でなければ、文字列とみなしそのまま出力する。変数は、単独か、+ で区切られていなければならない。
^getTakeoffAltitude():
60センチまでの高度をより正確に取るために使う。倍精度で値を返す。光距離センサーGP2Y0E03を使っている。
^getPropellaRpm():
現在のプロペラ回転数を取得する。変数、getPropellaRpm_0. getPropellaRpm_1. getPropellaRpm_2. getPropellaRpm_3 に自動的に代入される。