Qiita

Robot/ロボット Advent Calendar 2017 に投稿しました

“GNU Octave と 素のMatlab でロボットアームの逆運動学を解いてみる”
というタイトルで投稿しました (Qiita初投稿です).

再急降下法とLM法を使ってロボットアームの逆運動学をとくプログラムを作って見たという話です.
プログラムはGNU Octave と Matlab で書いています.
Matlabについては素のMatlabの機能だけを使用していて各種ツールボックスは使用していません.
衝突回避や関節角リミット回避などは考慮していないので、今後実装してみようと思っています.

Qiita Robot/ロボット Advent Calendar 2017 23日目

C92

コミックマーケットC92に参加しました

でしぷろんは2017年夏にコミックマーケットC92に参加しました.
主に頒布した本は以下の でしぷろノート2冊(Note4 & 5)になります.
新刊となるのはNote5になります.

でしぷろノートNo.5

ノートNo.4で解説した4脚ロボットのシステム側を扱う本になる予定でした。
結局電気ハードまで書いたところで力尽きました。。。
BeagleBoneBlackで組んだソフトウェアシステムについては次回以降のノートに記載する予定です.

note005

技術書典

技術書典2 と技術書典 に参加しました

でしぷろんと構成員として技術書典2 (2017/4/9) と超技術書典 (2017/4/30) に参加しました.
頒布した本は以下の でしぷろノート 2冊になります.
Note4の方を主に担当しました.

でしぷろノートNo.3

でしぷろノート No.2を大幅に加筆修正した1冊です.
3Dプリンタ製作のかわさきロボット競技大会むけのロボットに関する内容です.

でしぷろノートNo.4

かわさきロボット競技大会に参加したシリアルリンク4脚ロボットの eV のメカハードに関して記載した本です.

note004

c89

でしぷろんと構成員として2015年冬にコミックマーケットC89に参加しました.
頒布した本は以下の でしぷろノート 2冊になります.
Note1の方を主に担当しました.

詳しくはこちら

note001

note002

khr3_gr001_with_matlab.md

KHR3-HV & GR001 with MATLAB




1.今回の目標

Matlab(2014a)から直接ロボットを制御する.

但し(まずは)

  1. Matlab本体から(Simlinkにはつながない)
  2. 有線接続
  3. 全関節の角度制御のみ

想定するOS

  • Ubuntu Linux (14.04)
  • Windows 8
  • (OSX)

2.方針

以前製作したライブラリrsxを拡張します.




3.拡張例 (C++ と Python)





既にC++とPython向けの拡張行っているので,これと同様に拡張します.
C言語で記述されたdpservoを利用する上位レイヤを用意することで実現します.

4.C言語とMatlabの連携

MatlabからC言語で実装されたライブラリを利用する手段には大きく2通り存在します.

  1. 共有ライブラリをロード&実行する汎用関数を利用する ( *1)
  2. MATLABが読み込める形式の共有ライブラリ(MEXファイル)を作成する ( *2)

1.の方法は特に追加の作業なしにC言語と連携出来ますが、手順が煩雑です。
今回はより利用手順が簡単な2.の方法をとります.

*1 : http://jp.mathworks.com/help/matlab/using-c-shared-library-functions-in-matlab-.html

*2 : http://jp.mathworks.com/help/matlab/ref/mex.html


5.librsxのMEX拡張





こんな感じになります.




MEXファイル1つに付き1関数しか実装出来ないためAPIの数だけMEXファイルを作成します.
また複数のMEXファイルが共通のハードウェアリソース(シリアルデバイス)を使用します.
このままだとAPIを実行する度にそれらの初期化等を行わなければなりません、
これを回避するためにdpsproxyという層を設けています.

