1

公立はこだて未来大学 2013 年度 システム情報科学実習
グループ報告書
Future University Hakodate 2013 System Information Science Practice
Group Report
プロジェクト名
柔らかさを感じる筋電義手の開発
Project Name
Development of Myoelectric hand with feeling softness
グループ名
プログラミング班
Group Name
Programming Group
プロジェクト番号/Project No.
22-A
プロジェクトリーダ/Project Leader
1011045 岩口優也 Yuya Iwaguchi
グループリーダ/Group Leader
1011150 緒方悠也 Yuya Ogata
グループメンバ/Group Member
1011051 鈴木玲央 Reo Suzuki
指導教員
櫻沢繁, 伊藤精英
Advisor
Shigeru Sakurazawa Kiyohide Ito
提出日
2014 年 1 月 15 日
Date of Submission
Jan. 15, 2014
Development of myoelectric hand with feeling softness
概要
筋電義手とは,怪我や疾患で腕を欠損した人が使用する義手の一種である.その最大の特徴は内
部に動作機構を搭載しており,使用者の意思に応じて開閉などの動作が可能であることである.筋
電義手は生物の筋肉が活動する時に生じる筋電位を読み取り,その情報に基づいて
, 動作する.一
般的な鈎状の義手は先端の鈎に対象物を引っ掛ける程度のことしかできない.しかし手の形をした
筋電義手の場合,生身の手と概ね同じ程度の動作が可能である.一方,筋電義手の短所としては価
格が高いことと耐用年数が短いことが挙げられる.一般的な筋電義手の価格は一本あたり50万円
から100万円の値段が要求される.また,日本では保険適用外であるため使用者の負担は著しく
大きくなる.耐用年数は3年から4年程度で,精密な機械であるため定期的なメンテナンスが必要
である.また機械であるため神経は通っておらず,触れたものの硬度や温度は分からない.そして
外見から義手使用者である事が悟られるため,生身の腕に外見を似せた装飾用の義手の使用を選択
する人が多い.
本プロジェクトでは触知覚が得られないこと,人間らしくないことに注目し,これを解決した
『人間らしい筋電義手』を開発することを目標にした.本プロジェクトにおける人間らしさとは,
人間の手と同じ動きが可能で触知覚ができることと捉えた.
前期は筋電義手に,つまむ,放す,を最低限の動作として実現させることを目標にし,そのため
の知識の習得を目標にした.同時に触知覚の勉強と基礎研究も行った.筋電義手の制作にあたり,
プロジェクトを生体信号計測班,プログラミング班,義手制作班,触知覚研究班にグループ分けを
行った.この報告書ではプログラミング活動について記述する.
キーワード 筋電義手 筋電位 触知覚
(*文責:鈴木玲央)
Group Report of 2013 SISP i
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
Abstract
The myoelectric hand is a kind of prosthetic hand which is used by people lost their a hand by an accident or a
disease. The greatest feature is that it has the motion mechanism in the inside, and is that operation of opening
and closing according to user's intention is possible. It reads the signal which arises while muscles contraction
and is controlled by the signal. A general hook-type artificial arm can only perform hooking a thing at its tip.
However, in the case of myoelectric hand which has form of the hand, operation as same grade as a flesh and
blood hand is possible. On the other hand, it is faults that a price is high and that a life is short. From 500,000 to
one million yen price per one is required for the price of a common machine. Moreover, Since insurance is not
applied, user's burden becomes very large. The life is from three years to four years, and it requires a periodical
maintenance. And user can't sense hardness and temperature because it doesn't have nerves. And they choice a
ornamental artificial hand because they dislike using a artificial hand.
In this project, we aimed development the myoelectric hand which was solved two ploblems. We thought manlike is to be able to work and sense in this project.
In first half, we aimed to develop the myoelectric hand which perform gripping and releasing. And we studied
hand perception and made basic experiments. And we divided members into four groups:
measurement group, controlling group, robot hand group and hand perception group. And we write about
programming group actives on.
Keyword myoelectric hand, electromyography, hand perception
(*Responsibility for wording: Reo Suzuki)
Group Report of 2013 SISP ii
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
目次
第1章 概要
1.1
背景................................................ 1
1.2
筋電義手の現状とその問題点................................
1.3
課題の概要............................................ 2
1
第2章 到達目標 2.1
本プロジェクトの目的 ..................................... 3
2.2
プログラミング班の目的....................................
3
2.3
通常の授業ではなく,プロジェクト学習で行う利点....................
4
2.4
課題解決のプロセス......................................
4
2.5
課題の割り当て......................................... 6
第3章 グループ内の学習と問題解決の過程
3.1
概要................................................ 7
3.2
マイクロコンピュータ......................................
3.3
無線通信............................................. 8
3.4
サポートベクターマシン..................................
3.5
7
9
3.4.1
パターン認識.................................... 9
3.4.2
教師あり学習.................................... 9
3.4.3
サポートベクターマシン............................. 9
3.4.4
サポートベクターマシンの手法........................
3.4.5
カーネルトリック................................. 10
3.4.6
ニューラルネットワークとの相違点...................... 11
ニューラルネットワーク..................................
9
12
3.5.1
背景.......................................... 12
3.5.2
ニューラルネットワークの概要........................ 12
3.5.3
勾配法........................................
3.5.4
誤差逆伝播法.................................... 13
13
3.6
ポスター制作.......................................... 14
3.7
スライド制作.......................................... 14
第4章
結果
4.1
プロジェクトの成....................................... 15
4.2
成果の評価............................................ 15
4.3
担当分担課題の評価...................................... 16
4.3.1 プロジェクト全体..................................
16
4.3.2 プログラミング.................................... 16
Group Report of 2013 SISP iii
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
4.3.3 鈴木玲央........................................
16
4.3.4 緒方悠也........................................
17
第 5 章 今後の課題と展望........................................ 18
第 6 章 付録
6.1 入力用マイコンプログラム................................. 19
6.2 出力用マイコンプログラム................................. 20
6.3 サポートベクターマシン..................................
23
6.4 ニューラルネットワーク..................................
40
参考文献................................................... 67
Group Report of 2013 SISP iv
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
第 1章 背景
1.1 背景
筋電義手とは,人間が筋肉を動かす時に生じる筋電位を利用して動作させる義手の一種である .
一般的な義手は先端がフック状になっており,物を先端に引っ掛けることしかできない.しかし人
間の手の形をした義手の場合,フックで引っ掛けることができない形状のものでも持つことができ
るため,通常の義手以上に腕を失った障害者の生活を補うことができる.しかし筋電義手には筋電
位の計測や義手の構造,価格などの問題がいくつかある.
(*文責:緒方悠也)
1.2 筋電義手の現状とその問題点
筋電義手の使用にあたり,筋電位の計測には侵襲的計測法が用いられる場合が多い.この方法で
は外科的手段により電極を体内に埋め込んだり,計測用の針電極を筋肉に刺して直接筋電位を測る
これらの方法では安定的かつ正確に筋肉の活動を計測することができ,精密な義手の制御が可能と
なる.
しかし上記のような計測法を用いた義手の問題点は安全性に欠ける.侵襲的計測法では外科的手
法によって電極を装着するため,使用者に苦痛が伴い,感染症のリスクが発生する.
筋電義手には重量の問題がある.義手の指や腕のフレーム, 100gから 200g程度のサーボモータを
複数搭載すると自ずと総重量が大きくなり,日常的に装着して使用するには困難である.
3つめの問題点は価格の問題である.筋電義手は指や腕などの複数のパーツで構成され,サーボ
モータや計測,制御用の回路などが搭載されている.それらの単価は高く,故障した際の交換用の
パーツの購入を考慮すると使用者の金銭面の負担は非常に大きくなる.実際に販売されている筋電
義手は100万円程度で,より高性能なものはそれ以上の金額がつく.また筋電義手の使用には訓
練や定期的なメンテナンスが必要で,これらの負担も使用者が負う.筋電義手が普及している国で
はこれらの負担を国が補助する仕組みがあるが,日本においては補助が受けられない.そのため日
本では筋電義手の普及が遅れている.
Group Report of 2013 SISP
(*文責:緒方悠也)
1
Group Number 22 - Group A
.
Development of myoelectric hand with feeling softness
1.3 課題の概要
以上の課題を踏まえ,本プロジェクトでは義手の作成にあたり,低価格,軽量,非侵襲方式の計
測を条件とした.
プログラミング班の課題は非侵襲方式の計測で取得した筋電位をもとに,作成した筋電義手を制
御することである.非侵襲方式の計測では,筋肉が活動した時に皮膚表面上に生じる表面筋電位を
皮膚に貼り付けた電極によって計測する.この方法で計測した筋電位は電極を貼り付けた周辺の筋
肉の活動を区別することなく計測する.このため特定の筋との対応関係を作って制御することがで
きない.この問題を解決するため,装着した電極がによって計測された筋電位をパターン識別によ
って分別する事を試みた.
Group Report of 2013 SISP
(*文責:緒方悠也)
2
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
第 2章 到達目標
2.1 本プロジェクトの目的
本プロジェクトの目的は触知覚ができ,外見の問題を含めて人間らしい筋電義手を開発するこ
とである.触知覚の実現には振戦(静止状態に起こる微弱な肉体の震え)に注目し,人間らしさと
は前述の触知覚が可能で,生身の手と同等の細かな動作が可能であり,見た目がそれと似通ってい
る事 , と捉えた.また,義手作成の条件として,低価格,軽量,非侵襲方式の計測の三項目を設け
た.
(*文責:緒方悠也)
2.2 プログラミング班の目的
本プロジェクトにおけるプログラミング班の目的は,生体信号計測班が作成した回路により計測
した筋電位をもとに義手を動作させることである.本プロジェクトにおいて信号計測は非侵襲的方
法で実現する.侵襲的方法は肉体を傷つけて使用者に負担をかけるだけでなく,感染症のリスクが
伴うため棄却された.非侵襲的方法の計測は皮膚表面上に電極を医療用のテープで貼り付けること
で肉体を傷つけずに実現した.しかしこの方法では貼り付けた電極には任意の筋肉の活動だけでな
く,電極周辺の筋肉の活動を区別することなく計測してしまう.そのため前腕の筋肉と義手のそれ
ぞれの指の動作との間に対応関係を作ることができない.よってプログラミング班は各電極が計測
した筋電位の強さを数値として読み込み,機械学習プログラムによってパターンに分類,識別する
ことで義手の制御を試みた.よってプログラミング班の目的は計測した筋電位の読み込み,機械学
習プログラムの作成,および義手へのアウトプットである.また,義手の振戦による触知覚のフィ
ードバックを行うことも視野に入れた.
(*文責:緒方悠也)
Group Report of 2013 SISP
3
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
2.3 通常の授業ではなく,プロジェクト学習で行う利点
プロジェクト学習で行う利点は , 複数のメンバーで編成されたチームで課題に取り組む上で,プ
ロジェクト遂行に必要なルールやそのノウハウを学ぶことができる点である.より詳細にはスケジ
ュール管理やタスクの割り振りを経験し,チーム間あるいはメンバー間のコミュニケーション能力
を養うことができる.また通常の授業では取り組まなかった回路設計や大規模なプログラム開発な
どを教員の指導のもとに取り組めることも特徴である.さらに中間,最終発表ではプロジェクトで
取り組む分野の知識のない第三者へ成果を伝える必要があり,その素養を身につけることもできる.
(*文責:緒方悠也)
2.4 課題解決のプロセス
以下の手順を踏んだ.
1. 筋電義手についての調査
メンバーそれぞれが筋電義手について調べ,分かったことを発表した.
2.
中間発表までの課題を設定
メンバー全員で議論し,どのような筋電義手を作成するかを決定した.
3.
筋肉の特性と計測回路の講習
教員による講義が行われた.また,実際に簡易な回路を作成した.
4.
班分け
以下のような人員分配になった.
・プログラミング班
緒方悠也
鈴木玲央
・義手制作班
岩口優也
太恭兵
岩佐梨伽
・生体信号計測班
石原拓真
千葉悠貴
久田真矢
Group Report of 2013 SISP
4
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
なお,後期は振戦実験を集中して行うため,以下の班を新たに設けた.
・振戦実験班
岩佐梨伽
久田真矢
以下はプログラミング班について記述する.
5. マイクロコンピュータと機械学習の学習とプログラミング開発
マイクロコンピュータ『 Arduino 』(後述)とサポートベクターマシンの学習を行い,昨
年度に使用したプログラムを引き継ぎ,今年度の制作物に対応させた.
6.
後期の目標
前期の成果を振り返り,後期の目標を設定した.
7.
無線化とニューラルネットワークの学習と開発
夏期休暇中と後期序盤に学習を行い,開発に取り組んだ.
8.
ニューラルネットワークとサポートベクターマシンの比較
前期に使用したサポートベクターマシンと後期に開発したニューラルネットワークの比較
テストを行った.この結果,ニューラルネットワークのプログラムのほうが僅かに優れて
いた.
9.
プログラムの改善
プログラムを二通りに改善し,比較した.
10. 動作テスト
義手と計測回路を使い,全体でのテストを行った.
(*文責:緒方悠也)
Group Report of 2013 SISP
5
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
2.5 課題の割り当て
緒方悠也の課題の割り当ては以下のとおりである.
5 月:筋肉,筋電義手の学習.引き継いだプログラム,マイコンの理解.
6 月:プログラムの作成,マイコンを使用しながら理解.
7 月:制作した義手,回路と動作テスト.制作班への応援.
夏期休暇:ニューラルネットワーク,無線通信の勉強.ニューラルネットワークプログラムの
試作
9-10月:ニューラルネットワークプログラムの試作
11月:ニューラルネットワークプログラムの試作,比較テスト
12月 : プログラムの改善,比較テスト,動作テスト,発表練習
鈴木玲央の割り当ては以下のとおりである.
5 月:筋肉,筋電義手の学習.引き継いだプログラム,マイコンの理解.
6 月:プログラムの作成,マイコンを使用しながら理解.
7 月:制作した義手,回路と動作テスト.製作班への応援.
夏期休暇:ニューラルネットワーク,無線通信の勉強.
9-10月:無線機の勉強と試用.無線化.
11月:無線化,振戦実験班への応援
12月 : 振戦実験班への応援,ポスター掲載資料の作成
(*文責:緒方悠也)
Group Report of 2013 SISP
6
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
第 3章 グループ内の学習と問題解決の過程
3.1 概要
本章ではプログラミング班の取り組みを項目に分けて記述する.
(*文責:緒方悠也)
3.2 マイクロコンピュータ
マイクロコンピュータには , 前期,後期を通じて図 3.1 の『 Arduino MEGA 2560 』を使用した.
Arduino はオープンソースハードウェアで, C++ 風の Arduino 言語と統合開発環境で開発が可能で
ある. Arduino の設計図は公開されているため,それをもとに自作することができるが,本プロジ
ェクトにおいては購入した既製品を使用した. Arduino とパソコンはシリアル通信で伝達が可能で
あるが,両者の通信は一方通行であるため,筋電位の計測用と義手制御用に二つ用意した.
Arduino はアナログ値の入力電圧 0V から 5V として受け取り, A/D 変換を行って 0 から1023の
範囲で表されるディジタル値で表現する.
義手に搭載されたサーボモータへの出力は PWM 出力で擬似的にアナログ出力を行い,サーボモ
ータを制御する.
図 3.1 Arduino MEGA 2560
(文責:緒方悠也)
Group Report of 2013 SISP
7
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
3.3 無線通信
前期の活動における反省点として,計測時の機器の接続に時間がかかることや,回線により義手
の使用や持ち運びに支障が出ることがあげられた.これらの問題を解決するために,後期のプロジ
ェクトでは配線を無線化することにした.今回,本プロジェクトでは Zigbee 規格の無線機を使用し
た. Zigbee とは短距離無線通信の規格の一つで, Xbee モジュールの通信距離は屋内で 30m ,屋外
で 100m 程度に設定されている.また通信速度は 250kbps まで上げることが可能となる.無線通信
に関して,今回は以下の機材を使用した.
・ Xbee-PRO シリーズ 1/ ワイヤアンテナ型 2 個
・ Xbee USB アダプタ
・ Arduino MEGA 2560
・ Arduino ワイヤレスプロトシールド
使 用 方 法 と し て は , 図 3.2 の よ う に 1 台 の モ ジ ュ ー ル を Arduino XBee シ ー ル ド に セ ッ ト し ,
Aruduino のマイコンボードに接続する.もう一方のモジュールは USB 接続で PC と接続できる
XBee USB アダプタにセットして PC とUSB経由で接続する.
図 3.2 Arduino とシールド(左),USBアダプタ(右)
(※文責:鈴木玲央)
Group Report of 2013 SISP
8
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
3.4 サポートベクターマシン
3.4.1 パターン認識
パターン認識は,人間が行う学習をコンピュータで実現しようとする技術・手法のことである.
機械学習と呼ぶこともある.パターン識別は,入力された複数個のサンプルのデータを解析し,結
果を利用してパターンの識別に有用な規則や基準を抽出することで識別精度を向上させる.このと
きの入力と出力の対応をトレーニングデータと呼ぶ.本プロジェクトでは,与えられた点の分類か
ら,新たに与えられた点の分類を推測する教師あり学習を行う.
(※文責:鈴木玲央)
3.4.2 教師あり学習
教師あり学習は,事前に用意したトレーニングデータを利用してパターンを識別する手法である
.
教師付き学習とも呼ぶ.複数個のトレーニングデータを学習しておき,データに含まないような入
力データに対しても正しい出力を予測させる.また学習したデータ中に含まれていない
データに 対
応できる能力を汎化能力という.前期に用いたサポートベクターマシンは汎化能力を有しており,
学習に用いなかった未知のデータを分類することができる.
(※文責:鈴木玲央)
3.4.3 サポートベクターマシン
サポートベクターマシンは 2 つのクラスを識別可能な識別器を構成するパターン認識手法であり ,
上述の教師あり学習に分類される.サポートベクターマシンを用いて 2 つ以上のクラスの識別器を
構成するためには高次元化等を行う必要がある.
(※文責:鈴木玲央)
3.4.4 サポートベクターマシンの手法
サポートベクターマシンはトレーニングデータのうち,クラス境界近傍に位置する点を基準とす
る.また選択された点をサポートベクトルと呼ぶ.サポートベクターマシンは異なるクラスで最も
距離が小さなサポートベクトルを選択し,二つのサポートベクトルと識別線の距離が最も大きくな
るような位置に識別境界を設定する.これをマージン最大化という.
トレーニングデータを 2 つのクラスに分類するときに用いられる識別関数 f は以下の式で表され
る.
m
f (x )=sin( ∑ wi K ( x i , x )+b)
(i=1)
Group Report of 2013 SISP
9
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
ここで x は入力ベクトル, w は重みベクトル, b はバイアスである.また xi はサポートベクトルを ,
m はサポートベクトルの個数を表す. b は -θ で置き換えることができ,このときの θ を閾値と呼ぶ .
K はカーネル関数と呼ばれ,二つのベクトル xi と x を引数とする.
図 3.3 マージン最大化
(※文責:鈴木玲央)
3.4.5 カーネルトリック
カーネルトリックは,線形分離可能でない場合に線形しきい素子を求める手法である.サポート
ベクターマシンは線形分離可能でないデータには適用することができないため,そのままでは応用
できる範囲が限定される.分類するときの面が線形でない場合,カーネルトリックを用いて入力空
間を次元の高い特徴空間に写像できるので,その空間で線形分離を行う.この処理は,元の入力空
間においては非線形な分類を行っているのと同意である.
一般に,サンプルのデータ数が大きければ線形分離可能性は低くなり,特徴空間ベクトルの次元
が大きければ線形分離可能性は高くなる.複雑な問題を線形分離可能にするためにはサンプルのデ
ータと同じ数の次元に写像する必要があり,計算量が膨大になるうえ汎化能力が低くなる.
カーネルトリックを使用して非線形にも識別関数を構成できるように対応したサポートベクターマ
シンでは,中間層から出力層への重みベクトルのみ学習によって決定される.入力層から中間層へ
の重みベクトルは学習に左右されず,トレーニングデータの結果から求めることができる.
(※文責:鈴木玲央)
Group Report of 2013 SISP
10
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
3.4.6 ニューラルネットワークとの相違点
学習理論の代表的な成果の 1 つとしてニューラルネットワークが挙げられる.ニューラルネット
ワークは多層パーセプトロンをバックプロパゲーションによって学習させる.誤差逆伝搬法を用い
るニューラルネットワークでは,パラメータが学習の過程で特定の範囲内での最適解を導いて学習
を停止する.この問題を局所最適解といい,局所最適解は空間全体での最適解である広域最適解
とは一致しない場合がある .これは予め与えられたトレーニングデータには学習結果を対応させる
が,学習データが与えられていない範囲において初期値に依存するというバックプロパゲーション
学習の特性である.そのため最適な領域を確保する境界線が引かれず,非効率的な境界が設定され
る可能性がある.
サポートベクターマシンの学習では,局所最適解と広域最適解が等しくなる二次最適化問題に帰
着する.ラグランジュの未定乗数を用いることによるものであり,サポートベクターマシンには局
所最適解の問題が存在しない.
(※文責:鈴木玲央)
Group Report of 2013 SISP
11
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
3.5 ニューラルネットワーク
3.5.1 背景
後期のプロジェクトの目標として,義手に五本の指をつけて各々に動作機構を搭載することを設
定した.この目標を達成する上での問題点は計測回路と機械学習によるパターン認識の精度である.
計測上の問題は的確な筋電位を選別することが難しいことである.個々の指の筋肉に繋がる前腕の
筋肉は共通する部分があり,詳細な分岐は手の平にある.このため個々の指を一本ずつ動かす場合
でも異なる指同士であっても計測される筋電位は似た値を示し,結果,機械学習による判別が難し
くなる.そのため計測回路による計測精度の向上と合わせてパターン認識の精度を向上させる必要
があった.指針としてパターン認識に優れるニューラルネットワークのプログラムを開発し,前期
に使用したサポートベクターマシンのプログラムと比較を行うことにした.
(文責:緒方悠也)
3.5.2 ニューラルネットワークの概要
ニューラルネットワークとは生物の神経細胞(ニューロン)のネットワークの共同を模倣した工
学モデルである.図 3.5 に示すように入力ベクトル x
に対し,各ニューロンの閾値 θ
と結
合重み w
を設定し,(1)の式で出力を求める.学習の形態には正解データを入力する教師あ
り学習とそうでない教師なし学習があるが,今回は教師あり学習を実現した.
図 3.4 ニューロン 図 3.5 ニューロンのモデル
N
s=∑ x i wi
i=1
1
y=sigmoid ( s−θ)=
1+exp [−α (s−θ)]
…(1)
(文責:緒方悠也)
Group Report of 2013 SISP
12
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
3.5.3 勾配法
勾配法とは関数の極小値(あるいは極大値)を見つけ出すためのアルゴリズムで,ニューラルネ
ットワークに限らず多くの学習方式,適応システムに利用されている.勾配法の目的は図 3.6 の極
小値 A (または B )を探し出すことである.極小値 A を探す場合を例とすると,始めに A 周辺に適
当な初期値 x=a
が減少する方向へ x
を微小変化させる.この手続きを繰
は極小値 A に到達する.極小値 A では左右どちらに動かしても増加するため,
を設定し,
り返していくと x
y
ここで手続きは終了する.
図
3.6 勾配法
(*文責:緒方悠也)
3.5.4 誤差逆伝播法
誤差逆伝播法(バックプロパゲーション)とは教師あり学習の手法で,勾配法をもとに行われる.
, 出力を ( y 1, y 2, ... , y M ) とし,ネットワークの入出力
ネットワークへの入力を (x 1, x 2, ... , x N )
関係を関数 ( y 1, y 2, ... , y M )=F ( x 1, x 2, ... , x N )
で表すことにする.誤差逆伝播法は
( y 1, y 2, ... , y M )=F ( x 1, x 2, ... , x N ) が指定された入出力関係を実現するようにネットワーク内部の
パラメータ w ij , θi
を変化させる.以下に手順を追って記載する.
1.
ネットワークに学習のためのサンプルを与える.
2.
ネットワークの出力とそのサンプルの最適解を比較する.各出力ニューロンについて誤差
を計算する.
3.
結合重みを修正する.
以上を収束条件を満たすまで繰り返す.
(*文責:緒方悠也)
Group Report of 2013 SISP
13
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
3.6 ポスター制作
本プロジェクトで行った筋電義手の制作と触知覚実験に関して,中間発表および最終発表時の説
明の補足としてポスターを作製した.前期と後期のいずれもメインポスターを 1 枚,サブポスター
を 2 枚用意した.
プログラミング班は,前期はサポートベクターマシンによる識別を中心に説明した.図を使用し
サポートベクターマシンの理論を解説した.また 後期は無線通信とニューラルネットワークについ
て説明し, 目的と方法,結果を簡潔に示した.無線通信に関しては,有線の回線で接続している状
態の写真を無線の写真と並べて比較した.ニューラルネットワークは理論を解説する図と具体例を
示す図を 1 枚ずつ用意した.
(※文責:鈴木玲央)
3.7 スライド制作
中間発表および最終発表時に口頭の説明と併せて使用するスライドを作製した.
プログラミング班は, 前期は表面筋電位の計測から識別までの制御機構を説明した. アナログデジ
タル変換とサポートベクターマシンについての図を中心に用意し,その必要性を口頭で解説した.
後期は発表内容を無線通信とニューラルネットワークの二つに限定した.
前期に発生した問題と課題の解決方法を簡潔に書き,前期と同様に口頭で詳細を発表した.
(※文責:鈴木玲央)
Group Report of 2013 SISP
14
Group Number 22 - Group A
,
Development of myoelectric hand with feeling softness
第 4章 結果
4.1 プロジェクトの成果
プロジェクト全体の目的は義手で触知覚を可能にすることと,人間らしさを有した義手を開発す
ることであった.
前期では昨年度の技術を学ぶと同時に振戦の特性を知るための実験を行った.具体的には筋電義
手の親指と人差し指,中指の3本の指を動作させた.また,つまむ動作と脱力状態の2つのパター
ンを実装し,サポートベクターマシンを用いて学習させた.その結果,2種類の動作の判別に成功
したが,正確に識別させることはできず,誤動作が発生した.振戦実験では物質の硬度によって震
えの周波数に変化が見られ,振戦が知覚に関係していることが示唆された.
後期では人間らしさをより具体的に明示することと,振戦と知覚の関係を明らかにすることに取
り組んだ.そこで5本の指をそれぞれ独立して折り曲げる動作を実装した.また,ニューラルネッ
トワークを用いて学習させた.その結果,最大4本の指を識別できるようになったが,別の指の表
面筋電位を読み取ってしまう問題が発生したため,5本全ての動作を識別させることはできなかっ
た.また,じゃんけんに使われる3種類の動作をサポートベクターマシンに学習させたところ,安
定的に動作した.触知覚に関しては,硬度弁別の実験で外部から振動を与えた場合の正答率が与え
なかった場合の正答率を大きく上回ったため,触知覚と振戦の関係を示す結果になった.
(※文責:鈴木玲央)
4.2 成果の評価
無線化の設定は成功したものの,実際の運用ではデータ通信量の上限を超えたためにデータの通
信ができず,筋電義手の配線の無線化は実装することができなかった.また指を折り曲げる動作に
よって発生する筋電位の中で,他の指で観測されるパターンに類似したものが存在しており,後期
に新たに作製したニューラルネットワークのプログラムで判別することが不可能であった.そのた
め5本の指すべてを独立させて動かすことができなかった.これらの問題はニューラルネットワー
クや前期に用いたサポートベクターマシンの変更によって改善される可能性がある.
(※文責:鈴木玲央)
Group Report of 2013 SISP
15
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
4.3 担当分担課題の評価
4.3.1 プロジェクト全体
スケジュールに関しては,予定を変更しなければならないことが最後まで多々あった.この問題
は前期に課題として挙げられたものの,後期でも同様の事態が発生してしまった.原因としては,
後期の前半でプロジェクトの方向性が決まらなかったためにスケジュール管理が後回しになってい
たことが考えられる.役割分担については,前期だけでなく後期にも一部の人に仕事が集中してし
まうことがあった.連絡に関しては,前期では別の班との連携が疎かになったことで問題が発生し
たが,後期では改善されていた.
(※文責:鈴木玲央)
4.3.2 プログラミング班
前期ではサポートベクターマシンを用いて,つまむ動作と脱力状態の2種類を学習し,動作識別
を行った.しかし完全な識別ができずに誤動作を起こしてしまった.他にも配線の誤りなどの人的
ミスによる事故が発生した.後期ではニューラルネットワークと無線通信の導入を試みたが,無線
通信は失敗に終わり,ニューラルネットワークも目標の達成には至らなかった.またプロジェクト
全体の問題も当てはまり,スケジュールの見直しや仕事量の差などがあったほか,班の中でも各自
が別の仕事をしていたために十分な連携ができていなかった.
(※文責:鈴木玲央)
4.3.3 鈴木玲央
前期は最初に筋肉と筋電義手,震えについて学んだ.プログラミング班に属してからは昨年の識
別プログラムであるサポートベクターマシンの理論と構造,マイクロコンピュータの配線等を学び
前期のプロジェクトの目標であるつまむ動作の識別に向けて活動した.しかしプログラミングにつ
いての知識が不足しており,プログラムについては UI の変更等を除いてあまり関わることができ
なかった.また,場合によってはハード班が担当している義手の指を削る作業に参加していた.
後期はサポートベクターマシンに代わる識別アルゴリズムとしてニューラルネットワークを導入
したが,ここでも自分の力不足によって協力することができなかった.無線通信については初期設
定を行い無線化することに成功したが,時間がかかったためスケジュールの遅れを引き起こしてし
まった.後期では被験者として実験に参加したほか,他の班の補助に回ることが多かった.
全体としては,プログラミングの知識不足が原因で発生した問題があったため,今後解消してい
きたい.他にも仕事の役割分担等で消極的な姿勢があったため,その点も改善する.
(※文責:鈴木玲央)
Group Report of 2013 SISP
16
Group Number 22 - Group A
,
Development of myoelectric hand with feeling softness
4.3.4 緒方悠也
プログラミング班のリーダーとしてスケジュール管理やタスクの割り振りをしつつ , 一班員とし
てプログラミングなども行った . これらの役割には反省点が大いにある . プログラム開発に当たっ
ては基礎理論から開発に当たっての必要知識が不足していた . リーダーとしてはスケジュール管理
やタスクの振り分けに問題が見受けられ , チームの稼働率が低下することがしばしばあった . そし
て他の班との連携も滞り , 結果的に全体の開発に遅れを生じさせる原因の一端になってしまった .
(※文責:緒方悠也)
Group Report of 2013 SISP
17
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
第 5章 今後の課題と展望
プログラミング班の今後の課題として,後期に実装できなかった無線通信と5本指の実装がある.
前期に明らかになった問題として,今回用いたサポートベクターマシンは完全な識別ができず,義
手に誤作動が発生してしまうことや,義手に繋がる回線が多く義手使用者の負担が大きいうえに移
動可能な範囲が限定されることなどがある.これらの問題への対処法として,上記の2つを実装す
ることを引き続きプログラミング班の課題とする.
後期からの改善点としては,後期の識別プログラムの選定方法がある.今回,後期に作製したニ
ューラルネットワークと前期に使用したサポートベクターマシンを比較し,正答率が上回ったニュ
ーラルネットワークを用いたが,実験の正当性の考察や実施回数が不足していた.後に別の条件で
実験を行うとサポートベクターマシンが良い結果を出すこともあり,今後はアルゴリズムの改善と
ともに最適な実験方法を探っていく.
(※文責:鈴木玲央)
Group Report of 2013 SISP
18
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
第6章 付録
この章では作成したプログラムを記載する。
6.1 入力用マイコンプログラム
void setup(){
Serial.begin(115200);
}
int ch = 5;// チャンネル数
void loop(){
int ch_data[ch];
int ch_high[ch];
int ch_low[ch];
for(int i = 0; i < ch; i++){
ch_data[i] = analogRead(i);//0~1023 まで読み込める
ch_high[i] = ch_data[i] / 256; //
ch_low[i] = ch_data[i] % 256; //
}
if(Serial.available() > 4){
Serial.read();
for(int i = 0; i < ch; i++){
Serial.write(ch_high[i]);
Serial.write(ch_low[i]);
}
}
delay(10);
}
Group Report of 2013 SISP
19
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
6.2 出力用マイコンプログラム
#include <Servo.h>
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
void setup(){
Serial.begin(115200);
servo1.attach(2);// 親指
servo2.attach(4);// 人差し指
servo3.attach(6);// 中指
servo4.attach(8);// 薬指
servo5.attach(10);// 小指
pinMode(13, OUTPUT);
}
void loop(){
// モーターの設定
int motor = 5;//モーターの数
char signal;
int motor_data[motor];
int motor_wdata[motor];
signal = Serial.read();
if(Serial.available() > (motor-1)){
digitalWrite(13, HIGH);//点灯
for(int i = 0; i < motor; i++){
motor_data[i] = Serial.read();
motor_wdata[i] = map(motor_data[i],0,255,580,2375);
digitalWrite(13, LOW);// 点灯
}
if(signal == '1'){
servo1.writeMicroseconds(motor_wdata[0]);
delay(20);
servo2.writeMicroseconds(motor_wdata[1]);
delay(20);
servo3.writeMicroseconds(motor_wdata[2]);
delay(20);
servo4.writeMicroseconds(motor_wdata[3]);
delay(20);
Group Report of 2013 SISP
20
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
servo5.writeMicroseconds(motor_wdata[4]);
}
if(signal == '2'){
servo1.writeMicroseconds(motor_wdata[0]);
delay(20);
servo2.writeMicroseconds(motor_wdata[1]);
delay(20);
servo3.writeMicroseconds(motor_wdata[2]);
delay(20);
servo4.writeMicroseconds(motor_wdata[3]);
delay(20);
servo5.writeMicroseconds(motor_wdata[4]);
}
if(signal == '3'){
servo1.writeMicroseconds(motor_wdata[0]);
delay(20);
servo2.writeMicroseconds(motor_wdata[1]);
delay(20);
servo3.writeMicroseconds(motor_wdata[2]);
delay(20);
servo4.writeMicroseconds(motor_wdata[3]);
delay(20);
servo5.writeMicroseconds(motor_wdata[4]);
}
if(signal == '4'){
servo1.writeMicroseconds(motor_wdata[0]);
delay(20);
servo2.writeMicroseconds(motor_wdata[1]);
delay(20);
servo3.writeMicroseconds(motor_wdata[2]);
delay(20);
servo4.writeMicroseconds(motor_wdata[3]);
delay(20);
servo5.writeMicroseconds(motor_wdata[4]);
}
if(signal == '5'){
servo1.writeMicroseconds(motor_wdata[0]);
delay(20);
servo2.writeMicroseconds(motor_wdata[1]);
delay(20);
servo3.writeMicroseconds(motor_wdata[2]);
delay(20);
servo4.writeMicroseconds(motor_wdata[3]);
Group Report of 2013 SISP
21
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
delay(20);
servo5.writeMicroseconds(motor_wdata[4]);
}
if(signal == '6'){
servo1.writeMicroseconds(motor_wdata[0]);
servo2.writeMicroseconds(motor_wdata[1]);
servo3.writeMicroseconds(motor_wdata[2]);
servo4.writeMicroseconds(motor_wdata[3]);
servo5.writeMicroseconds(motor_wdata[4]);
}
}
delay(10);
}
Group Report of 2013 SISP
22
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
6.3 サポートベクターマシン
import libsvm.*;
import java.io.*;
import processing.serial.*;
Serial rport;//read port
Serial wport;//write
class point {
// 点の情報を格納するクラス
point(double c1, double c2,double c3,double c4,double c5,double c6, byte value) {
this.c1 = c1;
//A座標の情報
this.c2 = c2;
//B 標の情報
this.c3 = c3;
//C 座標の情報
this.c4 = c4;
//D座標の情報
this.c5 = c5;
//E 座標の情報
this.c6 = c6;//1~5 までの平均
this.value = value; // 点の色の情報
}
double c1,c2,c3,c4,c5,c6,c7,c8;
byte value;
}
int PLEN = 1024; // 点を打つことのできる A( 横幅 ) の範囲が 0 ~1024
//-------------------------------- データ数の設定------------------------------int count = 0;
int flag = 0;
int rdata = 0;
int DATANUM = 100;// 筋電から格納するデータ 200 個 (1 秒間で 1 各チャンネルから 100 個のデータ
が送られる )
int N = 10;//1 フレーム内のサンプル数
int n = 10;//0.1 秒毎のデータ数
//---------------------- モーターを動かすプログラム ----------------------------------------------------// モーターを動かす
int motor = 5;
int [] motor_count = new int[motor];
int [] motor_data = new int[motor];
//------------------------- チャンネル設定 -------------------------------------double ch1_data = 0;
double [] ch1_amount = new double[n];// 0.1 秒毎のデータの総量
double [] ch1 = new double[DATANUM];//Arduino から送信されるデータ
int ch1_high = 0;
int ch1_low = 0;
double ch2_data = 0;
double [] ch2_amount = new double[n];// 0.1 秒毎のデータの総量
Group Report of 2013 SISP
23
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
double [] ch2 = new double[DATANUM];//Arduino から送信されるデータ
int ch2_high = 0;
int ch2_low = 0;
double ch3_data = 0;
double [] ch3_amount = new double[n];// 0.1 秒毎のデータの総量
double [] ch3 = new double[DATANUM];//Arduino から送信されるデータ
int ch3_high = 0;
int ch3_low = 0;
double ch4_data = 0;
double [] ch4_amount = new double[n];// 0.1 秒毎のデータの総量
double [] ch4 = new double[DATANUM];//Arduino から送信されるデータ
int ch4_high = 0;
int ch4_low = 0;
double ch5_data = 0;
double [] ch5_amount = new double[n];// 0.1 秒毎のデータの総量
double [] ch5 = new double[DATANUM];//Arduino から送信されるデータ
int ch5_high = 0;
int ch5_low = 0;
double ch6_data = 0;
double [] ch6_amount = new double[n];// 0.1 秒毎のデータの総量
double [] ch6 = new double[DATANUM];//Arduino から送信されるデータ
int ch6_high = 0;
int ch6_low = 0;
//--------------------------------- 各動作の筋電の平均化 -------------------------double [] ch1_ave_action1 = new double[n];//0.1秒毎のデータ平均
double [] ch2_ave_action1 = new double[n];//0.1秒毎のデータ平均
double [] ch3_ave_action1 = new double[n];//0.1秒毎のデータ平均
double [] ch4_ave_action1 = new double[n];//0.1秒毎のデータ平均
double [] ch5_ave_action1 = new double[n];//0.1秒毎のデータ平均
double [] ch6_ave_action1 = new double[n];//0.1秒毎のデータ平均
double [] ch1_ave_action2 = new double[n];//0.1秒毎のデータ平均
double [] ch2_ave_action2 = new double[n];//0.1秒毎のデータ平均
double [] ch3_ave_action2 = new double[n];//0.1秒毎のデータ平均
double [] ch4_ave_action2 = new double[n];//0.1秒毎のデータ平均
double [] ch5_ave_action2 = new double[n];//0.1秒毎のデータ平均
double [] ch6_ave_action2 = new double[n];//0.1秒毎のデータ平均
double [] ch1_ave_action3 = new double[n];//0.1秒毎のデータ平均
double [] ch2_ave_action3 = new double[n];//0.1秒毎のデータ平均
double [] ch3_ave_action3 = new double[n];//0.1秒毎のデータ平均
double [] ch4_ave_action3 = new double[n];//0.1秒毎のデータ平均
double [] ch5_ave_action3 = new double[n];//0.1秒毎のデータ平均
Group Report of 2013 SISP
24
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
double [] ch6_ave_action3 = new double[n];//0.1秒毎のデータ平均
double [] ch1_ave_action4 = new double[n];//0.1秒毎のデータ平均
double [] ch2_ave_action4 = new double[n];//0.1秒毎のデータ平均
double [] ch3_ave_action4 = new double[n];//0.1秒毎のデータ平均
double [] ch4_ave_action4 = new double[n];//0.1秒毎のデータ平均
double [] ch5_ave_action4 = new double[n];//0.1秒毎のデータ平均
double [] ch6_ave_action4 = new double[n];//0.1秒毎のデータ平均
double [] ch1_ave_action5 = new double[n];//0.1秒毎のデータ平均
double [] ch2_ave_action5 = new double[n];//0.1秒毎のデータ平均
double [] ch3_ave_action5 = new double[n];//0.1秒毎のデータ平均
double [] ch4_ave_action5 = new double[n];//0.1秒毎のデータ平均
double [] ch5_ave_action5 = new double[n];//0.1秒毎のデータ平均
double [] ch6_ave_action5 = new double[n];//0.1秒毎のデータ平均
//-----------------------GUI パラメータ -------------------------//
int frameFrag = 0;
int debug=0;
String state = "";
PImage front,rev;
String frontPic="No_motion_01.jpg",revPic="No_motion_02.jpg";
//----------- 指の開閉の値 -------------//
final int oya_open = 160;
final int oya_close = 85;
final int hito_open = 170;
final int hito_close = 30;
final int naka_open = 180;
final int naka_close = 30;
final int kusuri_open = 190;
final int kusuri_close = 20;
final int koyubi_open = 190;
final int koyubi_close = 70;
//--------------------------------------------------------------------------Vector<point> point_list = new Vector<point>(); // 点を格納する配列
byte current_value = 0;
//点の色の情報
point p;
//point クラスの変数 p を宣言
void setup() {
size(screen.width-100,screen.height-100);
background(255);
Group Report of 2013 SISP
25
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
rport = new Serial(this, "COM13", 115200);//115200bps = 14400byte / s
wport = new Serial(this, "COM8", 115200);
for(int i = 0; i< motor;i++) {// モーターの初期化
motor_count[i] = 0;
motor_data[i] = 0;
}
//Arduino の初期化
rport.clear();
wport.clear();
}
void draw() {
//------------------------------SVM のパラメータ ----------------------------------------svm svm = new svm();
svm_parameter param = new svm_parameter();
svm_model model;
param.svm_type = svm_parameter.C_SVC;
//svm_parameter の初期化
param.kernel_type = svm_parameter.RBF;
param.degree = 5;
param.gamma = 0;
param.coef0 = 0;
param.nu = 0.5;
param.cache_size = 40;
param.C = 2;
param.eps = 0.001;
param.p = 0.1;
param.shrinking = 1;
param.probability = 0;
param.nr_weight = 0;
param.weight_label = new int[0];
param.weight = new double[0];
svm_problem prob = new svm_problem();
prob.l = point_list.size();
prob.y = new double[prob.l];
//------------------------------- チャンネル設定 -------------------------------------background(255);
front = loadImage(frontPic);
image(front,0,0,width/4,height);
rev = loadImage(revPic);
Group Report of 2013 SISP
26
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
image(rev,width-width/4,0,width/4,height);
//---------------------------------------- グラフ描写 ----------------------------------------------strokeWeight(1);
// 各辺 100 の六角形
line(width/2,height/2-200, width/2, height/2+200);
line(width/2-100*sqrt(3), height/2-100, width/2+100*sqrt(3), height/2+100);
line(width/2-100*sqrt(3), height/2+100, width/2+100*sqrt(3), height/2+-100);
line(width/2, height/2-200, width/2+100*sqrt(3),height/2-100);//p1-p2
line(width/2+100*sqrt(3), height/2-100, width/2+100*sqrt(3),height/2+100);//p2-p3
line(width/2+100*sqrt(3), height/2+100, width/2, height/2+200);//p3-p4
line(width/2, height/2+200, width/2-100*sqrt(3), height/2+100);//p4-p5
line(width/2-100*sqrt(3), height/2+100, width/2-100*sqrt(3), height/2-100);//p5-p6
line(width/2-100*sqrt(3), height/2-100, width/2, height/2-200);//p6-p1
ellipseMode(CENTER);
//ch1
fill(255,0,0);
ellipse(width/2, height/2-(ch1_high * 256 + ch1_low)*200/1024, 10, 10);
//ch2
fill(0,0,255);
ellipse(width/2+(ch2_high * 256 + ch2_low)*100*sqrt(3)/1024, height/2-(ch2_high * 256 +
ch2_low)*100/1024, 10, 10);
//ch3
fill(0,255,0);
ellipse(width/2+(ch3_high * 256 + ch3_low)*100*sqrt(3)/1024, height/2+(ch3_high * 256 +
ch3_low)*100/1024, 10, 10);
//ch4
fill(255,255,0);
ellipse(width/2, height/2+(ch4_high * 256 + ch4_low)*200/1024, 10, 10);
//ch5
fill(255,100,200);
ellipse(width/2-(ch5_high * 256 + ch5_low)*100*sqrt(3)/1024, height/2+(ch5_high * 256 +
Group Report of 2013 SISP
27
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
ch5_low)*100/1024, 10, 10);
int ave = (((ch1_high * 256 + ch1_low)+(ch2_high * 256 + ch2_low)+(ch3_high * 256 + ch3_low)+
(ch4_high * 256 + ch4_low)+(ch5_high * 256 + ch5_low))/5);
//ave
fill(0);
ellipse(width/2-ave*100*sqrt(3)/1024, height/2-ave*100/1024, 10, 10);
strokeWeight(4);
//ch1-ch2
line(width/2, height/2-(ch1_high * 256 + ch1_low)*200/1024, width/2+(ch2_high * 256 +
ch2_low)*100*sqrt(3)/1024, height/2-(ch2_high * 256 + ch2_low)*100/1024);
//ch2-ch3
line(width/2+(ch2_high
*
256 +
ch2_low)*100*sqrt(3)/1024,
height/2-(ch2_high
* 256
+
ch2_low)*100/1024, width/2+(ch3_high * 256 + ch3_low)*100*sqrt(3)/1024, height/2+(ch3_high * 256 +
ch3_low)*100/1024);
//ch3-ch4
line(width/2+(ch3_high * 256 + ch3_low)*100*sqrt(3)/1024, height/2+(ch3_high * 256 +
ch3_low)*100/1024, width/2, height/2+(ch4_high * 256 + ch4_low)*200/1024);
//ch4-ch5
line(width/2, height/2+(ch4_high * 256 + ch4_low)*200/1024, width/2-(ch5_high * 256 +
ch5_low)*100*sqrt(3)/1024, height/2+(ch5_high * 256 + ch5_low)*100/1024);
//ch5-ave
line(width/2-(ch5_high
* 256
+
ch5_low)*100*sqrt(3)/1024, height/2+(ch5_high
* 256
+
ch5_low)*100/1024, width/2-ave*100*sqrt(3)/1024, height/2-ave*100/1024);
//ave-ch1
line(width/2-ave*100*sqrt(3)/1024, height/2-ave*100/1024, width/2, height/2-(ch1_high * 256 +
ch1_low)*200/1024);
textSize(20);
fill(0);
text("ch1 = " + (ch1_high * 256 + ch1_low), width/2- 40, height/2-225);
text("ch2 = " + (ch2_high * 256 + ch2_low), width/2+190, height/2-120);
text("ch3 = " + (ch3_high * 256 + ch3_low), width/2+190, height/2+130);
text("ch4 = " + (ch4_high * 256 + ch4_low), width/2- 40, height/2+240);
text("ch5 = " + (ch5_high * 256 + ch5_low), width/2-270, height/2+140);
text("Avg.= "+ ((ch1_high * 256 + ch1_low)+(ch2_high * 256 + ch2_low)+(ch3_high * 256 + ch3_low)+
(ch4_high * 256 + ch4_low)+(ch5_high * 256 + ch5_low)) / 5, width/2-270, height/2-120);
//------------------------- マニュアル -------------------------------//
if(keyPressed){
if(key == 'o') frameFrag = 0;
Group Report of 2013 SISP
28
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
if(key == 'c') frameFrag = 1;
}
if(frameFrag == 0){
fill(220);
rect(0, height-300, width, height);
fill(0);
rect(width/2-510, height-238, 1020, 1);
textSize(20);
text("flag = " + flag , width/2-470, height-260);
text("prob.l" + " " + (prob.l), width/2-70, height-260);
text("read data" + " " + rdata, width/2+230, height-260);
// text("No motion : 1",width/2-470, height-230);
//
text("Clutch : 2",width/2-70, height-230);
//
text("Pinch : 3",width/2+230, height-230);
text("flag = 1 : Reading Data" , width/2-470, height-200);
text("flag = 2 : Learning SVM",width/2-70, height-200);
text("flag = 3 : OUTPUT", width/2+230, height-200);
text("'SHIFT'+'1' Key = No motion ", width/2-470, height-170);
text("'SHIFT'+'2' Key = Pinch ", width/2-70, height-170);
text("'SHIFT'+'3' Key = Clutch ", width/2+230, height-170);
text("'SHIFT'+'n'+'SPACE' Key = SVM_Learning ", width/2-470, height-140);
text("'SHIFT'+'n'+'ENTER' Key = OUTPUT", width/2-470, height-110);
text("Mouse Click = Read port Clear", width/2-470, height-80);
text("State: " + state,width/2-470,height-50);
}
//------------------------------------------ 初期条件 ----------------------------------------------if(flag == 0){
for(int i = 0; i < N; i++){
for(int j = 0;j < n; j++){
ch1[(10*i)+j] = 0;
ch2[(10*i)+j] = 0;
ch3[(10*i)+j] = 0;
ch4[(10*i)+j] = 0;
ch5[(10*i)+j] = 0;
ch6[(10*i)+j] = 0;
}
}
for(int i = 0; i < n; i++){
ch1_amount[i] = 0;
ch2_amount[i] = 0;
ch3_amount[i] = 0;
ch4_amount[i] = 0;
Group Report of 2013 SISP
29
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
ch5_amount[i] = 0;
ch6_amount[i] = 0;
}
current_value = 0;
if(keyPressed){
if(keyCode == SHIFT) {
flag = 1;
count = 0;
rdata = 0;
}
}
}
//-------------------------------------- 各動作の筋電位を抽出 ------------------------------------------if(flag == 1){
if(keyPressed){
if(key == '1') count = 1; // 安静状態
if(key == '2') count = 2; // つまむ
if(key == '3') count = 3;// つかむ
if(key == '4') count = 4;// 手首前
if(key == '5') count = 5;// 手首後
if(key == 'n') flag = 2;
}
//----------------------------------------- 安静状態-------------------------------------------------------if(count == 1){
state = "No motion";
current_value = 1;
ch1[rdata] = (ch1_high * 256) + ch1_low;
ch2[rdata] = (ch2_high * 256) + ch2_low;
ch3[rdata] = (ch3_high * 256) + ch3_low;
ch4[rdata] = (ch4_high * 256) + ch4_low;
ch5[rdata] = (ch5_high * 256) + ch5_low;
ch6[rdata] = ((ch1_high * 256 + ch1_low)+(ch2_high * 256 + ch2_low)+(ch3_high * 256 + ch3_low)+
(ch4_high * 256 + ch4_low)+(ch5_high * 256 + ch5_low)) / 5;
rdata++;
if(rdata >= DATANUM) {
flag = 0;
for(int i = 0;i < N; i++){
for(int j = 0; j < n ; j++){
ch1_amount[j] += ch1[(10*i)+j];
ch2_amount[j] += ch2[(10*i)+j];
ch3_amount[j] += ch3[(10*i)+j];
ch4_amount[j] += ch4[(10*i)+j];
ch5_amount[j] += ch5[(10*i)+j];
Group Report of 2013 SISP
30
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
ch6_amount[j] += ch6[(10*i)+j];
}
}
for(int i = 0; i < n; i++){
ch1_ave_action1[i] = ch1_amount[i] / N;
ch2_ave_action1[i] = ch2_amount[i] / N;
ch3_ave_action1[i] = ch3_amount[i] / N;
ch4_ave_action1[i] = ch4_amount[i] / N;
ch5_ave_action1[i] = ch5_amount[i] / N;
ch6_ave_action1[i] = ch6_amount[i] / N;
point
p
=
new
point((double)ch1_ave_action1[i]/PLEN,
(double)ch3_ave_action1[i]/PLEN,
(double)ch2_ave_action1[i]/PLEN,
(double)ch4_ave_action1[i]/PLEN,(double)ch5_ave_action1[i]/PLEN,
(double)ch6_ave_action1[i]/PLEN, current_value);
point_list.addElement(p);
}
}
}
//------------------------------------------------つまむ ------------------------------------------------------------if(count == 2){
state = "Pinch";
current_value = 2;
ch1[rdata] = (ch1_high * 256) + ch1_low;
ch2[rdata] = (ch2_high * 256) + ch2_low;
ch3[rdata] = (ch3_high * 256) + ch3_low;
ch4[rdata] = (ch4_high * 256) + ch4_low;
ch5[rdata] = (ch5_high * 256) + ch5_low;
ch6[rdata] = ((ch1_high * 256 + ch1_low)+(ch2_high * 256 + ch2_low)+(ch3_high * 256 + ch3_low)+
(ch4_high * 256 + ch4_low)+(ch5_high * 256 + ch5_low)) / 7;
rdata++;
if(rdata >= DATANUM) {
flag = 0;
for(int i = 0;i < N; i++){
for(int j = 0; j < n ; j++){
ch1_amount[j] += ch1[(10*i)+j];
ch2_amount[j] += ch2[(10*i)+j];
ch3_amount[j] += ch3[(10*i)+j];
ch4_amount[j] += ch4[(10*i)+j];
ch5_amount[j] += ch5[(10*i)+j];
ch6_amount[j] += ch6[(10*i)+j];
}
}
Group Report of 2013 SISP
31
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
for(int i = 0; i < n; i++){
ch1_ave_action2[i] = ch1_amount[i] / N;
ch2_ave_action2[i] = ch2_amount[i] / N;
ch3_ave_action2[i] = ch3_amount[i] / N;
ch4_ave_action2[i] = ch4_amount[i] / N;
ch5_ave_action2[i] = ch5_amount[i] / N;
ch6_ave_action2[i] = ch6_amount[i] / N;
point
p
=
new
point((double)ch1_ave_action2[i]/PLEN,
(double)ch3_ave_action2[i]/PLEN,
(double)ch2_ave_action2[i]/PLEN,
(double)ch4_ave_action2[i]/PLEN,(double)ch5_ave_action2[i]/PLEN,
(double)ch6_ave_action2[i]/PLEN, current_value);
point_list.addElement(p);
}
}
}
//-------------------------------------------- つかま-------------------------------------------------------------if(count == 3){
state = "Grip";
current_value = 3;
ch1[rdata] = (ch1_high * 256) + ch1_low;
ch2[rdata] = (ch2_high * 256) + ch2_low;
ch3[rdata] = (ch3_high * 256) + ch3_low;
ch4[rdata] = (ch4_high * 256) + ch4_low;
ch5[rdata] = (ch5_high * 256) + ch5_low;
ch6[rdata] = ((ch1_high * 256 + ch1_low)+(ch2_high * 256 + ch2_low)+(ch3_high * 256 + ch3_low)+
(ch4_high * 256 + ch4_low)+(ch5_high * 256 + ch5_low)) / 5;
rdata++;
if(rdata >= DATANUM) {
flag = 0;
for(int i = 0;i < N; i++){
for(int j = 0; j < n ; j++){
ch1_amount[j] += ch1[(10*i)+j];
ch2_amount[j] += ch2[(10*i)+j];
ch3_amount[j] += ch3[(10*i)+j];
ch4_amount[j] += ch4[(10*i)+j];
ch5_amount[j] += ch5[(10*i)+j];
ch6_amount[j] += ch6[(10*i)+j];
}
}
for(int i = 0; i < n; i++){
ch1_ave_action3[i] = ch1_amount[i] / N;
ch2_ave_action3[i] = ch2_amount[i] / N;
ch3_ave_action3[i] = ch3_amount[i] / N;
Group Report of 2013 SISP
32
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
ch4_ave_action3[i] = ch4_amount[i] / N;
ch5_ave_action3[i] = ch5_amount[i] / N;
ch6_ave_action3[i] = ch6_amount[i] / N;
point
p
=
new
point((double)ch1_ave_action3[i]/PLEN,
(double)ch3_ave_action3[i]/PLEN,
(double)ch2_ave_action3[i]/PLEN,
(double)ch4_ave_action3[i]/PLEN,(double)ch5_ave_action3[i]/PLEN,
(double)ch6_ave_action3[i]/PLEN, current_value);
point_list.addElement(p);
}
}
}
//------------------------------------------------手首前 ----------------------------------------------if(count == 4){
state = "4";
current_value = 4;
ch1[rdata] = (ch1_high * 256) + ch1_low;
ch2[rdata] = (ch2_high * 256) + ch2_low;
ch3[rdata] = (ch3_high * 256) + ch3_low;
ch4[rdata] = (ch4_high * 256) + ch4_low;
ch5[rdata] = (ch5_high * 256) + ch5_low;
ch6[rdata] = ((ch1_high * 256 + ch1_low)+(ch2_high * 256 + ch2_low)+(ch3_high * 256 + ch3_low)+
(ch4_high * 256 + ch4_low)+(ch5_high * 256 + ch5_low)) / 5;
rdata++;
if(rdata >= DATANUM) {
flag = 0;
for(int i = 0;i < N; i++){
for(int j = 0; j < n ; j++){
ch1_amount[j] += ch1[(10*i)+j];
ch2_amount[j] += ch2[(10*i)+j];
ch3_amount[j] += ch3[(10*i)+j];
ch4_amount[j] += ch4[(10*i)+j];
ch5_amount[j] += ch5[(10*i)+j];
ch6_amount[j] += ch6[(10*i)+j];
}
}
for(int i = 0; i < n; i++){
ch1_ave_action4[i] = ch1_amount[i] / N;
ch2_ave_action4[i] = ch2_amount[i] / N;
ch3_ave_action4[i] = ch3_amount[i] / N;
ch4_ave_action4[i] = ch4_amount[i] / N;
ch5_ave_action4[i] = ch5_amount[i] / N;
ch6_ave_action4[i] = ch6_amount[i] / N;
point
p
=
Group Report of 2013 SISP
new
point((double)ch1_ave_action4[i]/PLEN,
33
(double)ch2_ave_action4[i]/PLEN,
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
(double)ch3_ave_action4[i]/PLEN,
(double)ch4_ave_action4[i]/PLEN,(double)ch5_ave_action4[i]/PLEN,
(double)ch6_ave_action4[i]/PLEN, current_value);
point_list.addElement(p);
}
}
}
//------------------------------------------ 手首後 ------------------------------------------------------------if(count == 5){
state = "5";
current_value = 5;
ch1[rdata] = (ch1_high * 256) + ch1_low;
ch2[rdata] = (ch2_high * 256) + ch2_low;
ch3[rdata] = (ch3_high * 256) + ch3_low;
ch4[rdata] = (ch4_high * 256) + ch4_low;
ch5[rdata] = (ch5_high * 256) + ch5_low;
ch6[rdata] = ((ch1_high * 256 + ch1_low)+(ch2_high * 256 + ch2_low)+(ch3_high * 256 + ch3_low)+
(ch4_high * 256 + ch4_low)+(ch5_high * 256 + ch5_low)) / 5;
rdata++;
if(rdata >= DATANUM) {
flag = 0;
for(int i = 0;i < N; i++){
for(int j = 0; j < n ; j++){
ch1_amount[j] += ch1[(10*i)+j];
ch2_amount[j] += ch2[(10*i)+j];
ch3_amount[j] += ch3[(10*i)+j];
ch4_amount[j] += ch4[(10*i)+j];
ch5_amount[j] += ch5[(10*i)+j];
ch6_amount[j] += ch6[(10*i)+j];
}
}
for(int i = 0; i < n; i++){
ch1_ave_action5[i] = ch1_amount[i] / N;
ch2_ave_action5[i] = ch2_amount[i] / N;
ch3_ave_action5[i] = ch3_amount[i] / N;
ch4_ave_action5[i] = ch4_amount[i] / N;
ch5_ave_action5[i] = ch5_amount[i] / N;
ch6_ave_action5[i] = ch6_amount[i] / N;
point
p
=
new
point((double)ch1_ave_action5[i]/PLEN,
(double)ch3_ave_action5[i]/PLEN,
(double)ch2_ave_action5[i]/PLEN,
(double)ch4_ave_action5[i]/PLEN,(double)ch5_ave_action5[i]/PLEN,
(double)ch6_ave_action5[i]/PLEN, current_value);
point_list.addElement(p);
}
}
Group Report of 2013 SISP
34
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
}
}
//--------------------------------- データを平均化させる------------------------------------if(flag == 2){
if(keyPressed){//SVM が領域を分離する
if(key == ' ') count = 7;
// 学習した点から領域の分類を行う
if(key == ENTER) flag = 3; //OUTPUT
}
if(count == 7){
if (param.gamma == 0) param.gamma = 0.5;
prob.x = new svm_node[prob.l][6];
for (int i = 0; i < prob.l; i++) {
p = point_list.elementAt(i);
prob.x[i][0] = new svm_node();
prob.x[i][0].index = 1;
prob.x[i][0].value = p.c1;
prob.x[i][1] = new svm_node();
prob.x[i][1].index = 2;
prob.x[i][1].value = p.c2;
prob.x[i][2] = new svm_node();
prob.x[i][2].index = 3;
prob.x[i][2].value = p.c3;
prob.x[i][3] = new svm_node();
prob.x[i][3].index = 4;
prob.x[i][3].value = p.c4;
prob.x[i][4] = new svm_node();
prob.x[i][4].index = 5;
prob.x[i][4].value = p.c5;
prob.x[i][5] = new svm_node();
prob.x[i][5].index = 6;
prob.x[i][5].value = p.c6;
prob.y[i] = p.value;
}
model = svm.svm_train(prob, param);
svm_node[] x = new svm_node[6];
for(int i = 0; i < 6; i++){
x[i] = new svm_node();
x[i].index = (i + 1);
}
flag = 0;
}
}
//----------------------------------- 実行モードの出力 ------------------------------------------Group Report of 2013 SISP
35
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
if(flag == 3){
//------------------------------- 各チャンネルのデータ -------------------------------ch1_data = ch1_high * 256 + ch1_low;
ch2_data = ch2_high * 256 + ch2_low;
ch3_data = ch3_high * 256 + ch3_low;
ch4_data = ch4_high * 256 + ch4_low;
ch5_data = ch5_high * 256 + ch5_low;
ch6_data = ((ch1_high * 256 + ch1_low)+(ch2_high * 256 + ch2_low)+(ch3_high * 256 + ch3_low)+
(ch4_high * 256 + ch4_low)+(ch5_high * 256 + ch5_low)) / 5;
if (param.gamma == 0) param.gamma = 0.5;
prob.x = new svm_node[prob.l][6];
for (int i = 0; i < prob.l; i++) {
p = point_list.elementAt(i);
prob.x[i][0] = new svm_node();
prob.x[i][0].index = 1;
prob.x[i][0].value = p.c1;
prob.x[i][1] = new svm_node();
prob.x[i][1].index = 2;
prob.x[i][1].value = p.c2;
prob.x[i][2] = new svm_node();
prob.x[i][2].index = 3;
prob.x[i][2].value = p.c3;
prob.x[i][3] = new svm_node();
prob.x[i][3].index = 4;
prob.x[i][3].value = p.c4;
prob.x[i][4] = new svm_node();
prob.x[i][4].index = 5;
prob.x[i][4].value = p.c5;
prob.x[i][5] = new svm_node();
prob.x[i][5].index = 6;
prob.x[i][5].value = p.c6;
prob.y[i] = p.value;
}
model = svm.svm_train(prob, param);
svm_node[] x = new svm_node[6];
for(int i = 0; i < 6; i++){
x[i] = new svm_node();
x[i].index = i + 1;
}
x[0].value = (double) ch1_data / PLEN;
x[1].value = (double) ch2_data/ PLEN;
x[2].value = (double) ch3_data/ PLEN;
Group Report of 2013 SISP
36
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
x[3].value = (double) ch4_data/ PLEN;
x[4].value = (double) ch5_data/ PLEN;
x[5].value = (double) ch6_data/ PLEN;
current_value = (byte)svm.svm_predict(model, x);
//--------------------------- データの送信 ---------------------------------------// パー
if(current_value == 1){
state = "No motion";
frontPic="No_motion_01.jpg";
revPic="No_motion_02.jpg";
wport.write('1');
for(int i = 0; i< motor;i++) {
motor_count[i] = 0;
motor_data[i] = 0;
}
wport.write(oya_open);
wport.write(hito_open);
wport.write(naka_open);
wport.write(kusuri_open);
wport.write(koyubi_open);
}
// グー
if(current_value == 2){
state = "Pinch";
frontPic="Pinch_01.jpg";
revPic="Pinch_01.jpg";
wport.write('2');
wport.write(oya_close);
wport.write(hito_close);
wport.write(naka_close);
wport.write(kusuri_close);
wport.write(koyubi_close);
}
// チョキ
if(current_value == 3){
state = "Clutch";
wport.write('3');
wport.write(oya_close);
wport.write(hito_open);
wport.write(naka_open);
wport.write(kusuri_close);
wport.write(koyubi_close);
Group Report of 2013 SISP
37
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
}
}
// 手首前
if(current_value == 4){
state = "4";
wport.write('4');
wport.write(oya_open);
wport.write(hito_open);
wport.write(naka_open);
wport.write(kusuri_close);
wport.write(koyubi_open);
}
// 手首後
if(current_value == 5){
state = "5";
wport.write('5');
wport.write(oya_open);
wport.write(hito_open);
wport.write(naka_open);
wport.write(kusuri_open);
wport.write(koyubi_close);
}
//-------------------------------------------------------------------------------------------}
//--------------------------データを読み込む ---------------------------------------------void serialEvent(Serial s) {
if (s == rport) {
if (s.available() > 9) {
ch1_high = rport.read();
ch1_low = rport.read();
ch2_high = rport.read();
ch2_low = rport.read();
ch3_high = rport.read();
ch3_low = rport.read();
ch4_high = rport.read();
ch4_low = rport.read();
ch5_high = rport.read();
ch5_low = rport.read();
ch6_high = rport.read();
ch6_low = rport.read();
rport.write(50);
}
Group Report of 2013 SISP
38
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
}
}
//------------------------------Read port Clear----------------------------------void mousePreassed(){// 応急処置用のコマンド
rport.clear();
rport.write(50);
}
Group Report of 2013 SISP
39
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
6.4 ニューラルネットワーク
import processing.serial.*;
import java.util.ArrayList;
ArrayList ar1,ar2,ar3,ar4,ar5,ar6,mst,data,tstArr;
Serial rport;
Serial wport;
int DATANUM = 100;
int rdata = 0;
int motor = 3;
int DN = 200;
//------------------------- チャンネル設定 -------------------------------------double ch1_data = 0;
double [] ch1 = new double[DATANUM];//Arduino から送信されるデータ
int ch1_high = 0;
int ch1_low = 0;
double ch2_data = 0;
double [] ch2 = new double[DATANUM];//Arduino から送信されるデータ
int ch2_high = 0;
int ch2_low = 0;
double ch3_data = 0;
double [] ch3 = new double[DATANUM];//Arduino から送信されるデータ
int ch3_high = 0;
int ch3_low = 0;
double ch4_data = 0;
double [] ch4 = new double[DATANUM];//Arduino から送信されるデータ
int ch4_high = 0;
int ch4_low = 0;
double ch5_data = 0;
double [] ch5 = new double[DATANUM];//Arduino から送信されるデータ
int ch5_high = 0;
int ch5_low = 0;
//----------- 指の開閉の値 -------------//
final int oya_open = 160;
final int oya_close = 85;
final int hito_open = 160;
final int hito_close = 60;
final int naka_open = 160;
final int naka_close = 60;
final int kusuri_open = 210;
Group Report of 2013 SISP
40
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
final int kusuri_close = 90;
final int koyubi_open = 190;
final int koyubi_close = 70;
// モーターを動かす
void setup(){
size(1000,550);
background(255);
rport = new Serial(this,"COM13",115200);
wport = new Serial(this,"COM7",115200);
ar1 = new ArrayList();
ar2 = new ArrayList();
ar3 = new ArrayList();
ar4 = new ArrayList();
ar5 = new ArrayList();
ar6 = new ArrayList();
mst = new ArrayList();
data = new ArrayList();
tstArr = new ArrayList();
}
public class IrisNNControl{
ArrayList data = new ArrayList();
int idx = 0, considerNum = 10;
void readData() {
String itext;
String[] val;
int j=0;
while (j < mst.size()) {
itext=(String)mst.get(j);
val = itext.split(",");
String[] sdat = new String[7];
for (int i = 0; i < sdat.length; i++) {
sdat[i] = val[i];
}
data.add(sdat);
j++;
Group Report of 2013 SISP
41
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
}
}
void prepareInputData(double[] x) {
String[] val = (String[]) data.get(idx);
for (int j = 0; j < x.length-1; j++) {
x[j] = Double.parseDouble(val[2+j]);
}
}
void prepareOutputData(double[] y) {
String[] val = (String[]) data.get(idx);
for (int j = 0; j < y.length; j++) {
y[j] = 0;
}
int index = Integer.parseInt(val[0])-1;
y[index] = 1;
}
int randomChoose() {
return (int) (Math.random() * data.size());
}
}
class PointData{
int p1,p2,p3,p4,p5;
PointData(int a, int b, int c, int d, int e){
this.p1 = a;
this.p2 = b;
this.p3 = c;
this.p4 = d;
this.p5 = e;
}
String toString(){
return p1 + "," + p2 + "," + p3 + "," + p4 + "," + p5;
}
}
Group Report of 2013 SISP
42
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
class IrisNN extends DefaultNN {
double eps = 1e-2;
public void build() {
// 層数を決定
numOfLayer = 3;
// ニューロンを生成し配置
n = new Neuron[numOfLayer][];
n[0] = new Neuron[5+1];
n[1] = new Neuron[2000+1];
n[2] = new Neuron[6];
for (int j = 0; j < n[0].length; j++) {
//n[0][j] = new SigmoidNeuron(0.1);
n[0][j] = new LinearNeuron();
}
//System.out.println(n[0].length);// 入力層の数を表示
//System.out.println(n[1].length);// 潜れ層の数を表示
n[0][n[0].length - 1] = new FixedNeuron();
for (int j = 0; j < n[1].length; j++) {
n[1][j] = new SigmoidNeuron();
}
n[1][n[1].length - 1] = new FixedNeuron();
for (int j = 0; j < n[2].length; j++) {
n[2][j] = new SigmoidNeuron(1e-1);
}
}
}
/*
* ニューロン
* @author Hisashi
*/
interface Neuron {
/*
* ニューロンへの入力値をセットする
Group Report of 2013 SISP
43
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
* @param val 入力値
*/
void setInput(double val);
/*
* ニューロンの出力値を返す
* @return 出力値
*/
double getOutput();
/*
* 入力から出力を計算する
*/
void calculate();
/*
* 出力関数
* @param x 入力
* @return 出力
*/
double f(double x);
/*
* 出力関数の入力値での微分
* @return 関数f()の x での微分
*/
double df();
/*
* dE/ds の値をセットする
* @param val 値
*/
void setdEds(double val);
/*
* dE/ds の値を返す
* @return dE/ds の値を返す
*/
double getdEds();
}
/*
* デフォルトニューロン
Group Report of 2013 SISP
44
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
*/
class DefaultNeuron implements Neuron{
double in, out, dEds;
public void calculate() {
out = f(in);
}
public double f(double x){
return x;
}
public double df() {
double dx = 1e-4;
return (f(in+dx)-f(in))/dx;
}
public double getOutput() {
return out;
}
public void setInput(double val) {
in = val;
}
public void setdEds(double val) {
dEds = val;
}
public double getdEds() {
return dEds;
}
}
/*
* 固定出力をするニューロン
*/
class FixedNeuron extends DefaultNeuron {
/*
* 固定値 x を出力するニューロンを生成
* @param x 固定出力する値
Group Report of 2013 SISP
45
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
*/
public FixedNeuron(double x){
out = x;
}
/*
* 固定値 1 を出力するニューロンを生成
*/
public FixedNeuron(){
this(1);
}
public double f(double x){
return out;
}
public double df() {
return 0;
}
}
/*
* 線型ニューロン
*/
class LinearNeuron extends DefaultNeuron {
double a;
/*
* 傾き a のリニア出力する線型ニューロンを生成
* @param a 直線の傾き
*/
public LinearNeuron(double a){
this.a=a;
}
/*
* 傾き 1 のリニア出力する線型ニューロンを生成
*/
public LinearNeuron(){
this(1);
}
public double f(double x) {
Group Report of 2013 SISP
46
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
return a*x;
}
public double df() {
return a;
}
}
/*
* シグモイドニューロン
*/
class SigmoidNeuron extends DefaultNeuron {
double gain;
/*
* シグモイドニューロンを生成する
* @param val シグモイド関数のゲイン
*/
public SigmoidNeuron(double val){
gain=val;
}
/*
* ゲイン 5 のシグモイドニューロンを生成する
*/
public SigmoidNeuron(){
this(5);
}
public double f(double x) {
return 1/(1+Math.exp(-gain*x));
}
public double df() {
return gain*out*(1-out);
}
}
interface NeuralNetwork {
/**
* ニューラルネットワークを構築する
*/
void build();
Group Report of 2013 SISP
47
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
/**
* 結合加重を乱数で初期化する
*/
void init(double min, double max);
/**
* 入力の次数を返す
* @return 入力次数
*/
int getInputDimension();
/**
* ニューラルネットワークへの入力値を設定する
* @param val 入力値の配列。入力次数と等しい大きさの配列
*/
void setInput(double[] val);
/**
* 前進計算
*/
void forward();
/**
* 出力の次数を返す
* @return 出力次数
*/
int getOutputDimension();
/**
* 教師信号を設定する
* @param val 教師信号の配列。出力次数と等しい大きさの配列
*/
void setTeachSignal(double[] val);
/**
* 後退計算
*/
void backward();
/**
* 学習つまり結合加重の変更を行う
*/
Group Report of 2013 SISP
48
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
void learn();
/**
* 現在の評価値を返す
* (out-teach)^2
* @return 現在の評価値
*/
double eval();
/**
* ニューラルネットワークの出力を得る
* @param val 出力値を格納する配列。出力次数と等しい大きさの配列
* @return 出力値を格納した配列
*/
double[] getOutput(double[] val);
}
/**
* デフォルトニューラルネットワーク
*/
class DefaultNN implements NeuralNetwork{
/*
* numOfLayer 層数
* 各層には入力側から順に 0 オリジンの番号をつけて識別する
*
* n[ 層番号 ][ 素子番号 ] ニューロン素子
* 各素子には層内で 0 オリジンの番号をつけて識別する
*
* w[層番号 ][ 素子番号 ][ 次素子番号 ] 結合加重
* n[ 層番号 ][ 素子番号 ] から n[ 層番号 +1][ 次素子番号 ] への結合加重
*
* t 教師信号を保持する
*/
double eps = 1e-2;
int numOfLayer;
Neuron[][] n;
double[][][] w;
double[] t;
public void build() {
// 層数を決定
numOfLayer = 3;
Group Report of 2013 SISP
49
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
// ニューロンを生成し配置
n = new Neuron[numOfLayer][];
n[0] = new Neuron[3];
n[1] = new Neuron[4];
n[2] = new Neuron[1];
for (int i=0; i<numOfLayer; i++){
for (int j=0; j<n[i].length; j++){
if (i<numOfLayer-1 && j==n[i].length-1){
n[i][j] = new FixedNeuron();
}
else{
n[i][j] = new SigmoidNeuron();
}
}
}
}
public void init(double min, double max) {
// 加重結合を生成
w = new double[numOfLayer][][];
for (int i=0; i<numOfLayer-1; i++){
w[i] = new double[n[i].length][n[i+1].length];
}
// 加重結合を初期化
for (int i=0; i<numOfLayer-1; i++){
for (int j=0; j<n[i].length; j++){
for (int k=0; k<n[i+1].length; k++){
w[i][j][k] = Math.random()*(max-min)+min;
}
}
}
}
public int getInputDimension() {
return n[0].length;
}
public void setInput(double[] val) {
for (int i=0; i<n[0].length-1; i++){
n[0][i].setInput(val[i]);
}
}
Group Report of 2013 SISP
50
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
public void forward() {
for (int i=0; i<numOfLayer-1; i++){
for (int j=0; j<n[i].length; j++){
n[i][j].calculate();
}
for (int k=0; k<n[i+1].length; k++){
double in = 0;
for (int j=0; j<n[i].length; j++){
in += w[i][j][k] * n[i][j].getOutput();
}
n[i+1][k].setInput(in);
}
}
for (int j=0; j<n[numOfLayer-1].length; j++){
n[numOfLayer-1][j].calculate();
}
}
public int getOutputDimension() {
return n[numOfLayer-1].length;
}
public void setTeachSignal(double[] val) {
t = val;
}
public void backward() {
for (int i=0; i<n[numOfLayer-1].length; i++){
Neuron tn = n[numOfLayer-1][i];
tn.setdEds(2*(tn.getOutput()-t[i])*tn.df());
}
for (int i=numOfLayer-2; i>0; i--){
for (int j=0; j<n[i].length; j++){
double val=0;
for (int k=0; k<n[i+1].length; k++){
val += n[i+1][k].getdEds()*w[i][j][k];
}
n[i][j].setdEds(val*n[i][j].df());
}
}
}
Group Report of 2013 SISP
51
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
public void learn() {
for (int i=0; i<numOfLayer-1; i++){
for (int j=0; j<n[i].length; j++){
for (int k=0; k<n[i+1].length; k++){
w[i][j][k] -= eps*n[i+1][k].getdEds()*n[i][j].getOutput();
}
}
}
}
public double eval() {
double e=0;
for (int i=0; i<n[numOfLayer-1].length; i++){
e+=(n[numOfLayer-1][i].getOutput()-t[i])*(n[numOfLayer-1][i].getOutput()-t[i]);
}
return e;
}
public double[] getOutput(double[] val) {
for (int i=0; i<n[numOfLayer-1].length; i++){
val[i] = n[numOfLayer-1][i].getOutput();
}
return val;
}
public String toString() {
String ret="";
DecimalFormat dform = new DecimalFormat("##0.0##");
for (int i=0; i<numOfLayer-1; i++){
ret += "Layer"+i+"\n";
for (int k=0; k<n[i+1].length; k++){
for (int j=0; j<n[i].length; j++){
ret += "\t"+dform.format(w[i][j][k]);
}
ret += "\n";
}
ret += "\n";
}
return ret;
}
}
IrisNNControl mlc = new IrisNNControl();
Group Report of 2013 SISP
52
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
IrisNN NN;
int inD,outD;
double[] x,y;
int xp;
int yp;
int state = -1;// 処理状態を切り替えるためのスイッチ。基本は 0
/*
-1...NN生成。一回だけ
0... 基本状態
1... 学習項目 1
2... 学習項目 2
3... 学習項目 3
4... 学習実行
5... パターン認識実行
*/
int keyFrag = 0;// キー入力を受け付けるフラグ
0: 拒否
int inFrag = 0;// 座標データを配列に格納する際のフラグ
int select = 9;// ソートした配列から取得する数値の位置
1: 受理
0: 拒否
1: 受理
int i=0;//ArrayList の添字
String[] pat = {"read","oya","hito","naka","kusuri","koyubi","test","datsuryoku","nothing"};// 入力データ
作成用の文字列配列 .0 番目は不使用
int col=0;
void draw() {
if(state == -1){
NN = new IrisNN();
NN.build();
inD = NN.getInputDimension();
outD = NN.getOutputDimension();
x = new double[inD];
y = new double[outD];
state = 0;
println("CreateNN.");
}
background(255);
noStroke();
fill(180);
rect(0,400,1000,150);
Group Report of 2013 SISP
53
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
//------------------------- データインプット処理 -------------------------//
if(inFrag == 1){
if(state == 1){
int darrays1[] = new int[10];
int darrays2[] = new int[10];
int darrays3[] = new int[10];
int darrays4[] = new int[10];
int darrays5[] = new int[10];
ar1.clear();
for(int i=0; i<DN; i++){
for(int j=0; j<10; j++){
darrays1[j] = (ch1_high * 256) + ch1_low;
darrays2[j] = (ch2_high * 256) + ch2_low;
darrays3[j] = (ch3_high * 256) + ch3_low;
darrays4[j] = (ch4_high * 256) + ch4_low;
darrays5[j] = (ch5_high * 256) + ch5_low;
Meter();
Manual();
delay(10);
}
// 配列をソート
Arrays.sort(darrays1);
Arrays.sort(darrays2);
Arrays.sort(darrays3);
Arrays.sort(darrays4);
Arrays.sort(darrays5);
// 下から5番目の要素をインプット
ar1.add(new
PointData(darrays1[select],darrays2[select],darrays3[select],darrays4[select],darrays5[select]));
println(1 +":"+ i);
}
inFrag = 0;
}else if(state == 2){
int darrays1[] = new int[10];
int darrays2[] = new int[10];
int darrays3[] = new int[10];
int darrays4[] = new int[10];
int darrays5[] = new int[10];
ar2.clear();
for(int i=0; i<DN; i++){
for(int j=0; j<10; j++){
Group Report of 2013 SISP
54
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
darrays1[j] = (ch1_high * 256) + ch1_low;
darrays2[j] = (ch2_high * 256) + ch2_low;
darrays3[j] = (ch3_high * 256) + ch3_low;
darrays4[j] = (ch4_high * 256) + ch4_low;
darrays5[j] = (ch5_high * 256) + ch5_low;
Meter();
Manual();
delay(10);
}
// 配列をソート
Arrays.sort(darrays1);
Arrays.sort(darrays2);
Arrays.sort(darrays3);
Arrays.sort(darrays4);
Arrays.sort(darrays5);
// 下から5番目の要素をインプット
ar2.add(new
PointData(darrays1[select],darrays2[select],darrays3[select],darrays4[select],darrays5[select]));
println(2 +":"+ i);
}
inFrag = 0;
}else if(state == 3){
int darrays1[] = new int[10];
int darrays2[] = new int[10];
int darrays3[] = new int[10];
int darrays4[] = new int[10];
int darrays5[] = new int[10];
ar3.clear();
for(int i=0; i<DN; i++){
for(int j=0; j<10; j++){
darrays1[j] = (ch1_high * 256) + ch1_low;
darrays2[j] = (ch2_high * 256) + ch2_low;
darrays3[j] = (ch3_high * 256) + ch3_low;
darrays4[j] = (ch4_high * 256) + ch4_low;
darrays5[j] = (ch5_high * 256) + ch5_low;
Meter();
Manual();
delay(10);
}
// 配列をソート
Arrays.sort(darrays1);
Arrays.sort(darrays2);
Group Report of 2013 SISP
55
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
Arrays.sort(darrays3);
Arrays.sort(darrays4);
Arrays.sort(darrays5);
// 下から5番目の要素をインプット
ar3.add(new
PointData(darrays1[select],darrays2[select],darrays3[select],darrays4[select],darrays5[select]));
println(3 +":"+ i);
}
inFrag = 0;
}else if(state == 4){
int darrays1[] = new int[10];
int darrays2[] = new int[10];
int darrays3[] = new int[10];
int darrays4[] = new int[10];
int darrays5[] = new int[10];
ar4.clear();
for(int i=0; i<DN; i++){
for(int j=0; j<10; j++){
darrays1[j] = (ch1_high * 256) + ch1_low;
darrays2[j] = (ch2_high * 256) + ch2_low;
darrays3[j] = (ch3_high * 256) + ch3_low;
darrays4[j] = (ch4_high * 256) + ch4_low;
darrays5[j] = (ch5_high * 256) + ch5_low;
Meter();
Manual();
delay(10);
}
// 配列をソート
Arrays.sort(darrays1);
Arrays.sort(darrays2);
Arrays.sort(darrays3);
Arrays.sort(darrays4);
Arrays.sort(darrays5);
// 下から5番目の要素をインプット
ar4.add(new
PointData(darrays1[select],darrays2[select],darrays3[select],darrays4[select],darrays5[select]));
println(4 +":"+ i);
}
inFrag = 0;
}else if(state == 5){
int darrays1[] = new int[10];
int darrays2[] = new int[10];
Group Report of 2013 SISP
56
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
int darrays3[] = new int[10];
int darrays4[] = new int[10];
int darrays5[] = new int[10];
ar5.clear();
for(int i=0; i<DN; i++){
for(int j=0; j<10; j++){
darrays1[j] = (ch1_high * 256) + ch1_low;
darrays2[j] = (ch2_high * 256) + ch2_low;
darrays3[j] = (ch3_high * 256) + ch3_low;
darrays4[j] = (ch4_high * 256) + ch4_low;
darrays5[j] = (ch5_high * 256) + ch5_low;
Meter();
Manual();
delay(10);
}
// 配列をソート
Arrays.sort(darrays1);
Arrays.sort(darrays2);
Arrays.sort(darrays3);
Arrays.sort(darrays4);
Arrays.sort(darrays5);
// 下から5番目の要素をインプット
ar5.add(new
PointData(darrays1[select],darrays2[select],darrays3[select],darrays4[select],darrays5[select]));
println(5 +":"+ i);
}
inFrag = 0;
}else if(state == 6){
int darrays1[] = new int[10];
int darrays2[] = new int[10];
int darrays3[] = new int[10];
int darrays4[] = new int[10];
int darrays5[] = new int[10];
ar6.clear();
for(int i=0; i<DN; i++){
for(int j=0; j<10; j++){
darrays1[j] = (ch1_high * 256) + ch1_low;
darrays2[j] = (ch2_high * 256) + ch2_low;
darrays3[j] = (ch3_high * 256) + ch3_low;
darrays4[j] = (ch4_high * 256) + ch4_low;
darrays5[j] = (ch5_high * 256) + ch5_low;
Group Report of 2013 SISP
57
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
Meter();
Manual();
delay(10);
}
// 配列をソート
Arrays.sort(darrays1);
Arrays.sort(darrays2);
Arrays.sort(darrays3);
Arrays.sort(darrays4);
Arrays.sort(darrays5);
// 下から5番目の要素をインプット
ar6.add(new
PointData(darrays1[select],darrays2[select],darrays3[select],darrays4[select],darrays5[select]));
println(6 +":"+ i);
}
inFrag = 0;
}else if(state == 8){
PointData testData = new PointData((ch1_high * 256) + ch1_low,(ch2_high * 256) + ch2_low,
(ch3_high * 256) + ch3_low,(ch4_high * 256) + ch4_low,(ch5_high * 256) + ch5_low);
Test(4 +","+ pat[4] +","+ testData.toString());
}else if(state == 0){
wport.write('6');
wport.write(oya_open);//oya
wport.write(hito_open);//hitosashi
wport.write(naka_open);//naka
wport.write(kusuri_open);//kusuri
wport.write(koyubi_close);//koyubi
}
}
//---------------------------------------------------------------------//
Meter();
Manual();
}
void Meter(){
textSize(18);
text("ch1 = " + ((ch1_high * 256) + ch1_low), 100, 340);
text("ch2 = " + ((ch2_high * 256) + ch2_low), 200, 340);
text("ch3 = " + (ch3_high * 256 + ch3_low), 300, 340);
text("ch4 = " + (ch4_high * 256 + ch4_low), 400, 340);
text("ch5 = " + (ch5_high * 256 + ch5_low), 500, 340);
Group Report of 2013 SISP
58
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
rect(110,300,70,-(ch1_high * 256 + ch1_low)/6);
rect(210,300,70,-(ch2_high * 256 + ch2_low)/6);
rect(310,300,70,-(ch3_high * 256 + ch3_low)/6);
rect(410,300,70,-(ch4_high * 256 + ch4_low)/6);
rect(510,300,70,-(ch5_high * 256 + ch5_low)/6);
}
void Manual(){
fill(0);
textSize(15);
text("Input",20,420);
textSize(13);
text("Shift + 1",20,440);
text("Shift + 2",20,460);
text("Shift + 3",20,480);
text("Finish input",20,510);
text("Shift + f",20,530);
textSize(15);
text("Learning",120,420);
textSize(13);
text("Shift + l",120,440);
textSize(15);
text("ArraySize", 520,420);
textSize(13);
text("Array 1: " + ar1.size(),520,440);
text("Array 2: " + ar2.size(),520,460);
text("Array 3: " + ar3.size(),520,480);
text("Array 4: " + ar4.size(),520,500);
text("Array 5: " + ar5.size(),520,520);
text("Array 6: " + ar6.size(),600,440);
text("Array mst: " + mst.size(),520,540);
textSize(15);
text("Test",220,420);
textSize(13);
text("Shift + t",220,440);
textSize(15);
text("Reset all",220,480);
textSize(13);
text("Shift + r",220,500);
Group Report of 2013 SISP
59
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
textSize(15);
text("Flags",320,440);
textSize(13);
text("state: " + state,320,460);
text("Shift: "+ keyFrag,320,480);
textSize(15);
text("Judge",320,520);
textSize(13);
text(pat[col],320,540);
textSize(15);
text("Read Data", 420,440);
textSize(13);
text(rdata,420,460);
}
//--------------- キー入力処理 ---------------------//
void keyPressed(){
if(keyCode == SHIFT){
keyFrag = 1;
rdata = 0;
}
if(keyFrag == 1){
if(key == '1'){
state = 1;
inFrag = 1;
keyFrag = 0;
}else if(key == '2'){
state = 2;
inFrag = 1;
keyFrag = 0;
}else if(key == '3'){
state = 3;
inFrag = 1;
keyFrag = 0;
}else if(key == '4'){
state = 4;
inFrag = 1;
keyFrag = 0;
}else if(key == '5'){
Group Report of 2013 SISP
60
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
state = 5;
inFrag = 1;
keyFrag = 0;
}else if(key == '6'){
state = 6;
inFrag = 1;
keyFrag = 0;
}else if(key == 'l'){
state = 7;
inFrag = 1;
keyFrag = 0;
Learn();
}else if(key == 't'){
state = 8;
inFrag = 1;
keyFrag = 0;
println("Test mode");
}else if(key == 'f'){// データ入力終了。全てのフラグをリセット
keyFrag = 0;
state = 0;
inFrag = 0;
i = 0;
}else if(key == 'r'){// 全データ削除。リセット
keyFrag = 0;
state = 0;
inFrag = 0;
i = 0;
arClear();
wport.write(160);
wport.write(160);
wport.write(160);
wport.write(210);
wport.write(190);
background(255);
}
}
}
void arClear(){
ar1.clear();
ar2.clear();
ar3.clear();
Group Report of 2013 SISP
61
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
ar4.clear();
ar5.clear();
ar6.clear();
mst.clear();
data.clear();
tstArr.clear();
}
void Learn(){
getData(ar1,1);
getData(ar2,2);
getData(ar3,3);
getData(ar4,4);
getData(ar5,5);
getData(ar6,6);
mlc.readData();
int ncount = 0, loopCount=0;
double E;
NN.eps = 1e-3;
int maxLoop = (int)2e+3;
//int maxLoop = (int)1;
double th = 0.5;
// 学習
do {
loopCount++;
NN.init(-1, 1);
E=0;
for (int i = 0; i < maxLoop; i++) {
mlc.idx = mlc.randomChoose();
mlc.prepareInputData(x);
NN.setInput(x);
NN.forward();
mlc.prepareOutputData(y);
NN.setTeachSignal(y);
NN.backward();
NN.learn();
E += NN.eval();
}
E/=maxLoop;
Group Report of 2013 SISP
62
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
System.out.println("eval = "+E+"("+loopCount+")");
} while (E>th);
}
//ar1,2,3 のデータを取得、変換し、 mst に格納する。
void getData(ArrayList arr,int n){
for(int i=0; i<arr.size(); i++){
mst.add(n +"," + pat[n] +","+ arr.get(i).toString());
}
}
void Test(String st){
double[] inData = new double[5];
inData = consd(st);
NN.setInput(inData);
NN.forward();
y = NN.getOutput(y);
println("-------------------");
println("y[0]=" + y[0]);
println("y[1]=" + y[1]);
println("y[2]=" + y[2]);
println("y[3]=" + y[3]);
println("y[4]=" + y[4]);
println("y[5]=" + y[5]);
println("-------------------");
double thOut = 0.5;
if((1-y[0]<thOut) && (y[1]<thOut) && (y[2]<thOut) && (y[3]<thOut) && (y[4]<thOut) && (y[5]<thOut))
{//脱力状態
println("oya");
col=1;
wport.write('1');
wport.write(oya_close);//oya
wport.write(hito_open);//hitosashi
wport.write(naka_open);//naka
wport.write(kusuri_open);//kusuri
wport.write(koyubi_close);//koyubi
}else if((y[0]<thOut) && (1-y[1]<thOut) && (y[2]<thOut) && (y[3]<thOut) && (y[4]<thOut) &&
(y[5]<thOut)){// 掴む
println("hitosashi");
wport.write('2');
col=2;
wport.write(oya_open);//oya
Group Report of 2013 SISP
63
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
wport.write(hito_close);//hitosashi
wport.write(naka_open);//naka
wport.write(kusuri_open);//kusuri
wport.write(koyubi_open);//koyubi
}else if((y[0]<thOut) && (y[1]<thOut) && (1-y[2]<thOut) && (y[3]<thOut) && (y[4]<thOut) &&
(y[5]<thOut)){// 摘む
println("naka");
wport.write('3');
col=3;
wport.write(oya_open);//oya
wport.write(hito_open);//hitosashi
wport.write(naka_close);//naka
wport.write(kusuri_open);//kusuri
wport.write(koyubi_open);//koyubi
}else if((y[0]<thOut) && (y[1]<thOut) && (y[2]<thOut) && (1-y[3]<thOut) && (y[4]<thOut) &&
(y[5]<thOut)){
println("kusuri");
wport.write('4');
col=4;
wport.write(oya_open);//oya
wport.write(hito_open);//hitosashi
wport.write(naka_open);//naka
wport.write(kusuri_close);//kusuri
wport.write(koyubi_open);//koyubi
}else if((y[0]<thOut) && (y[1]<thOut) && (y[2]<thOut) && (y[3]<thOut) && (1-y[4]<thOut) &&
(y[5]<thOut)){
println("koyubi");
wport.write('5');
col=5;
wport.write(oya_open);//oya
wport.write(hito_open);//hitosashi
wport.write(naka_open);//naka
wport.write(kusuri_open);//kusuri
wport.write(koyubi_close);//koyubi
}else if((y[0]<thOut) && (y[1]<thOut) && (y[2]<thOut) && (y[3]<thOut) && (y[4]<thOut) && (1y[5]<thOut)){
println("datsuryoku");
col=7;
wport.write('6');
wport.write(oya_open);//oya
wport.write(hito_open);//hitosashi
wport.write(naka_open);//naka
wport.write(kusuri_open);//kusuri
Group Report of 2013 SISP
64
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
wport.write(koyubi_open);//koyubi
}else{
println("nothing");
col=8;
}
}
public static double[] consd(String st){
String stArray[] = st.split(",");
println(Arrays.toString(stArray));
double[] dArray = new double[5];
dArray[0] = Double.parseDouble(stArray[2]);
dArray[1] = Double.parseDouble(stArray[3]);
dArray[2] = Double.parseDouble(stArray[4]);
dArray[3] = Double.parseDouble(stArray[5]);
dArray[4] = Double.parseDouble(stArray[6]);
println(Arrays.toString(dArray));
return dArray;
}
void conArray(){
mst.addAll(ar1);
mst.addAll(ar2);
mst.addAll(ar3);
mst.addAll(ar4);
mst.addAll(ar5);
mst.addAll(ar6);
}
//--------------------------データを読み込む ---------------------------------------------void serialEvent(Serial s){
if(s == rport){
if(s.available() > 13){
ch1_high = rport.read();
ch1_low = rport.read();
ch2_high = rport.read();
ch2_low = rport.read();
ch3_high = rport.read();
ch3_low = rport.read();
ch4_high = rport.read();
ch4_low = rport.read();
Group Report of 2013 SISP
65
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
ch5_high = rport.read();
ch5_low = rport.read();
rport.write(50);
}
}
}
Group Report of 2013 SISP
66
Group Number 22 - Group A
Development of myoelectric hand with feeling softness
参考文献
[1] Nello Cristianini, John Shawe-Taylor 著, 大北剛訳:サポートベクターマシン入門 ,
共立出版
, 2005
[2] 熊沢逸夫:学習とニューラルネットワーク
森北出版株式会社 , 1998第一版第一刷発行
Group Report of 2013 SISP
67
Group Number 22 - Group A