環境
この記事は以下の環境で動いています。
項目 | 値 |
---|---|
CPU | Core i5-8250U |
Ubuntu | 16.04 |
ROS | Kinetic |
PlatformIO | 3.6.0 |
インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。
概要
ロボットの下回りの特にアクチュエーターは自作をする必要があるのが現状です。今回はmbedを用います。Arduinoほどはメジャーではありませんが、Arduinoで使われるAVRよりもIOなどの性能が高いARMベースのコアを使ったマイコンプラットフォームです。この記事では
- カスタムmbedボードの作り方
- mbed用のソースコードのオフラインでのビルド
- カスタムmbedに書き込む方法
- mbedでrosserialを使う方法
を説明します。
カスタムmbedボードの作り方
青mbedが一番メジャーですが、ロボット用としては自分で基板を起こしたくなります。そんな時はICだけを買って自分で基板を作りましょう。
接続 | ピン番号 |
---|---|
3.3V | 10, 12, 19, 28, 42, 54, 71, 84, 96 |
GND | 11, 15, 31, 41, 55, 72, 83, 97 |
水晶 | 22, 23 |
リセットIC | 17 |
書き込みにはシリアル通信を使います。USBシリアル変換を使うとよいです。RTSとDTRはリセット&bootモードに入る設定を行うものです。
USBシリアル | LPC1768 |
---|---|
TxD | 99 |
RxD | 98 |
RTS | 53 |
DTR | 17 |
mbed用のソースコードをオフラインでのビルド
platformioを用いてビルドをすることができます。platformio boards|grep lpc1768
でplatformioでlpc1768が対応推しているか見れます。(結果はlpc1768 LPC1768 96MHz 512KB 64KB NXP mbed LPC1768
ともう一行出る)
roscd hard_lecture/platformio/mbed01 #プロジェクトのディレクトリに移動
platformio init -b lpc1768
ソースコードを編集します。これのプログラムはオンラインのコンパイラと同様に書けます。
#include "mbed.h"
#define SRSG_LED0 P0_16
#define SRSG_TX0 P0_2
#define SRSG_RX0 P0_3
DigitalOut l0(SRSG_LED0);
Serial pc(SRSG_TX0,SRSG_RX0);
int main() {
pc.baud(1000000);
while (true) {
l0 = !l0;
wait(500);
pc.printf("hellow mbed!\n");
}
}
最後にコンパイルです。
platformio run
これでhard_lecture/platformio/mbed01/.pioenvs/lpc1768/firmware.bin
にビルド済みのバイナリが生成されます。
カスタムmbedに書き込む方法
通常のmbedならplatformioでuploadオプションを付けると自動でダウンロードしてくれますが、カスタムmbedではそうはいきません。lpc21isp
で書き込みを行います。
sudo apt-get install lpc21isp
/dev/ttyUSB0
にカスタムmbed用のライターがついているとします。
roscd hard_lecture/platformio/mbed01/.pioenvs/lpc1768/
sudo lpc21isp -control -bin firmware.bin /dev/ttyUSB0 115200 12000
わざわざ別のコマンドを打つのは面倒ですので、すべてplatformio run
でやってくれるように設定を変えましょう。
[env:lpc1768]
platform = nxplpc
board = lpc1768
framework = mbed
targets = upload # デフォルトで書き込みを行う
extra_scripts = pre:lpc21isp_script.py # カスタム書き込みコマンドのロード
upload_protocol = custom # 標準ではなくカスタムの書き込みを行う
upload_port = /dev/ttyUSB0 # 書き込み先のポートの設定
以下のファイルを追加します。
Import("env")
print("load lpc21")
env.Replace(
UPLOADCMD="lpc21isp -control -bin $SOURCE $UPLOAD_PORT 115200 12000"
)
これでplatformio run
でコンパイルから書き込みまですべてをおこなえます。
mbedでrtosライブラリを使う
強力なmbedのライブラリとしてrtosがあります(逆にこれがないとプログラムがだいぶ難しい)。これは標準の設定だとplatformioでは使えません。
#include "mbed.h"
#include "rtos.h"
#define SRSG_LED0 P0_16
#define SRSG_LED1 P0_15
#define SRSG_LED2 P0_17
#define SRSG_LED3 P0_18
DigitalOut l0(SRSG_LED0);
DigitalOut l1(SRSG_LED1);
DigitalOut l2(SRSG_LED2);
DigitalOut l3(SRSG_LED3);
void blink1(void) {
while (1) {
l1=!l1;
Thread::wait(1000);
}
}
void blink2(void) {
while (1) {
l2=!l2;
Thread::wait(1000);
}
}
int main() {
Thread thread1;
thread1.start(blink1);
Thread thread2;
thread2.start(blink2);
while (true) {
l0 = !l0;
Thread::wait(500);
}
}
この状態でplatformio run
をするとエラーになります。設定ファイルに書き加える必要があります。
[env:lpc1768]
platform = nxplpc
board = lpc1768
framework = mbed
build_flags = -D PIO_FRAMEWORK_MBED_RTOS_PRESENT #この行を追加
これでplatformio run
のビルドが通ります。
mbedでrosserialを使う方法
platformioワークスペースの作成
面倒なのでmbed01をコピーしてmbed03にします。
ライブラリの生成
ライブラリの生成のために以下が必要になります。
sudo apt-get install ros-kinetic-rosserial-mbed
以下のコマンドで生成します。ライブラリは<platformioワークスペース>/lib
に入れます。
roscd hard_lecture/platformio/mbed03/lib/
rosrun rosserial_mbed make_libraries.py ./
ros_lib以下には多数のファイルディレクトリが生成されます。ファイルは全て必要ですが、ディレクトリはBufferedSerial
、ros
、rosserial_msg
、ソース中でincludeしているパッケージ以外は消去しても構いません。
ソースコード
文字を1秒単位でpublishする、msgをsubscribeするとLEDが点灯するというものです。LEDハP0_16につながっているとします。
#include <mbed.h>
#include <ros.h>
#include <std_msgs/Empty.h>
#include <std_msgs/String.h>
DigitalOut led = P0_16;
ros::NodeHandle nh;
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);
void messageCb( const std_msgs::Empty& toggle_msg) {
led=1;
wait(0.2);
led=0;
}
ros::Subscriber<std_msgs::Empty> sub("led", &messageCb );
int main() {
nh.getHardware()->setBaud(115200);
nh.initNode();
nh.advertise(chatter);
nh.subscribe(sub);
while (1) {
str_msg.data = "hello world!";
chatter.publish( &str_msg );
nh.spinOnce();
wait_ms(1000);
}
}
コンパイル&書き込み
roscd hard_lecture/platformio/mbed03/lib/
platformio run
実行
どうやらubuntuのデフォルトのUSB設定ではRST、DTRの設定のせいでこれらをlpc1768とつないでいると、通常の起動時でもbootモードに入って動かなくなってしまいます。動作時はこの2本の信号は物理的に切り離す必要があります。
roscore
rosrun rosserial_python serial_node.py _port:=/dev/ttyACM0 _baud:=115200
これでrostopic list
で/chatter
と/led
が見えます。後は普通のrosと同じように使うことができます。
参考
platformioでmbedを使う
lpc21isp
bin->hex変換ツール?
mbedシリアル書き込み
platformio mbedオプション
rosserial mbed