6.C言語におけるMATLAB連携(1/2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
* MATLAB連携のためのヘッダファイルを読み込みます.
*/
#include "mex.h"
#include "matrix.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

/*
* 引数の数と型をチェック
* 期待値と一致しない場合にはエラーとする.
*/
if (nrhs < 1 || !mxIsChar(prhs[0])) {
mexErrMsgIdAndTxt(
"dps_proxy:EINVAL",
"dps_assign ics|rsx(string)");
return;
}

/* 次ページに続く */

6.C言語におけるMATLAB連携(2/2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

/* 前ページから */

/*
* 引数の解釈
*/
int num = mxGetNumberOfElements(prhs[0]);
char name[num + 1];
if (mxGetString(prhs[0], name, num + 1) != 0) {
mexErrMsgIdAndTxt("dps_proxy:ERR","");
}

/*
* proxy関数の呼び出し
*/
errno_t eno = dps_proxy_assign(name);

/*
* エラーチェック
*/
if (eno != EOK) {
mexPrintf("The input string is: %s\n", name);
mexErrMsgIdAndTxt("dps_proxy:ERR","");
}

return;
}

7.ビルド手順 Linux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// required package
// -- MATLAB (MEXコンパイラのため)
> git clone https://github.com/takarakasai/rsx.git
> cd rsx
> mkdir build
> cd build
> cmake ..
> ccmake ..
CMAKE_INSTALL_PREFIX: 任意のインストールディレクトリ
ENABLE_MATLAB_API : ON
HR_SERIAL_AUTO_READ_ECHO_DATA : ON (ローカルエコー有の場合)
HR_SERIAL_AUTO_READ_ECHO_DATA : OFF (ローカルエコー無の場合)
> make
> make install

7.ビルド手順 Windows

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// required package
// -- MATLAB (MEXコンパイラのため)
// -- mingw-w64 : http://mingw-w64.org/
// -- gnumex : http://gnumex.sourceforge.net/
// -- git(2.7.1) : https://git-for-windows.github.io/
// -- cmake(3.4.1) : https://cmake.org/download/
> git clone https://github.com/takarakasai/rsx.git
> cd rsx
> . setup_mingw.sh <<<< Windows ではこれが必要です
> mkdir build
> cd build
> cmake ..
> ccmake ..
CMAKE_INSTALL_PREFIX: 任意のインストールディレクトリ
ENABLE_MATLAB_API : ON
HR_SERIAL_AUTO_READ_ECHO_DATA : ON (ローカルエコー有の場合)
HR_SERIAL_AUTO_READ_ECHO_DATA : OFF (ローカルエコー無の場合)
> make
> make install

※ 必要に応じてPATHを通してください.
※ WindowsもしくはMATLABが32bitの場合にはMinGWも32bit環境を用意する必要があります
(http://www.mingw.org/).
私は試したことありませんがおそらく以下のpkgがMinGW上で必要となるはずです.
mingw-base mingw-gcc mingw32-gmp(dev) msys-ligbmp(dev)


7.起動手順 Linux/Windows

Linux の場合

1
2
> cd ${インストールディレクトリ}
> LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:../lib matlab

Windows の場合

1
2
3
MATLAB起動後にインストールディレクトリ以下のlib/mexを
MATLABのPATHに追加してください
(これであっているはず...)

7.1 実行手順 KHR3-HV (1関節だけ)

実行手順はポート名を除きLinux/Windowsで共通です.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
% サーボ通信プロトコルを指定
>> dps_assign('ics')
% サーボIDを登録
>> dps_add_servo(uint8(1))
id:1
% UARTポートオープン(通信速度 115200[bps])
% Linux例 : /dev/ttyUSB0
>> dps_open('ttyUSB','0',int32(115200))
dev:ttyUSB port:0 baudrate:115200
file open : /dev/ttyUSB0
% Windows例 : COM0
>> dps_open('COM','0',int32(115200))
dev:COM port:0 baudrate:115200
file open : COM0
% Servo ON
>> dps_set_state(uint8(1), 'on')
id:01 state:on
% 30度に指定
>> dps_set_goal(uint8(1), 30.0)

7.2 実行手順 KHR3-HV (複数関節)

実行手順はポート名を除きLinux/Windowsで共通です.

1
2
3
4
5
6
7
8
9
% 前ページの続き
% ID:6~10のサーボを登録
>> dps_set_servo(uint8([6, 7, 8, 9, 10]))
5 : 06 07 08 09 10
% ID:1,6~10のサーボをON
>> dps_set_states('on')
% ID:1,6~10のサーボを駆動
>> dps_set_goals([20.0, 0.0, 0.0, 0.0, 0.0, 0.0])
id:all : 20.000000 -30.000000 0.000000 0.000000 0.000000 0.000000 0.000000

7.3 実行手順 KHR3-HV (offset設定)

実行手順はポート名を除きLinux/Windowsで共通です.

1
2
3
4
5
% 前ページの続き
>> dps_set_offset(uint8(1), 10.0)
id:01 oangle:10.0
>> dps_set_offsets([10.0, 0.0, 0.0, 0.0, 0.0, 0.0])
6 : 10.0 0.0 0.0 0.0 0.0 0.0

※ 極性の設定は今後対応予定です (mex対応するの忘れてた…).


7.1実行手順 GR001

実行手順はポート名を除きLinux/Windowsで共通です.

1
2
3
% サーボ通信プロトコルを指定
>> dps_assign('rsx')
% 以下はKHR3-HVの場合と同じです

8.1 まとめ

  1. MATLABでGR001とKHR3-HVを動作させる為のMEXファイルを作成しました
  2. WindowsとLinuxで動作することを確認しました(OSXでも多分動く)



controll GR001 with Python on Edison/PC.

今回の目標

EdisonもしくはPC上のpython環境からGR001を制御する.
これを実現するために以前C言語で作成した通信ライブラリrsxをpythonから利用できる様に拡張します.
拡張したライブラリを利用してpython環境からGR001を制御します.

※ :ライブラリの利用のみを行う場合には# 1.を飛ばしてください.


1. python用通信ライブラリ(rsxpy)のビルド/実行環境を構築

今回はEdison上でビルドします.
boost-pythonがビルドに必要で、ipythonが実行環境として便利なので
これらをインストールします.

1
2
3
4
> sudo apt-get install libboost-python-dev
130[MB]ほど消費されます.
> sudo apt-get install ipython
6.0[MB]ほど消費されます.

2. ライブラリの取得

以前作成したRS301/RS302サーボ向けの通信ライブラリを修正するため
通信ライブラリrsxを取得します.

1
2
3
> git clone git@github.com:takarakasai/rsx.git
> cd rsx
> git checkout feature/for_edison

3. ライブラリ内部の説明

rsxをpythonから利用するためのライブラリrsxpyに拡張します。
これにはboost_pythonを利用します.


3.1 全体構成

rsxpy向けに新たに用意したソースコードは以下のとおりです。
boost_pythonはC++のテンプレートライブラリなので、一旦C++によるラッパ(rsxpp)を作成して
boost_pythonにてpython向けのAPIを作成していきます.

1
2
3
4
./rsx/h/rsxpp/rsxpp.h                   // rsxライブラリのC++ラッパ
./rsx/python/sample/rsx_servo_state.py // pythonによるサンプルプログラム
./rsx/python/src/rsxpy.cc // python向けのラッパクラスの実装
./rsx/python/src/rsxpy.h // python向けのラッパクラスのヘッダ

3.2 C++によるラッパクラスの作成

ここではrsxppというクラスを作成します.

1
2
3
4
5
6
7
8
9
-- h/rsxpp/rsxpp.h
// C言語で作成した通信ライブラリrsxを利用するためrsx.hを読み込みます.
// またシリアル通信向けのEnumを扱えるようにするためhr_serial.hも読み込みます.
extern "C" {
#include "rsx.h"
#include "serial/hr_serial.h"
}

// (略)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
-- h/rsxpp/rsxpp.h
// (略)

// ラッパクラスを定義します.
// rsxライブラリを利用するために必要なrsx構造体を
// DEPSERVO_DECLというマクロを利用してメンバ変数として定義します.
// これをクラスのコンストラクタ内から初期化するようにします.
class rsxpp
{
public:
rsxpp(void) {
DPSERVO_INIT(servo_inst, RSX_INIT);
servo = (rsx*)(&servo_inst);
}

// (略)

// ここにrsxライブリが用意している通信APIを一通りラップする関数を用意します.
// 紙面の都合上全ては記載しませんが、
// ロングパケットでデータを送信するAPIについて以下に例を示します.
errno_t lpkt_mem_write_all
(uint8_t id[/*num*/], uint8_t num ,
uint8_t start_addr, uint8_t size, uint8_t data[/*size*/]) {
ECALL(rsx_lpkt_mem_write_all(servo, id, num, start_addr, size, data));
return EOK;
}

// (略)

protected:
DPSERVO_DECL(servo_inst, kNUM_OF_JOINTS, kMAX_PKT_SIZE, RSX_DECL);
rsx *servo;
}
```

---

## 3.3 Pythonで公開するためのクラスの作成

rsxppクラスを継承したrsxpyクラスを作成します.
rsxppクラスではrsxライブラリのAPIをそのままラップしていますが、
rsxpyクラスではpythonから利用することを考えて、
pythonで扱いやすい型の変数を引数や返り値にしています.

```c++
-- python/src/rsxpy.h
// C++によるラッパクラスrsxppを利用するためのヘッダを読み込みます.
// boost_pythonを利用するためヘッダを読み込みます.
#include "rsxpp.h"
#include "boost/python.hpp"
...
class rsxpy : public dp::rsxpp<kRSXPY_NUM_OF_JOINTS, kRSXPY_MAX_PKT_SIZE> {
...
// ここにrsxppライブリが用意している通信APIを一通りラップする関数を用意します.
// 紙面の都合上全ては記載しませんが、ロングパケットでデータを送信するAPIについて以下に例を示します.
errno_t lpkt_mem_write (bp::list &in_id, uint8_t start_addr, size_t size, bp::list &in_data) {
GET_C_ARRAY(uint8_t, num, id/*[num]*/, in_id);
GET_C_ARRAY_2D(uint8_t, num, size, data/*[num][size]*/, in_data);

ECALL(base::lpkt_mem_write(id, num, start_addr, size, (uint8_t**)data));
return EOK;
}
...
}

3.3 boost_pythonによるAPIの公開

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-- h/rsxpp/rsxpp.cc
...
// rs30xの仮想アドレスをpythonに定数として公開するため
include "mmap/rs30x.h"
...
// boost_pythonのおまじないコードです.
BOOST_PYTHON_MODULE( rsxpy ) {
using namespace dp;

// シリアル通信の通信レートを定数として公開します.
boost::python::enum_<hr_baudrate>("HR_BAUDRATE")
.value("HR_B9600" , HR_B9600 )

// 以下定数の公開処理が続きます.
...

// ここからrsxpyクラスをpythonのrsxpyクラスとして公開します.
boost::python::class_<rsxpy>("rsxpy")
// rsxpyクラスの各公開関数をpythonのrsxpyクラスの関数として公開します.
.def("open", &rsxpy::open)
...
.def("lpkt_mem_write", &rsxpy::lpkt_mem_write)
...
;
}

3 . ライブラリのビルド

1
2
3
4
5
6
7
> m  kdir build
> c make ..
> c cmake ..
// PYTHON_API : OFF --> ON に変更します.
// gとcを押下してmakefileを生成します.
// qを押下してccmakeを抜けます.
> make

3. 実行

pythonのインタプリタを起動します.
ipythonだと関数や定数はタブ補完してくれます.

1
2
3
4
5
6
7
8
9
10
11
12
> cd python
> ipython
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
Type "copyright", "credits" or "license" for more information.

IPython 1.2.1 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.

In [1]:

ipythonのインタプリタから通信APIを叩いていきます.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// ライブラリを読み込んで、通信クラスをインスタンス化します.
IN[*]: import rsxpy
IN[*]: rsx = rsxpy.rsxpy()

// 通信ポートを開きます.
IN[*]: rsx.open("ttyMFD", "1", rsxpy.HR_BAUDRATE.HR_B460800, rsxpy.HR_PARITY.HR_PAR_NONE)
// PCから直接GR001を制御する場合には下記の様に第12引数を読み替えてください.
IN[*]: rsx.open("ttyUSB", "0", rsxpy.HR_BAUDRATE.HR_B460800, rsxpy.HR_PARITY.HR_PAR_NONE)

IN[*]: ids = range(1,21)

// サーボをONにします.
IN[*]: rsx.lpkt_mem_write_all(ids, rsxpy.RSX_RS30X_MEM_ADDR.RSX_RAM_TRQ_ENABLE, [1])

// 各関節の角度を取得します.
IN[*]: ang = list()
IN[*]: for id in ids :
IN[*]: ang.append(rsx.lpkt_mem_read_int16(id, rsxpy.RSX_RS30X_MEM_ADDR.RSX_RAM_PRESENT_POS_L, 1)[0])
IN[*]:

// 1番と4番関節の角度を30度変化させます.
IN[*]: ang[1] += 30 * 10;
IN[*]: ang[4] += 30 * 10;
IN[*]: rsx.lpkt_mem_write_int16(ids, rsxpy.RSX_RS30X_MEM_ADDR.RSX_RAM_GOAL_POS_L, 1, ang)

// サーボをOFFします.
IN[*]: rsx.lpkt_mem_write_all(ids, rsxpy.RSX_RS30X_MEM_ADDR.RSX_RAM_TRQ_ENABLE, [0])

rs485-with-Intel-Edison

Intel EdisonでGR001とRS485で通信




1.今回の目標

  • Intel EdisonでGR001とRS485で通信する.

  • 複数の構成が考えられるので代表的なものを試す.

  • できれば通信時間等の比較をしてみる.


2.実施する構成

  1. USB-RS232C変換ケーブル + RS232C-RS485変換コネクタを使用する

  2. USB-RS485変換コネクタを使用する

  3. RS232C-RS485変換ICを使用する.

*通信速度は115200[bps]で行います.


3.想定する環境

break out board

  • henry board

OS

  • ubilinux + xenomai3.0.0

library

  • cmake
  • cmake-ncurses-gui

4.コードのビルドと実行

全身のサーボの目標角度の更新と現在角度の取得を繰り返し行い。
その間に消費される時間を測定します.

1
2
3
4
5
6
7
8
9
10
11
> mkdir work
> cd work
> git clone git@github.com:takarakasai/rsx.git
> mkdir -p rsx/build
> cd rsx/build
> camke ..
> ccmake ..
ここで4.に示すコンフィグを行います.
> make
> ./sample/rsx_latency_test tty*** *
ここで4.に示すttyUSB/ttyMFD 0/1の値を指定します.

4.実施形態


4.1 実施形態1 (USB-RS232C + RS232C-RS485)

1
2
3
+--------+  USB  +------------+ RS232C +------------+ RS485 +-------+
| Edison |=======| USB-RS232C |========|RS232C-RS485|=======| GR001 |
+--------+ +------------+ +------------+ +-------+



4.1.1 サーボON中の現在角度取得 (Echo:On)

  • 1軸あたり約3.0[msec]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
file open : /dev/ttyUSB0
auto echo read latency : 000000000001996.318[usec]
read latency : 000000000000899.985[usec]
Model Number L:10 H:30
Firmware Version:05
auto echo read latency : 000000000001928.862[usec]
read latency : 000000000000941.456[usec]
auto echo read latency : 000000000001975.050[usec]
read latency : 000000000000959.415[usec]
auto echo read latency : 000000000001979.356[usec]
read latency : 000000000000939.320[usec]
auto echo read latency : 000000000002017.731[usec]
read latency : 000000000000928.883[usec]
auto echo read latency : 000000000001944.446[usec]
read latency : 000000000001006.780[usec]
auto echo read latency : 000000000001927.463[usec]
read latency : 000000000000954.515[usec]
auto echo read latency : 000000000002015.670[usec]
read latency : 000000000000936.443[usec]
auto echo read latency : 000000000001963.297[usec]

4.1.1 サーボON中の現在角度取得 (Echo:Off)

  • 1軸あたり約3.0[msec], Echoなしとあまり変わらない。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
file open : /dev/ttyUSB0
read latency : 000000000002938.702[usec]
Model Number L:10 H:30
Firmware Version:05
read latency : 000000000002889.709[usec]
read latency : 000000000002944.792[usec]
read latency : 000000000002939.965[usec]
read latency : 000000000002937.811[usec]
read latency : 000000000002943.545[usec]
read latency : 000000000002945.761[usec]
read latency : 000000000002950.890[usec]
read latency : 000000000002932.800[usec]
read latency : 000000000002945.314[usec]
read latency : 000000000002970.654[usec]
read latency : 000000000002937.247[usec]
read latency : 000000000002954.433[usec]
read latency : 000000000002910.236[usec]
read latency : 000000000002951.315[usec]
read latency : 000000000002956.522[usec]
read latency : 000000000002945.080[usec]

4.1.2 目標角度更新+現在角度取得 (Echo:On)

  • 1回あたり約2200[msec],遅い…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@ubilinux:/home/kasai/rsx/build# ./sample/rsx_latency_test ttyUSB 0
file open : /dev/ttyUSB0
Model Number L:10 H:30
Firmware Version:05
write read latency : 000000002209018.433[usec]
write read latency : 000000002209550.048[usec]
write read latency : 000000002215498.369[usec]
write read latency : 000000002210337.490[usec]
write read latency : 000000002214434.746[usec]
write read latency : 000000002210338.889[usec]
write read latency : 000000002208474.912[usec]
write read latency : 000000002213613.604[usec]
write read latency : 000000002207402.759[usec]
write read latency : 000000002223359.310[usec]
write read latency : 000000002214373.243[usec]
write read latency : 000000002209397.254[usec]
write read latency : 000000002215453.894[usec]
write read latency : 000000002221349.023[usec]
write read latency : 000000002213387.381[usec]
write read latency : 000000002226612.283[usec]
write read latency : 000000002229343.842[usec]
write read latency : 000000002207545.825[usec]
write read latency : 000000002218341.943[usec]
write read latency : 000000002221342.090[usec]

4.1.2 目標角度更新+現在角度取得 (Echo:Off)

  • 1回あたり約66[msec], Echoなしとだいぶ変わる.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
root@ubilinux:/home/kasai/rsx/build# ./sample/rsx_latency_test ttyUSB 0 
file open : /dev/ttyUSB0
Model Number L:10 H:30
Firmware Version:05
write read latency : 000000000066007.243[usec]
write read latency : 000000000065416.549[usec]
write read latency : 000000000065517.149[usec]
write read latency : 000000000065456.895[usec]
write read latency : 000000000065402.658[usec]
write read latency : 000000000065359.403[usec]
write read latency : 000000000065491.657[usec]
write read latency : 000000000065477.599[usec]
write read latency : 000000000065335.568[usec]
write read latency : 000000000065364.201[usec]
write read latency : 000000000065544.980[usec]
write read latency : 000000000065445.083[usec]
write read latency : 000000000065318.323[usec]
write read latency : 000000000065438.933[usec]
write read latency : 000000000065735.271[usec]
write read latency : 000000000065654.119[usec]
write read latency : 000000000065327.452[usec]
write read latency : 000000000065310.521[usec]
write read latency : 000000000065388.858[usec]
write read latency : 000000000065337.072[usec]
----- end -----

4.2 実施形態2 (USB-RS485)

1
2
3
+--------+  USB  +----------+ RS485 +-------+
| Edison |=======| USB-RS485|=======| GR001 |
+--------+ +----------+ +-------+



4.2.0 実施形態2 (USB-RS485) 準備

  • 今回使用する変換コネクタはCH340+MAX485の構成なので,ch341なドライバが必要.
  • Edison標準のLinuxイメージにはこれがないのでドライバの導入が必要.
  • 標準でサポートしているのでカーネルコンフィグをいじってドライバをビルドする.参考
  1. インストール場所はこんな感じ
1
2
3
4
hroot@ubilinux:home/kasai/rsx/build# find /lib/modules/3.10.17-yocto-standard | grep ch341.ko$
/lib/modules/3.10.17-yocto-standard/kernel/drivers/usb/serial/ch341.ko
hroot@ubilinux:home/kasai/rsx/build# cat /lib/modules/3.10.17-yocto-standard/modules.dep | grep ch341
kernel/drivers/usb/serial/ch341.ko:
  1. ドライバをロードすると/dev/ttyUSB*として認識する
1
2
3
4
5
6
7
8
root@ubilinux:/home/kasai/rsx/build# dmesg | grep ch341
//ロードしていないので何も表示されない
root@ubilinux:/home/kasai/rsx/build# modprobe ch341
root@ubilinux:/home/kasai/rsx/build# dmesg | grep ch341
[ 4594.146533] usbcore: registered new interface driver ch341
[ 4594.146684] usbserial: USB Serial support registered for ch341-uart
[ 4594.146773] ch341 1-1:1.0: ch341-uart converter detected
[ 4594.149669] usb 1-1: ch341-uart converter now attached to ttyUSB0

4.2.1 サーボON中の現在角度取得 (Echo:Off)

  • 1軸あたり4.0-5.0[msec]程度の時間が消費されるようです.
  • ばらつきがあります.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
file open : /dev/ttyUSB0
read latency : 000000000004025.258[usec]
Model Number L:10 H:30
Firmware Version:05
read latency : 000000000004837.597[usec]
read latency : 000000000004894.456[usec]
read latency : 000000000004113.485[usec]
read latency : 000000000004768.715[usec]
read latency : 000000000004956.296[usec]
read latency : 000000000004102.266[usec]
read latency : 000000000004829.400[usec]
read latency : 000000000004925.636[usec]
read latency : 000000000004913.047[usec]
read latency : 000000000004939.229[usec]
read latency : 000000000004973.907[usec]
read latency : 000000000004061.789[usec]
read latency : 000000000004838.127[usec]
read latency : 000000000004946.335[usec]
read latency : 000000000004037.351[usec]
read latency : 000000000004833.191[usec]

4.2.2 目標角度更新+現在角度取得 (Echo:Off)

  • 1軸あたり100[msec]程度の時間が消費されるようです.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
root@ubilinux:/home/kasai/rsx/build# ./sample/rsx_latency_test ttyUSB 0
file open : /dev/ttyUSB0
Model Number L:10 H:30
Firmware Version:05
write read latency : 000000000099950.036[usec]
write read latency : 000000000098789.981[usec]
write read latency : 000000000099444.884[usec]
write read latency : 000000000098239.896[usec]
write read latency : 000000000099361.530[usec]
write read latency : 000000000100248.693[usec]
write read latency : 000000000100436.427[usec]
write read latency : 000000000101202.667[usec]
write read latency : 000000000100670.694[usec]
write read latency : 000000000100652.687[usec]
write read latency : 000000000101576.298[usec]
write read latency : 000000000100529.411[usec]
write read latency : 000000000101556.370[usec]
write read latency : 000000000101491.546[usec]
write read latency : 000000000100395.651[usec]
write read latency : 000000000099471.337[usec]
write read latency : 000000000095471.131[usec]
write read latency : 000000000099132.585[usec]
write read latency : 000000000101567.170[usec]
write read latency : 000000000101641.469[usec]
----- end -----

4.3 実施形態3 (RS232C-RS485)

1
2
3
+--------+  uart  +------------+ RS485 +-------+
| Edison |========|RS232C-RS485|=======| GR001 |
+--------+ +------------+ +-------+





フリスクケースあり (左)
フリスクケースなし (右)

4.3 実施形態2´ (RS232C-RS485)

1
2
3
4
5
6
7
+--------+
| Edison |
+--------+
|| uart
+--------+ uart +------------+ RS485 +-------+
|自作基板|========|RS232C-RS485|=======| GR001 |
+--------+ +------------+ +-------+


=>


4.3.0 uart <-> RS485 変換IC

ISL32603E

-半二重通信用のICで1.8[V]で駆動.256~460[Kbps]までいける.
(※ 保証はできませんが私の環境では115[Kbps]でも動作しました.).

-パッケージはSOIC(1.27[mm])もしくはMSOP(0.5[mm])になるので表面実装が必要.

[1]
[2]
[3]


[1] http://www.incom.co.jp/var/assets/storage/images/companies/node_1664/product/node_118235/1662980-2-jpn-JP/RS-485-ISL3260x_square250.jpg

[2] http://www.eleki-jack.com/KitsandKids2/assets_c/2010/11/LTSP20620020-thumb-400x493.jpg

[3] http://akizukidenshi.com/img/goods/L/P-06863.jpg

購入場所
mouser
or
digikey

仕様書


4.3.1 サーボON中の現在角度取得

  • 1軸あたり2.5[msec]程度の時間が消費されるようです.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
file open : /dev/ttyMFD1
auto echo read latency : 000000000002568.977[usec]
read latency : 000000000000154.489[usec]
Model Number L:10 H:30
Firmware Version:05
auto echo read latency : 000000000002389.956[usec]
read latency : 000000000000153.327[usec]
auto echo read latency : 000000000002391.869[usec]
read latency : 000000000000150.943[usec]
auto echo read latency : 000000000002416.129[usec]
read latency : 000000000000161.699[usec]
auto echo read latency : 000000000002291.760[usec]
read latency : 000000000000161.488[usec]
auto echo read latency : 000000000002269.892[usec]
read latency : 000000000000165.285[usec]
auto echo read latency : 000000000002278.397[usec]
read latency : 000000000000163.622[usec]
auto echo read latency : 000000000002203.704[usec]
read latency : 000000000000164.331[usec]
auto echo read latency : 000000000002218.209[usec]

4.3.2 目標角度更新+現在角度取得

  • 1回あたり57[msec]程度の時間が消費されるようです.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@ubilinux:/home/kasai/rsx/build# ./sample/rsx_latency_test ttyMFD 1
file open : /dev/ttyMFD1
Model Number L:10 H:30
Firmware Version:05
write read latency : 000000000056354.259[usec]
write read latency : 000000000056687.984[usec]
write read latency : 000000000056654.634[usec]
write read latency : 000000000056597.344[usec]
write read latency : 000000000056777.629[usec]
write read latency : 000000000056968.642[usec]
write read latency : 000000000056450.153[usec]
write read latency : 000000000056666.476[usec]
write read latency : 000000000056631.691[usec]
write read latency : 000000000056884.130[usec]
write read latency : 000000000056841.407[usec]
write read latency : 000000000056458.870[usec]
write read latency : 000000000056554.745[usec]
write read latency : 000000000056651.169[usec]
write read latency : 000000000056691.800[usec]
write read latency : 000000000056875.255[usec]
write read latency : 000000000056446.435[usec]
write read latency : 000000000056648.150[usec]
write read latency : 000000000056814.218[usec]
write read latency : 000000000057273.610[usec]

5 結果まとめ





USB-RS232-RS485USB-RS485uart-RS232-RS485
現在角度取得 3.0[msec]4-5.0[msec] 2.5[msec]
目標角度更新と現在角度取得67.0[msec] 100.0[msec]57.0[msec]

6 考察

通信遅延要因

シリアル通信ドライバ

  • 速度優先の設定になっていない (setserial /dev/tty* low_latency)
  • バッファ処理による遅延
  • ユーザ-カーネル間の遷移に関連する遅延(通信データ, コンテキストスイッチ)

==> RTDM対応のシリアル通信ドライバを作成すれば改善する可能性あり.

その他

  • サーボに設定できる通信遅延時間が長く設定されている (0.1 - 12.850[msec])

==> 最小値(0.1[msec])に設定されていた


おわり




xenomai-3.0 on ubilinux with Intel Edison

1.今回の目標

Intel Edison向けUbilinuxのカーネルをxenomaiカーネルに置き換える.


2.方針

Ubilinuxのカーネルソースは公開されていないので,Edison向けYocto linuxのソースを落としてきてXenomaiパッチをあててビルドします.
Yoctoのビルドシステムを使用することになるので,手動でパッチあてて即ビルドというわけにはいかないです.
なので,Yocto linux向けのXenomaiパッチを作成してYoctoのビルドコンフィグに設定してビルドするです.


3.準備

まずEdisonにUbilinuxの環境を作成します.

1
2
3
4
5
6
> wget http://www.emutexlabs.com/files/ubilinux/ubilinux-edison-150309.tar.gz
> tar zxvf ubilinux-edison-150309.tar.gz$
> cd toFlash
ここで一旦Edisonに接続されているUSBケーブルを取り外します
> ./flashall.sh
EdisonにUSBケーブルを接続します.

4.作業手順


4.1 作業ディレクトリ作成

適当に作業用ディレクトリを作成します.
以降はこの下で作業を行います.

1
2
> mkdir work
> cd work

4.2 ソースコードの準備

Yocto LinuxとXenomaiのソース一式を取得して展開

1
2
3
4
> wget http://downloadmirror.intel.com/25028/eng/edison-src-ww25.5-15.tgz
> tar zxvf edison-src-ww25.5-15.tgz$
> wget https://xenomai.org/downloads/xenomai/stable/xenomai-3.0.tar.bz2
> bzip2 -dc xenomai-3.0.tar.bz2$ | tar xvf -

Git から取得しても良いです.

1
2
3
4
5
6
7
8
9
10
11
> git clone git://git.yoctoproject.org/meta-intel-edison
> cd meta-intel-edison
> git checkout ww05-15
> cd ..
> mkdir edison-src
> mv meta-intel-edison edison-src/

> git clone git://git.xenomai.org/xenomai-3.git
> cd xenomai-3
> git checkout v3.0
> cd ..

4.3 一旦ビルドする

Yoctoのビルドシステムではビルドコマンドしないとソースコードを落としてくれないのでビルドします.
と書いたもののバージョンが一致するカーネルをkernel.orgから持ってきても良さそうです. ビルドすると34GBほど消費されます.

1
2
3
4
5
6
> cd edison-src
> ln -s meta-intel-edison/utils/Makefile.mk Makefile
> make setup
> cd edison-src/out/linux64
> source poky/oe-init-build-env
> bitbake edison-image

4.4 パッチ作成

ビルド終わると以下のディレクトリにカーネルソースが取得されています.
out/linux64/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/
ので、xenomaiパッチをあてます.
*edison用のディストリは皆32bitなので注意.

diff -Narup linux linux_xeno

1
2
3
4
5
6
> cp -rf edison-src/out/linux64/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/ ./linux.org
> cp -rf edison-src/out/linux64/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/ ./linux.xeno
> xenomai-3/scripts/prepare-kernel.sh \
--linux=linux.xeno \
--ipipe=xenomai-3/kernel/cobalt/arch/x86/patches/ipipe-core-3.10.32-x86-6.patch \
--arch=x86

これだとエラーが出るのでなくなるまで修正します.
修正が終わったらパッチを作成します.

1
> diff -Narup linux.org linux_xeno > xenomai-3.0-3.10.17.patch

4.5 パッチの組み込み

作成したパッチをYoctoのビルドに組み込みます.
これには特定の場所にパッチを配置して、bitbakeの設定ファイルに記述を追加する必要があります.

1
2
3
4
5
6
7
> mv xenomai-3.0-3.10.17.patch edison-src/meta-intel-edison/meta-intel-edison-bsp/recipes-kernel/linux/files/
> vi edison-src/meta-intel-edison/meta-intel-edison-bsp/recipes-kernel/linux/linux-yocto_3.10.bbappend
... 略 ...
SRC_URI += "file://defconfig"
SRC_URI += "file://upstream_to_edison.patch" <<<< edison向けのパッチ
SRC_URI += "file://xenomai-3.0-3.10.17.patch" <<<< 追加.xenomaiパッチ
... 略 ...

4.6 カーネルコンフィグ

Yoctoのビルドシステムを使ってカーネルのコンフィグをいじります.
Xenomaiを使い物にするには,CPUをぶん回したりするので以下を参考に設定します。
https://xenomai.org//2014/06/configuring-for-x86-based-dual-kernels/

1
> bitbake virtual/kernel -c menuconfig

設定が終わったらYoctoのビルドシステムが指定する所定の場所に配置します.

1
cp edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux-edison-standard-build/.config ../../../meta-intel-edison/meta-intel-edison-bsp/recipes-kernel/linux/files/defconfig

4.7 ビルド

Xenomaiパッチを当てたカーネルをビルドします.

1
2
3
4
5
6
> bitbake edison-image
> ls edison-src/out/linux64/build/tmp/deploy/images/edison
...
bzImage--3.10.17-r0-edison-YYYYMMDDHHMMSS.bin
edison-image-edison-YYYYMMDDHHMMSS.hddimg
...

4.8 インストール

vmlinuz と必要あれば/lib/modulesなどをコピーします.

1
2
3
4
5
6
7
8
9
10
> mkdir ext4
> sudo mount -o loop edison-image-edison-YYYYMMDDHHMMSS.rootfs.ext4 ext4
> ls ext4
bin boot dev etc home lib lost+found media mnt opt proc run sbin sketch sys tmp usr var
> scp -rf ext4/lib/modules/3.10.17-yocto-standard root@${edison_ip}:/lib/modules/

> mkdir hddimg
> sudo mount -o loop edison-image-edison-YYYYMMDDHHMMSS.hddimg hddimg
ldlinux.c32 ldlinux.sys syslinux.cfg vmlinuz
> scp -rf hddimg/vmlinuz root@${edison_ip}:/boot/vmlinuz.xeno

wlan at ubilinux with edison

ubilinux な edison で wlan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
> wpa_passphrase koya ${your_wpa_passwd} > koya-wlan.conf
> cp ./koya-wlan.conf /etc/wpa_supplicant/
> vi /etc/network/interfaces
auto wlan0
iface wlan0 inet dhcp
# For WPA
+ wpa-conf /etc/wpa_supplicant/koya-wlan.conf
- wpa-ssid test
- wpa-psk pass
+ #wpa-ssid test
+ #wpa-psk pass
# For WEP
#wireless-essid Emutex
#wireless-mode Managed
#wireless-key s:passwordk

> ifdown wlan0
nternet Systems Consortium DHCP Client 4.2.2
Copyright 2004-2011 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/wlan0/78:4b:87:a8:f0:e9
Sending on LPF/wlan0/78:4b:87:a8:f0:e9
Sending on Socket/fallback
DHCPRELEASE on wlan0 to 192.168.11.1 port 67

> ifup wlan0
Internet Systems Consortium DHCP Client 4.2.2
Copyright 2004-2011 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/wlan0/78:4b:87:a8:f0:e9
Sending on LPF/wlan0/78:4b:87:a8:f0:e9
Sending on Socket/fallback
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 8
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 13
DHCPREQUEST on wlan0 to 255.255.255.255 port 67
DHCPOFFER from 192.168.11.1
DHCPACK from 192.168.11.1
bound to 192.168.11.11 -- renewal in 76747 seconds.

> iwconfig wlan0
wlan0 IEEE 802.11abgn ESSID:"koya"
Mode:Managed Frequency:2.412 GHz Access Point: 4C:E6:76:3E:BE:A1
Bit Rate=54 Mb/s Tx-Power=31 dBm
Retry long limit:7 RTS thr:off Fragment thr:off
Encryption key:off
Power Management:on
Link Quality=56/70 Signal level=-54 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:14 Invalid misc:1 Missed beacon:0