趣味で作るロボット用ソフトウェア
ルンバの制御について

概要

ルンバは iRobot 社 が販売している家庭向けの掃除ロボットです。
iRobot 社がルンバを制御するための通信プロトコルを公開していることもあり、多くの有志がルンバを改造して楽しんでいるようです。ルンバを改造したり、自分のソフトウェアを動作させてして楽しむことを、ルンバ・ハック (Roomba Hack) と呼ぶそうです。

ルンバをハックするための資料は、下記サイトにあります。

このプロジェクトでは、ルンバを実験用のロボット台車として利用します。
ルンバを用いる理由としては

などが挙げられます。

ハックの手順

以下が、このプロジェクトでルンバをハックする手順です。

  1. シリアルのコネクタを覆っているカバーを外す
  2. PC とルンバを接続するためのケーブルを作成する
  3. 作成したケーブルを接続し、通信できるかを確認する
  4. 利用したいルンバの機能をテストし、制御ライブラリを作成していく

シリアルのコネクタを覆っているカバーを外す

シリアル接続を行うコネクタは、カバーに隠されています。まずは、これを外します。

roomba_cover_before.jpg
カバーがあるとき
roomba_cover_after.jpg
カバーを外したとき

カバーは、外周側の4つの爪と内周側を押し込むことで固定されています。
カバーを外すときは外周側の爪を外し、割り箸のようなものや長めのマイナスドライバを差し込み、こじるようにして内周側の固定を外していくとよいと思います。取り付けは割としっかりされているので、カバーを取り外すには結構な思いきりや勇気が必要です。

カバーを外すと、真ん中のボタンの右側にシリアル接続用のコネクタがあります。

roomba_connector_zoom.jpg
ルンバのコネクタ

PC とルンバを接続するためのケーブルを作成する

ルンバとのシリアル接続は 5V の TTL 接続で行います。そのため、通常のシリアル端子とルンバを直に接続することはできません。
今回は FTDI 社の USB-Serial 変換チップ FT232RL の評価基板を用いて PC と接続するためのケーブルを作成します。ルンバの RXD, TXD, GND を接続すれば通信できます。

dot_inline_dotgraph_1.png

作成したケーブルを接続し、通信できるかを確認する

作成したケーブルを用い、実際に PC からルンバにコマンドを送信してケーブルの動作を確認します。まずは PC からの送信が動作するかの確認のために、ルンバに音を鳴らせてみます。

ルンバとの通信プロトコルの詳細は参考文献から確認できます。
以下は C++ と Lua 版の音を鳴らすプログラムです。

ルンバで音を鳴らせるプログラム (C++)

/*
  ルンバに音を鳴らせる

  \author Satofumi Kamimura

  $Id$
*/

#include "Serial.h"
#include <string>
#include <iostream>

using namespace hrk;
using namespace std;


int main(int argc, char *argv[])
{
    static_cast<void>(argc);
    static_cast<void>(argv);

    Serial serial;
    enum { Roomba_default_baudrate = 115200 };
    if (!serial.open("/dev/ttyUSB0", Roomba_default_baudrate)) {
        cout << "Serial::open(): " << serial.what() << endl;
        return 1;
    }

    const char send_command[] =
        "\x80\x80"
        "\x8c\x0\x1\x43\x20"
        "\x8d\x0";

    serial.write(send_command, sizeof(send_command) - 1);

    return 0;
}

ルンバで音を鳴らせるプログラム (Lua)
libs/robot/example/roomba.cpp を利用します。

-- ルンバに音を鳴らせる
--
-- Satofumi Kamimura
--
-- $Id$


local serial = Serial()
local Roomba_default_baudrate = 115200
if not serial:open("/dev/ttyUSB0", Roomba_default_baudrate) then
   print("Serial::open(): " .. serial:what())
   return 1
end

local send_command = "\128\130" .. "\140\000\001\067\032" .. "\141\000"
print(#send_command)
serial:write(send_command, #send_command)

実行方法

% ./roomba play_roomba.lua 

ここまでで、PC からルンバへの送信が確認できました。
次は、受信のテストを兼ねてルンバのバッテリー情報を取得してみます。

ルンバのバッテリー情報を取得するプログラム (C++)

/*
  ルンバのバッテリー情報を取得して表示する

  \author Satofumi Kamimura

  $Id$
*/

#include "Serial.h"
#include <string>
#include <iostream>

using namespace hrk;
using namespace std;


int main(int argc, char *argv[])
{
    static_cast<void>(argc);
    static_cast<void>(argv);

    Serial serial;
    enum { Roomba_default_baudrate = 115200 };
    if (!serial.open("/dev/ttyUSB0", Roomba_default_baudrate)) {
        cout << "Serial::open(): " << serial.what() << endl;
        return 1;
    }

    const char send_command[] =
        "\x80\x82"
        "\x15";

    serial.write(send_command, sizeof(send_command) - 1);

    enum {
        Receive_size = 1,
        Timeout = 100,
    };
    unsigned char receive_data;
    int n = serial.read(reinterpret_cast<char*>(&receive_data),
                        Receive_size, Timeout);
    if (n != Receive_size) {
        cout << "receive data failed." << endl;
        return 1;
    }

    string message;
    switch (receive_data) {
    case 0:
        message = "0 Not charging";
        break;

    case 1:
        message = "1 Reconditioning Charging";
        break;

    case 2:
        message = "2 Full Charging";
        break;

    case 3:
        message = "3 Trickle Charging";
        break;

    case 4:
        message = "4 Waiting";
        break;

    case 5:
        message = "5 Charging Fault Condition";
        break;

    default:
        message = "invalid receive data.";
        break;
    }

    cout << message << endl;

    return 0;
}

ルンバのバッテリー情報を取得するプログラム (Lua)
libs/robot/example/roomba.cpp を利用します。

-- ルンバのバッテリー情報を取得して表示する
--
-- Satofumi Kamimura
--
-- $Id$


local serial = Serial()
local Roomba_default_baudrate = 115200
if not serial:open("/dev/ttyUSB0", Roomba_default_baudrate) then
   print("Serial::open(): " .. serial:what())
   return 1
end

-- !!! not implemented
local send_command = ""
print(#send_command)
serial:write(send_command, #send_command)

-- !!! receive battery status information

実行方法

% ./roomba battery_state_roomba.lua 

利用したいルンバの機能をテストし、制御ライブラリを作成していく

ここまでで、PC とルンバの動作が確認できました。
以降は、別ページにてルンバの走行系やバンパなどの機能を試すためのプログラム作成を行っていきます。ルンバでは、以下の機能を利用できます。

このプロジェクトでは、ルンバを移動ロボットとして走行させることを目的にしています。また、一応は掃除機としても利用したいと思っています。そのため、走行まわり、掃除、バッテリー、などの機能について、ソフトウェアのライブラリを作成していきます。

参考文献

 All Classes Files Functions Variables Enumerations Enumerator Friends