marunomaruno-memo

marunomaruno-memo

Lego NXT のプログラミング (NXC) (1)

2008年01月04日 | LEGO
■ Lego NXT ファームウェアを更新

Lego NXT ファームウェアを更新。といっても、もともと入ってい
るものを入れただけ。
1.01 から、1.03 に更新。

BricxCC 3.3 の前提のファームウェアは 1.02 なので、1.01 の場
合は更新する必要がある。現在 (2008-01-03) の最新は 1.05.

[NXT ソフトウェア] - [ツール]メニュー - [NXT ファームウェア
の更新]を選択 - [NXT ファームウェアの更新]ダイアログボックス
が表示
[チェック]ボタンをクリックして、最新のファームウェアを確認し、
あればダウンロード
[ダウンロード]ボタンをクリックして更新を開始


■ C 言語もどきの NXC を使ってプログラミングしてみる。

まだ、NXT は、C/C++ に対応していないみたい。NXC は、NQC の
NXT 版のような感じ。
開発環境として、 BricxCC を使う。


■ BricxCC のインストール

Bricx Command Center 3.3 (BricxCC) のインストール
http://bricxcc.sourceforge.net/nbc/
http://sourceforge.net/project/showfiles.php?group_id=68600&
package_id=67285
(08-01-05 追記)
から、
bricxcc_setup_33718.exe
をダウンロード。

ダウンロードした実行ファイルをダブルクリックして、そのままイ
ンストールする。

NXT に電源を入れて、USB 接続にしておけば、ほとんど設定するこ
ともなく、NXC プログラミングができる。
NXC プログラムは、ほぼ C 言語の感じだが、ちょっとだけ文法が
違う。ロボットを制御するのに適した感じになっている。まず、タ
スクを言語仕様として作ることができる。bool 型も標準仕様。ま
あ、そこら辺の話はおいおいすることにして、参考資料は以下の 2
つ。

Not eXactly C (NXC) Programmer's Guide
Version 1.0.1 b33, October 10, 2007
http://bricxcc.sourceforge.net/nbc/nxcdoc/NXC_Guide.pdf

Programming LEGO NXT Robots using NXC (beta 27 or higher)
(Version 2.1, Apr 9, 2007)
http://bricxcc.sourceforge.net/nbc/nxcdoc/NXC_tutorial.pdf

これらにしたがって、「トライボット」使用するプログラムを作っ
てみた。これだけみると、C言語とほぼ同様で違和感はない。


■ 1秒間前進し、その後1秒間停止、1秒間後退するプログラム

---
/**
 * ForwardAndBackword01.nxc
 * 「トライボット」使用
 * 1秒間前進し、その後1秒間停止、1秒間後退する。
 * @author maruno
 * @version 1.0, 2008-01-03
 * @since 1.0
 */
#include "NXCDefs.h"
task main()
{
    OnFwd(OUT_BC, 75); // BCモーター前進、1000ミリ秒間
    Wait(1000);
    Off(OUT_BC);       // BCモーター停止、1000ミリ秒間
    Wait(1000);
    OnRev(OUT_BC, 75); // BCモーター後退、1000ミリ秒間
    Wait(1000);
    Off(OUT_BC);       // BCモーター停止
}

---

基本的に、動きを設定して、それをどれくらい持続するか、という
ことを Wait 関数でミリ秒を指定する。

ちなみに、NXT ソフトウェアで作った同じ動きをするプログラム。
まあ、ソフトウェアブロックでは、時間待機ブロックを使って作っ
たものが、NXC では、Off 関数 + Wait 関数での実現がいいかどう
かは、これから調査する。

プログラムの作成手順は以下のとおり。
1. ソースを入力 / 編集
2. コンパイル (F5)
3. プログラムのダウンロード (F6)
4. NXT で実行


これらの関数の引数で使っている outputs の定数は、以下のとお
りで、それぞれ、OUT_x の「x」部分がポートの番号をあらわして
いる。「OUT_BC」は、B ポートと C ポートを同時に動かすことを
意味する。
---
OUT_A
OUT_B
OUT_C
OUT_AB
OUT_AC
OUT_BC
OUT_ABC
---


それぞれの関数の仕様 [NXC_Guide]

□ Off
---
Off(outputs) Function

outputs ポートのモータを停止する。

例:
Off(OUT_A); // turn off output A
---

□ OnFwd
---
OnFwd(outputs, pwr) Function

outputs ポートのモータをパワーpwr(-100 ~ 100)で前進させる。

例:
OnFwd(OUT_A, 75);
---

□ OnRev
---
OnRev(outputs, pwr) Function

outputs ポートのモータをパワーpwr(-100 ~ 100)で後退させる。

例:
OnRev(OUT_A, 75);
---

□ Wait
---
Wait(time) Function

タスクを指定ミリ秒数分スリープさせる。
この関数の前にモーターを動かせば、ここで指定したミリ秒間、
モーターがそのまま動き続けることになる。

例:
Wait(1000); // wait 1 second
Wait(Random(1000)); // wait random time up to 1 second
---


■ 500ミリ秒間前進し、その後右に180度曲がるプログラム

---
/**
 * TrunRight01.nxc
 * 「トライボット」使用
 * 500ミリ秒間前進し、その後右に180度曲がる。
 * @author maruno
 * @version 1.0, 2008-01-03
 * @since 1.0
 */
#include "NXCDefs.h"

#define MOVE_TIME 500
#define TURN_TIME 360
task main()
{
    OnFwd(OUT_BC, 75);
    Wait(MOVE_TIME);
    OnRev(OUT_B, 75);
    Wait(TURN_TIME);
    Off(OUT_BC);
}

---

#define で、マクロを定義できるのも C 言語と同じ。

