9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ROS講座96 カスタムmbedでrosserial+platformioを使う

Last updated at Posted at 2019-03-23

環境

この記事は以下の環境で動いています。

項目
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

lpc1768.png

書き込みにはシリアル通信を使います。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

ソースコードを編集します。これのプログラムはオンラインのコンパイラと同様に書けます。

hard_lecture/platformio/mbed01/src/main.cpp
#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で書き込みを行います。

lpc21ispのインストール
sudo apt-get install lpc21isp

/dev/ttyUSB0にカスタムmbed用のライターがついているとします。

lpc21ispの書き込み
roscd hard_lecture/platformio/mbed01/.pioenvs/lpc1768/ 
sudo lpc21isp -control -bin firmware.bin /dev/ttyUSB0 115200 12000

わざわざ別のコマンドを打つのは面倒ですので、すべてplatformio runでやってくれるように設定を変えましょう。

hard_lecture/platformio/mbed01/platformio.iniに追加
[env:lpc1768]
platform = nxplpc
board = lpc1768
framework = mbed

targets = upload                        # デフォルトで書き込みを行う
extra_scripts =  pre:lpc21isp_script.py # カスタム書き込みコマンドのロード
upload_protocol = custom                # 標準ではなくカスタムの書き込みを行う
upload_port = /dev/ttyUSB0              # 書き込み先のポートの設定

以下のファイルを追加します。

hard_lecture/platformio/mbed01/lpc21isp_script.py
Import("env")

print("load lpc21")

env.Replace(
    UPLOADCMD="lpc21isp -control -bin $SOURCE $UPLOAD_PORT 115200 12000"
)

これでplatformio runでコンパイルから書き込みまですべてをおこなえます。

mbedでrtosライブラリを使う

強力なmbedのライブラリとしてrtosがあります(逆にこれがないとプログラムがだいぶ難しい)。これは標準の設定だとplatformioでは使えません。

hard_lecture/platformio/mbed02/src/main.cpp
#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をするとエラーになります。設定ファイルに書き加える必要があります。

hard_lecture/platformio/mbed02/platformio.ini
[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以下には多数のファイルディレクトリが生成されます。ファイルは全て必要ですが、ディレクトリはBufferedSerialrosrosserial_msg、ソース中でincludeしているパッケージ以外は消去しても構いません。

ソースコード

文字を1秒単位でpublishする、msgをsubscribeするとLEDが点灯するというものです。LEDハP0_16につながっているとします。

hard_lecture/platformio/mbed03/src/main.cpp
#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本の信号は物理的に切り離す必要があります。

1つ目のターミナル
roscore
2つ目のターミナル
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

目次ページへのリンク

ROS講座の目次へのリンク

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?