TURN_TIME として、 360 を指定しているが、これでいいかどうか
は疑問。
モーターのパワーなんかとも関係するし、わたしのつくった「トラ
イボット」ではほぼ 180 度反転しているが、参考資料のチュート
リアルでは、90 度と書かれている。まあ、ちゃんと計算したりし
ないとだめ、ということでしょうね。
床の素材にも関係するようである。(08-01-05 追記)


■ NXC 文法

コーディングをするための仕様は、[NXC_Guide] にまとまっている。
これ以降、詳細な説明は後日考えるが、とりあえず、コーディング
できるだけの分を記す。
C 言語でコーディングできることを前提にする。
なお、わたしもはじめての言語で、まだ、ぱら見しかしていないの
で、もしかしたら間違っている箇所があるかもしれないし、推測で
記しているところ(★を補足)があるので、注意されたい。


■ キーワード

---
__RETURN__     char      long      sub
__RETVAL__     const     mutex     switch
__STRRETVAL__  continue  priority  task
__TMPBYTE__    default   repeat    true
__TMPWORD__    do        return    typedef
__TMPLONG__    else      safecall  unsigned
abs            false     short     until
asm            for       sign      void
bool           goto      start     while
break          if        stop
byte           inline    string
case           int       struct
---

■ タスク

C 言語との大きな違いはタスクを作れることでしょう。これには t
ask キーワードを使います。C 言語での入口点は main 関数でした
が、NTC では、main タスクになります。タスクの起動 / 停止は、
start 文 / stop 文を使います。また、priority 文を使ってタス
クの優先順位をつけることもできます。

---
task 名前()
{
    // タスクのコード
}

---


■ 関数

関数は C 言語とほぼ同じです。ただ、inline キーワードを使って、
関数をインライン展開できます。また、safecall キーワードを使
って、この関数の実行を排他的に行うことができます(★)。

---
[safecall] [inline] 戻り値型 名前(引数リスト)
{
    // 関数のコード
}

---

配列を引数とする関数は、関数をアセンブラーで記述する必要があ
ります。 (08-01-18 追記) ★


■ データ型と変数

整数の型は C 言語と同じように使えます。ただし、int は 16 ビ
ットです。
また、string が用意されているのもうれしい限りです。

型名 内容
------------------- -------------------------------
bool 8 bit unsigned
byte, unsigned char 8 bit unsigned
char 8 bit signed
unsigned int 16 bit unsigned
short, int 16 bit signed
unsigned long 32 bit unsigned
long 32 bit signed
mutex 排他制御を行うための型(と思われる。ロッ
クフラグ?)★
string byte 型の配列
struct 構造体
Arrays 配列

bool 型があるので、リテラル true / false もキーワードとして
用意されています。

なお、Arrays は配列ですが、C 言語と同じように
int array[10];
と書くこともできます。

整数リテラルは、通常の 10 進数と、前に 0x をつけた 16 進数で
書くことができます。

string リテラルは二重引用符 (") で囲みます。

なお、NXC には、ポインター型はありません。どうやら、その
まま
int 型や long 型を使うようです。
asm キーワードで、アセ
ンブラーを使って表現するようです (08-01-18 修正)★

また、共用体もないようです。★

構造体は、C++ 形式です。すなわち、typedef しなくても、タグ名
をそのまま構造体名として使えます。 (08-01-18 追記)


■ 演算子

つぎの演算子があります。C 言語と同じですが、abs() と sign()
も演算子に入っています。これ以外は C 言語と一緒です。

---
abs()         絶対値
sign()        符号
++, --        インクリメント、デクリメント
-             単項マイナス
~             ビット否定
!             論理否定
*, /, %       乗算、除算、剰余算
+, -          加算、減算
<<, >>        左シフト、右シフト
<, >, <=, >=  関係演算
==, !=        等価、非等価
&             ビット論理積
^             ビット排他的論理和
|             ビット論理和
&&            論理積
||            論理和
? :           条件演算

---


■ 制御文

□ if 文

if (条件式) 条件式の結果が true のとき実行するボディ

if (条件式) 条件式の結果が true のとき実行するボディ
else そうでないときに実行するボディ


□ switch 文

switch (式) ボディ

case 定数式 :
default :


□ while 文

while (条件式) ボディ


□ do while 文

do ボディ while (条件式)


□ for 文

for (初期値化式 ; 条件式 ; 更新式) ボディ


□ repeat 文

repeat (式) ボディ

C 言語にはない制御文です。式の結果の回数分だけ繰り返します。


---
repeat (10) {
    // 繰り返すコード
}

---

□ until マクロ (08-01-05 追記)

つぎのように定義されています。センサーを使うときによく使いま
す。

#define until(c) while(!(c))


■ プリプロセッサー

□ #include

ヘッダーのファイル名を二重引用符 (") で囲って指定します。
なお、山カッコ(<、>) を使うことはできません。

#include "NXCDefs.h"
はデフォルトで入っているらしいので書かなくても大丈夫みたい。



□ #define

マクロの定義

□ 条件付コンパイル

#ifdef symbol
#ifndef symbol
#else
#endif
#if condition
#elif


□ 連結

##

□ プラグマ

#pragma


基本的な文法事項は以上です。
細かい内容はまた、別途。

また、API についても、いずれまた。


■ 参考文献

[NXC_Guide]
Not eXactly C (NXC) Programmer's Guide
Version 1.0.1 b33, October 10, 2007
http://bricxcc.sourceforge.net/nbc/nxcdoc/NXC_Guide.pdf


[NXC_tutorial]
Programming LEGO NXT Robots using NXC (beta 27 or higher
)
(Version 2.1, Apr 9, 2007)
http://bricxcc.sourceforge.net/nbc/nxcdoc/NXC_tutorial.p
df

以上