へっぽこ元ロボコニスト

ロボコンに燃え尽きた自分が日々の出来事を書くだけのブログです twitter:@mozyanari_tech

MENU

2023年年度末にやりたいこと

めっちゃ久しぶりに記事を書く
最近はOpenAIのAPIを触るのにハマっています


前回の更新は2022年2月でした
働き始めてから2年目で少し余裕も出てきて、会社から帰ってからValorantをしていました
あれから、約2年が経ち、なぜか仕事でプログラムを触っています
最初の配属はメカ設計でしたが紆余曲折あり、今のところにお世話になっています

そんな自分がなぜまた記事を書いているかというと、次のステップへ向けてまた自分が勉強したことをアウトプットしないといけないと思い始めたからです
せっかく仕事で色んな事を学べているので、仕事に関係しない部分でアウトプットを出していければいいなと思っています

なので、とりあえずは年度末にしようと思っていること一覧です

プログラミング以外の本を読む

仕事で複数人ですることになるので、プログラムが組めるだけでなく、
他の人が読みやすいプログラム、アーキテクチャ、要件定義など上流部分にも目を向けていきたいと思っています
その取っ掛かりとして様々な視点を得るためプログラミング以外の本を読みます
例えばこれとか
Good Code, Bad Code ~持続可能な開発のためのソフトウェアエンジニア的思考


プログラミング以外の環境構築を学ぶ

仕事ではPythonやTypescriptを触っていますが、
これらの言語を使って何かを実現する時の周辺のDockerやnode js、ビルドシステムなど周辺環境がブラックボックスのまま進んでいます
このままではフレームワークの上で遊んでいるだけなのでもう少し深いところまで学びたいと思っています

技術記事を書く

特に仕事では
ReactのフレームワークでTypescriptを使ってUIを作る
クラウドでデータベースを立ち上げて、ロボットのデータを入れる
ChatGPTのAPIを使ってLLMで遊ぶ
をやっているので、これまでやっていた組み込みとかではない記事をまとめて書きたいと思っています

資格を取る

会社からクラウド系の資格の補助が出るので、とりあえず受けます
また、去年不合格だった応用情報技術者試験は春に受けようと思っているので、再度勉強します

自分のホームページを作る

仕事で学んだことを活かして全く別のHPを立てようとしています
おそらくはこのHPで技術ブログとかを書こうかなと思っています
あと、これとは別に収益が出そうなHPを作ろうとしています

人生を進める

さすがにこの歳になったのでそろそろ結婚しないといけないなと焦っています
ただ、このまま何もなければ本当にお金をためて大学院に行くことになりそうです

さて、頑張ります


なんでこの記事を書こうと思った理由ですが、
大学時代に聞いていたヒルクライムの音楽が流れてきて、
大学生の時によくヒルクライムの音楽を聴きながら記事を書いていたなぁと思って書きました
www.youtube.com

Riotアカウントのメールアドレスを乗っ取られて取り返すまで

こんなくそ雑魚アカウントを乗っ取る必要なんてあるのか・・・・・?

Valorantでアイアンとブロンズを行き来しているエンジョイプレーヤーです。
最近、弟からLogicoolのワイヤレス無線マウスとキーボードをもらって楽しくゲームをしています。

そんなある日、Riotから以下のメールが届きました。

「Riotアカウントに紐づくメールアドレスの変更が完了しました」
いやいやこんな変更してないよ・・・・?
ログインしてパスワード変更をしようとしても、
認証先のメールアドレスが変更されているので変更できません。

あとで分かったのですが、昨年にパスワードが流出していたようで、
自分のアカウントに誰かがログインして、
サポートにメルアド変更を何回も要求していたようでした。
(なんの確認もせずメルアド変更するサポートはやばいとは思いますが・・・・・)
www.valorant4jp.com


ここからは、メルアドをもとに戻してもらうまでの過程です。

メルアドの乗っ取りを取り返すまでの過程

ライアットのプレイヤーサポートに飛ぶ


今自分がしているゲームを選択


これはRiotのアカウントが自分がものであることを証明するために、
「最近ゲーム内で購入したものは?」
「最近いつログインした?」
などの質問があるため、
直近で自分がしているゲームだと証明しやすいと思います。
自分はvalorantを選択しました。

問い合わせを選択


ページの真ん中ほどに問い合わせがあるので選択します。

「アカウントにログインできない、アカウントを復旧する」を選択


リクエストを記入して送信


この画面で記入可能なところは記入して送信します。
ただ、この時自分は、
「ゲーム内通貨(RP、VP、コインなど)を購入していましたか?」
を「はい」にすると、クレジットカードの最初の6桁と最後の4桁を聞かれたのですがこれには答えず、「過去にメールで受け取ったこのアカウントの取引番号または確認番号」を記入しました。

過去にvalorantのバトルパスを購入したのですが、
この時のメールアドレスに取引番号があったのでこれを書きました。
おそらくこれが本人の証明に一番効いたのだと思います。

返信が来るのを待つ


リクエストに記入したメールアドレスにリクエストを受け付けましたよの確認メールが来るので返信が来るまで待ちます。
自分は土曜日の10時頃にリクエストを送ると、11時ごろに返信が来ました。
(土曜日なのに中の人ありがとうございます)

新規のメールアドレスを返信する


人によっては本人確認が必要だと思うのですが、自分はバトルパスの購入履歴があったのでこれが本人確認の証拠になった?ので新規のメールアドレスを返信してほしいというメールが来ました。
(なので、ハッキング対策で一度はバトルパスを課金しよう!)
今までとは違うメールアドレスをサポートに送りました。

新規のメールアドレスからパスワード変更してアカウントを取り戻す

新規のメールアドレスを送ると、5分後には新規のメールアドレス先にパスワードリセットのURLが来ました。
このURLからパスワード変更してアカウントを取り戻せました。
このあと、すべての機器から一度アカウントをログあyとをして、メールアドレスの2段階認証をすぐにONにしました。

初めてハッキングされてめっちゃ焦ったのですが、すぐに取り返せてよかったです。
また、サポートの返信も早くて対応もよかったので、次のシーズンもバトルパスを買おうと思います。

DaVinci Resolve起動時にMinGW Runtime Assertionが出て起動できないのを解決する

動画編集難しい・・・・

動画を作るためにAdobe Premiere Proを体験版で使っていましたが、正直使いこなせないし2週間程度しか使わないのが大半です
なので、DaVinci Resolveを使おうと思ってインストールして起動するのですが、以下のようなMinGW Runtime Assertionのエラーが出ました
f:id:masanari7430:20210928133528p:plain

これを解決するには、以下の過去記事にあったCatalyst Browseのエラーと同様にIntel Graphics バージョンを最も古いものにすると解決できました
他の解決方法を見るとグラフィックを削除や停止をしているものが見られますが怖いので自分はやっていません


mozyanari.hatenablog.com

自作PCだと動画編集するために設定を色々いじらないといけないの面倒だなぁ

Catalyst Browseが起動しないのを解決する

最近はフォトコンテストに出す写真をひたすら撮るために外出中

a7cで動画を撮っていますがその時に問題になるのは動画の手振れです
これを解消するためにジンバルを使っていますが、正直友達との旅行中にこれを振り回すのはかなり勇気がいります

なので、ソフトウェアで補正出来なかと思っていた時に、Catalyst Browseを見つけました
www.sonycreativesoftware.com

撮った動画のジャイロセンサ情報から傾きを検知して補正するらしいです
結構簡単にできそうと思ったので、インストールして試してみようと思いました

ですが、起動時に
Catalyst Browse.exeが応答していません」
というエラーが出ました
f:id:masanari7430:20210925144712p:plain

ここからは、以下の文献を参考にエラーを解消して起動するまでのメモ書きを残していきます
www.sumhit.jp

結論を先に書いておくと、Intel Graphics バージョンを最も古い奴に変更する必要があります

PCの構成

自分のPCは
CPU:Intel Core i5-6500@3.2GHz
マザーボード:H110M PRO-VH PLUS
GPU:GEFORCE GTX 1050Ti

ただ、最も重要なのは
Intel Graphics Ver: 27.20.100.8681
f:id:masanari7430:20210925143306p:plain

この数字です

この数字は、デバイスマネージャ上で調べることが出来ます
f:id:masanari7430:20210925150444p:plain

Intel Graphicsのバージョンを変更する

参考文献によると、バージョンを変更する必要がありそうだったので以下のサイトから
インテルのグラフィックドライバをダウンロードしました
www.intel.com

ただ、これは自分の場合のグラフィックドライバーのダウンロード方法なので、
グラフィックドライバーの探し方を以下に書いておきます

インテルのホームページからダウンロードセンターに行く

www.intel.com
f:id:masanari7430:20210925150851p:plain

ダウンロードセンターからグラフィックを選択

f:id:masanari7430:20210925151301p:plain

検索窓に自分のCPUの型番を入れる

f:id:masanari7430:20210925151416p:plain

DCH Driverを選択する(これは人による?)

f:id:masanari7430:20210925151604p:plain
自分はDCHドライバを選択しました
BETAはさすがに対応してなさそうだったのと、DCHがついていないドライバは数年前で更新が止まっていたのでDCHドライバにしました

古いバージョンの中で最も最後にリリースされたドライバを選ぶ

f:id:masanari7430:20210925151922p:plain
自分の場合はバージョン26が古かったので26の中で最後にリリースされたものを選びました

exeファイルをダウンロードしてインストール

f:id:masanari7430:20210925152117p:plain
おすすめでは.zipファイルでダウンロードすることを推奨されています
ですが、デバイスドライバからzipファイルを使って更新しようと思っても新しいドライバが入っているのでダウンロードできませんと拒否されます
なので、exeファイルからインストールする必要があります

f:id:masanari7430:20210925152735p:plain
インストールの終了後、グラフィックドライバのバージョンを確認するとちゃんと古いものに置き換わっていました
そして、Catalyst Browseを起動してみるとエラー無く起動しました
f:id:masanari7430:20210925152912p:plain

起動したが・・・・

これで起動がようやくできました
また、参考文献にあったようにグラフィックドライバを自動更新できないようにしておく必要があると思います
www.sumhit.jp


ですが、撮った動画をの手振れ補正をかけることはできませんでした・・・・
それは以下の理由からです
tecstaff.jp
f:id:masanari7430:20210925142318p:plain

それは知らんわーーー
今回撮った動画は、スローで使う可能性があったので全て120pで撮影しています
また、手振れ補正も入れています

なので、Catalyst Browseが起動しましたが自分の撮影した動画では傾き補正はできませんでした・・・・・

つまり、ジンバルで補正しろってことですねーーーー

以上、頑張って起動はしたけど結局使いませんでした

FeiyuTech G6 Maxをsonyのa7シリーズに接続する

カメラ沼にハマりそう?

自分は旅行で動画を撮るために
フルサイズのミラーレス一眼のa7cと
www.sony.jp

ジンバルのFeiyuTech G6 Maxを持っています
www.amazon.co.jp

FeiyuTech G6 Maxが2020年5月5日以降更新が行われておらず
公式ではジンバルの手元のボタンでシャッターを押せたり、録画が出来る方法が紹介されていません
ただ、a7cは以前のカメラとソフトの部分は変化していないようなので
似た方法で出来るのではと思って試した結果できたので、備忘録として書いておきます

公式の情報

公式の情報は2020年5月5日以降停止しています
なのでa7cは公式でサポートされていません
www.feiyu-tech.jp
http://2258d491506853e.main.jp/feiyu/catalog/G6Max_SupportedCamera_2006.pdf

必要なもの

  • FeiyuTech G6 Maxに同梱されているtype-C to type-Cケーブル

f:id:masanari7430:20210704122939j:plain

これだけです

接続方法

f:id:masanari7430:20210704122002j:plain
画像のようにFeiyuTech G6 Maxとa7cをケーブルで接続します

a7の設定方法

  • 設定画面から「ネットワーク1」→「PCリモート機能」

f:id:masanari7430:20210704122446j:plain

  • 「PCリモート」を入、「PCリモート接続方式」をUSBに変更

f:id:masanari7430:20210704122635j:plain

  • 「静止画の保存先」をカメラ本体のみに変更

f:id:masanari7430:20210704123041j:plain

これで、手元で操作が出来るようになります

注意点

「PCリモート」を入にしていると、スマートフォン転送が出来ないので
スマートフォン転送を行う際には、「PCリモート」を切にする必要があります

まとめ

FeiyuTech G6 Maxでもa7cに有線接続して、手元で操作できるようになりました
ただ、無線で接続することはいろんな方法を試したのですが自分は出来ませんでした
もし可能なら教えて頂きたいです

ただ、自分はFeiyuTech G6 Maxを安かったので購入したのですが
数年で切れたサポート、などを考えると少し高くてもDJIのジンバルを買っておけばと少し後悔しています
また、FeiyuTech G6 Maxにa7c+SEL35F18F or キットレンズの組み合わせでバランスが取れていますが
これ以上大きいレンズはきついかなと感じています

2021/04/04(プロポのサーボ信号を受信したい)

社会人二年目

前回、PWM Inputを使って自分で出したPWM信号を受信しました
mozyanari.hatenablog.com

このコードで実際のプロポを接続してサーボ信号を受信しようとしたのですが、
信号の周期、Duty比を計算したところ少し汚い数字が出てきました
f:id:masanari7430:20210404202647p:plain
b=55000、クロックの8Mhzなので
8*10^6 / 55000 =145Hz

なので、実際にプロポのサーボ信号をロジアナで確認してみました
f:id:masanari7430:20210329143904p:plain

見てみると、
周期15ms=66Hz、Duty比10%の信号が出ていました
計算と異なります

よく考えてみると、前回の記事でも言及しましたが現在の設定では
8Mhzのクロックでカウンタが動き、Max 65535カウントしかできないので、
8*10^6/65535=122Hz
以上の周期しか正しくカウントできません

そりゃ計算の結果がおかしくなるわ

という訳で、以下のようにプリスケーラの設定を0→7に変更して
カウンタクロックを8Mhzから1MHzに変更しました
f:id:masanari7430:20210404204213p:plain
こうすることで
1*10^6/65535=15Hz
以上のサーボ信号を受信できます

やってみた結果は以下のようになり
f:id:masanari7430:20210404203604p:plain
b=15000、クロック1Mhzなので
1*10^6 / 15000 =66Hz
となり、想定していた通りの結果が出ました
(c、dの値は変更する前の値を表示しています)

また、余談ですがプロポのサーボ信号の上限、下限、ニュートラルは意外と狭く
今回の設定ではカウンタが2000(13%)→1000(6%)→1500(10%)これぐらいの変化量です

結局言いたかったのは、プロポの信号は意外と遅いので設定をしないと値が取れないということです
次はモータを動かします

2021/03/01(IdeaPad Slim 550にSSDを増設する)

SWITCH買ったけど全然有効活用できてない

現在持っているノートPCがThink Pad X220で起動するだけでCPUが50%、web閲覧で80%とかなりやばい状態でした
ロボコンするにあたってSTM32CubeIDEなどでプログラムを書く必要があるのでノートPCを新調しました

選んだ基準としては
CPUはRyzen
メモリは16GB
ストレージはSSD 512GB
お値段は10万以下
を目安にして選びました
また、ROSでも使用したかったので
Ubuntuデュアルブートできればいいなとも考えていました

そこで自分が選んだのは
IdeaPad Slim 550です

このPCは
CPU:Ryzen 4700
メモリ:16GB
ストレージ:512GB SSD
です
さらにこのPCは、SSDが増設できます!
つまり、SSDを分けてwindowsUbuntuを入れることが出来ます

以下に自分がSSDを増設するまでの手順を備忘録として残します


裏面のネジを外す

t5のトルクスドライバーを使って裏面を外します
f:id:masanari7430:20210301222002j:plain
ただ、上側の3本は裏面のカバーから外せないので無理に引き抜かないようにします
f:id:masanari7430:20210301222140j:plain

裏面の天板を外す

裏面の天板を外しますが、左上のデイズプレイのヒンジ部分にある隙間から開きます
少し開くとあとは隙間に爪を入れて外周をはがしていきます
ですが、天板の構造上はがしていく際に中の引っかかり部分が折れますw
f:id:masanari7430:20210301222409j:plain
スマホ分解用の薄いペラがあれば出来るかもしれませんが、どうせネジで止めるので気にしないようにしましょう

SSDを取り付ける

中を開けてみるとSSDの取り付け部がありますが、大きさは以下の写真のようなサイズです
f:id:masanari7430:20210301223257j:plain
f:id:masanari7430:20210301222935j:plain
なので、type2280のSSDを取り付けます
自分はSumsungのSSDを買って取り付けました

(個人的にサムスンラズベリーパイに使用するmicroSDカードを選定した際に最も壊れなかったSDカードだったため、ストレージでは最も信頼しています)

取り付けてみたのがこんな感じです
f:id:masanari7430:20210301223602j:plain

windowsに認識させる

差しただけではフォーマットも何もされていないのでwindowsに認識させます
手順としては、「ディスクの管理」からフォーマットをするだけです
f:id:masanari7430:20210301223908j:plain
これでボリュームDとして認識されて増設が完了しました
f:id:masanari7430:20210301224053j:plain

まとめ

裏の天板をはがした際に中の爪が折れたのはショックでしたが、見えないので気にしないことにします
これで、WindowsとROSを同時にノートPCで環境を作れるのでロボコンに役立てたいと思います

2020/12/29(STM32におけるPWM Inputの使い方)

社会人はちゃんと休みがあっていい
けど、平日は何もできない

前回の記事はこちら
mozyanari.hatenablog.com


現在、川ロボに出るための基板とプログラムを作成していますが、プロポと通信するためにサーボ信号を読み取る必要があります
ですが、ネットを検索しても出てくるのはInput Captureを使用した例しかありませんでした
自分はCube MXでCombined Channelsで選択できるPWM Input on CHxでやりたかったので、調べてやってみました

今回参考にしたのは以下のSTの公式サンプルです
www.stmcu.jp

このサンプルは他の機能も動くサンプルが入っているので、割り込みの初期化、タイマーの起動方法などCubeMXでポチポチしただけでは動かないときに見るといいと思います

また、私は前回の記事のようにSTM32F303K8の自作ボードを使用しています
mozyanari.hatenablog.com

なので、STM32F3シリーズのリファレンスマニュアルも参考にしました
www.stmcu.jp

PWM Inputの動きについて

リファレンスマニュアルにどのようにPWM Inputが動いているかが分かる説明があります
f:id:masanari7430:20201229012914p:plain
f:id:masanari7430:20201229013222p:plain

結局、Input Captureと同じなんですね
Input Captureを読んでいくと以下の記述があります
f:id:masanari7430:20201229013114p:plain

つまり、TIMxのCCRxを読みに行けばタイマのカウント値が入っているので、タイマのカウントスピードからPWMのDuty比、周波数が割り出せそうです

CubeMXの設定

今回はTime15を使用してPWM Inputを行います
まずは、「Combined Channels」で「PWM Input on CH2」を有効にします
(CH1でも可)
f:id:masanari7430:20201229010839p:plain

そうすると、PA3がTIM15_CH2になります
(他のピンはPWM出力や、LEDデバックの為に使用しています)
f:id:masanari7430:20201229010957p:plain

次に、Configurationをいじりたいですが動くのを確認するのであればこのままで大丈夫です
f:id:masanari7430:20201229011108p:plain

※詳しく説明すると、PrescalerでClockConfigurationのAPB1を分周します
自分は0なので分周せず、8MHzそのまま使用します
Counter Periodでカウンタの最大値を決めます
この値が大きいほどカウンタがたまる時間を待つことが出来て、低周波数のPWMを測定できます
今回の自分の場合は、8*10^6/65535=122HzまでのPWMを観測できます
詳しくは以下のページに乗っています
controllerstech.blogspot.com

これでCubeMXの準備は完了です

プログラム

初期化を追加

ここが最大の難関でした
先ほどあったようにTIM15のCCR1とCCR2を読みに行けばカウント値が入るはずなのですが動かしてもCubeMXの初期化だけでは何も動きませんでした
そこでサンプルを見てみるとCubeMXの初期化にはない以下の関数を見つけました
f:id:masanari7430:20201229013738p:plain
(これはサンプルの「STM32F3-Discovery」→「Examples」→「TIM」→「TIM_InputCapture」にあります)

なので以下のようにmain分のTIM15の初期化の下のユーザコードに書きます
f:id:masanari7430:20201229013949p:plain

(ここで行われているのは割り込みの初期化です
割り込みの初期化なんか関係あるのかと思っていましたが、InputCaptureの説明の箇所に割り込み発生時のカウントをCCRに格納しているらしいので割り込みが必要になります)

タイマのカウント値を確認

これで初期化が出来たのでPWMのパルスに応じて変化するかを確認します
今回はPWM周波数1kHzで幅を50%→30%→10%と変化させて値が変化するかを確認します
main文に以下のようなプログラムを書きます
f:id:masanari7430:20201229014602p:plain

PWMのパルス幅を変化させてその後、TIM15のCCR1とCCR2の値をデバッカで確認します

f:id:masanari7430:20201229014822p:plain
f:id:masanari7430:20201229014849p:plain
f:id:masanari7430:20201229014918p:plain

CCR2は8000の値で固定されています
これは、タイマのカウント8Mhzなので、8*10^6/8*10^3=1kHzでPWMの周波数と一致しています
また、CCR1は4000→2400→800となっています
これはPWMのduty比を50%→30%→10%と変化させているので一致しています

これでPWM Inputは使えそうです
ただ、これが完成した後に複数のPWMを同期的に取得する必要があることが分かったので、結局Input Captureを使用することになりそうです・・・・

自分用追記
今回はPA3を受信用のピンとしているので、TIM15のCH2がタイマのリセットタイミングとなっている
そのため、自分の直感に沿っている設定方法としては、CH2立ち上がりに設定する

プロポで実際に受信するときの記事を書きました
mozyanari.hatenablog.com

2020/7/9(STM32F303K86Tの自作ボードにおける電源接続部分)

最近初めてSpotifyを使い始めたのですがサジェストされる曲が刺さり過ぎるので永遠に聞いています

前回の記事はこちら mozyanari.hatenablog.com

前回は書き込み部分について書きましたが、次は電源について書きます

電源部分

3.3V

f:id:masanari7430:20200709215749p:plain
STM32F303において3.3Vは1、5、17ピンのVDDとVDDAに接続します
VDDとVDDAは何が違うのとなりますが、VDDはIOピンのための電源供給、VDDAはDACやADCなどのアナログ系のための電源供給です

GND

f:id:masanari7430:20200709215732p:plain
GNDは16、32ピンのVSSに接続します
(これを見て疑問に思うのですが、結局GND接続するはずなのになぜVSSという名前になっているかが毎回疑問に感じます)

またこれらの接続については公式のリファレンスに詳しく載っているので、ADCをガチで使ったりする際にはよく読む必要があります
(まあ、ロボコンではいらないでしょう)

他のボードでは?

今回使用するSTM32F303K86Tは電源系のピンはこれぐらいになります
ただ、以前STMのサンプル請求をしたときに64ピンのSTM32F405RGTを入手して自作基板を作ったことがあります
その時もう少し電源周りのピンが多くてどうしたらいいのか最初は分かりませんでした
なのでその部分について追加で書いておきます

VBAT、VCAP


見慣れないVBATとVCAPがありますが、VBATは外部のRTC用の電源、VDDが供給されなかったときのバックアップレジスタの電源として使われるようです
(バックアップレジスタって何?まあロボコンでは使わないでしょう)
なので使わないにしてもとりあえず繋いでおきましょう
またこれも公式のリファレンスに書かれています

VCAPは公式を翻訳すると、
「メインレギュレータの安定化は、VCAP_1/VCAP_2 端子に外付けコンデンサ CEXT を接続することで実現します。CEXTは表16に規定されています。」

おそらくこのレギュレータは電圧を降下させるためのレギュレータではなく、Voltage regulatorと呼ばれる電圧を監視して低電圧モードなどに移行するためのレギュレータ(制御器)っぽいです

なのでここには2.2uFのコンデンサを付けておきましょう
あと書いているときに気づいたのですがこれを付けると2つのマイコンパスコンを外してもいいそうです

2020/7/7(STM32F303K86Tの自作ボードにおける書き込み部分の回路)

社会人になってもロボコン

大学院生活も終わり社会人になりました
コロナのせいで同期にも全く会えず、「あれ社会人ってこんなんやったけ?先輩に聞いてたのと違うぞ?」と思いながら日々を過ごしていました
(先輩に聞いていた社会人生活だと研修で女子と出会って色々あるはずでは?)

そしてコロナが少し収まりかけたころ、ようやく寮に入って同期に会えました
その中に寮で川ロボに参加している人がいて、話を聞いているとメカはやっているけど回路と制御は何も入れていないということでした

そこで「自分がやってもいい?」と聞くと「いいよ」という返事をもらったので社会人でもロボコンをやることになりました
(こういうことしてるから彼女が出来ないんだぞ)
(あと、今年の川ロボは無くなったのに、出会ってから1か月でボード設計を終わらせたので若干引かれました)

どういう回路が欲しいのかと聞くと以下の要望が出てきました

  1. アームの部分をエンコーダとポテンショメータでPID制御をして欲しい
  2. モータドライバ1つで380モータを4つ回してほしい
  3. 回路やケーブル含めて300g以下にして欲しい

初めて聞いたとき1つ目の要望しか理解できませんでした
川ロボは380モータしか使用できないらしく、そのために380モータを一つの軸に並列で繋いでトルクを稼ぐらしいです
また、重量制限も厳しく300g以下じゃないと現在の機体では重量オーバーになるらしいです

特に最後の要望は初めて聞きました
回路に重量制限がある世界線は初めてです

以上の要望から今回はマイコンとMDボードの二つを作成することになりました
ただMDはモータ線や大きめのFETを使うことからマイコンボードは出来るだけ軽くする必要があります

そこで秋月のSTM32F303K86Tのチップを自作ボードを組み込むことでマイコン部分を作成します
akizukidenshi.com
川ロボが終わったらgithubごと公開する予定ですが、今は抜粋しながら解説します

書き込み部

STMの評価ボードではプログラムを書き込む場合はUSBケーブルで評価ボードを繋げば簡単に書き込みできます
チップからやる場合はまず、ST-Linkを用意します
秋月で買える公式のST-Linkや中華でも買うことが出来ます
akizukidenshi.com www.amazon.co.jp

また、アクロバットな方法としては評価ボードに乗っているST-Linkを利用するというものもあります
一度やってみましたがジャンパーがめんどくさかったので一度しかしたことがありません
yuppi5.hateblo.jp

繋ぐピンですが以下のページを参考にして繋ぎました
ruru-log.hatenablog.com blog.goo.ne.jp

また、このチップの評価ボードの回路図も参考にしました https://www.st.com/resource/en/user_manual/dm00231744-stm32-nucleo32-boards-mb1180-stmicroelectronics.pdf

以下が実際につないでみた図です
f:id:masanari7430:20200707231454p:plain f:id:masanari7430:20200707231349p:plain f:id:masanari7430:20200707231419p:plain

4ピンのNRSTはスイッチとコンデンサを接続することでリセットを手動でかけることが出来ます
このつなぎ方は公式リファレンスにも載っています
akizukidenshi.com f:id:masanari7430:20200707232939p:plain

23ピンのPA13にはSWDIO、24ピンのPA14にはSWCLKを接続します
(これらを10kの抵抗で吊っていますがたぶんなくても動きます。どっかのページで吊ってあるのを見てなんとなく入れているだけです)

そしてこれらのピンをST-Linkにつなぎます
この時中華ST-Linkだと電流が足りないことがあったので、電源はマイコンの方で用意してGNDとこれらの信号線を繋ぎました
プログラムは今はSTMCubeIDEがあるので繋げば書き込めるでしょう
今回は回路図だけの解説にとどめます

注意点・疑問点

これは書き込むためだけの線だから出力ピン出してもいいかなと思いますが、この方がはまっているようにこれらのピンはGPIOやPWMに設定しない方が無難です
ajinori3.hatenablog.com

また、今回のつなぎ方はSWDという方法で接続しています
以下のページと一つ上のはまった方のページを見ると、必要なのはSWDIOとSWCLKのみでNRSTに関する言及は何もありません
qiita.com なのでもしかしたらNRSTはなしでも書き込めてデバックが出来るのではと思っています
(今回作成する基板でNRSTをなしでやってみてまた追記します)

2020/3/5(理系大学院生の沖縄旅行:3~5日目)

1~2日目はこちら mozyanari.hatenablog.com

三日目(美ら海水族館ツアー)

美ら海水族館沖縄県の北部にある水族館で,公共交通機関もないため車で2時間ほどかかります
レンタカーで行くかツアーで行くか悩みましたが,前日にシュノーケリングで疲れていて事故をする可能性があるということを考えるとツアーの方がいいと考えツアーに参加しました
www.cerulean-blue.co.jp このツアーは美ら海水族館だけではなく,お土産屋さんや他の観光地などの様々な場所を巡ることができます
また,美ら海水族館の入場料も含まれているのでお得かなと思ってこのツアーにしました
ツアー中は添乗員さんが窓から見える風景について教えてくれるので勉強になります

美ら海水族館

このツアーは最初に美ら海水族館に行きます
滞在時間は2時間半です
名物のジンベイザメから,伊勢海老や小さい蟹など様々な水中生物がいました
f:id:masanari7430:20200223121958j:plainf:id:masanari7430:20200223121122j:plainf:id:masanari7430:20200223122418j:plainf:id:masanari7430:20200223123012j:plain

ただ,美ら海水族館は海洋博公園の中の施設の一つで,周囲にはおきちゃん劇場や植物園など他にも施設があります
美ら海水族館で2時間程度使ってしまうので,他行けたのはおきちゃん劇場とウミガメ館,マナティ館だけでした
次来るときは,レンタカーで来て一日かけて巡りたいです

古宇利島

古宇利島は美ら海水族館の東にある島できれいな砂浜があります f:id:masanari7430:20200223131258j:plainf:id:masanari7430:20200223142549j:plain また,海ぶどうの直売所があり新鮮な海ぶどうが買えます

御菓子御殿

ここは元祖紅芋タルトを販売しているらしく自分もお土産用に買いました
ただ,国際通りにも同じお土産屋さんがあるのでここで買わなくても大丈夫だと思います

万座毛

象の鼻の岩が有名らしく写真を撮りました ただ,この時工事をしていたので添乗員さんと一緒に一周しただけで自由時間がなかったのが残念です
f:id:masanari7430:20200223161242j:plain

北谷アメリカンビレッジ

最後に訪れたのは北谷アメリカンビレッジです アメリカンな雑貨屋,服屋がありました おしゃれには興味があまりなかったのでただ何があるか歩き回っていただけでした

晩御飯:島しゃぶしゃぶNAKAMA

shabushabu-nakama.com ここでアグー豚のしゃぶしゃぶ食べ放題を食べました
他の店で食べる豚しゃぶより脂の部分があっさりしていて,お腹がいっぱいでもしゃぶしゃぶだけ食べれるぐらいあっさりしていました
自分はゴマダレなど濃い目のたれで食べるのですが,アグー豚とポン酢の相性が最高でポン酢で食べ続けていました
ただ,食べ放題で一番おいしかったのは,アグー豚のコロッケでした
柔らかくてとてもジューシーでした
f:id:masanari7430:20200223200504j:plain f:id:masanari7430:20200223200501j:plain

四日目(BBQ)

この日は夕方からのBBQしか予定を入れていないので,国際通りで一日中ぶらぶらしていました
ただ,これまでの疲れがあったので特に遊ぶ元気も無かったので写真をあまりとりませんでした

朝ごはん:ポークたまごおにぎり

porktamago.com 国際通りから少し離れたところにある,ポークたまごおにぎりに行きました
f:id:masanari7430:20200305125316j:plain スパムと卵焼きを挟んだおにぎりを食べれるお店で,朝の9時過ぎに行ったのですがかなり人が並んでいました
自分はエビタルを注文しました
一個350円で安くて,ボリュームがあったので一つで朝ごはんとしては十分でした
f:id:masanari7430:20200224093609j:plain

昼ご飯:むつみ橋かどや

tabelog.com 沖縄のソーキそばを食べてなかったので,国際通りのこのお店で食べました
ソーキそばのほかに,三枚肉そば,ロースそばがありました
これらは上に乗っている肉の種類が違うだけで,麺やスープは同じらしいです
ソーキは煮込んだ骨付きのバラ肉で,あっさりとしたスープによく合いました
f:id:masanari7430:20200224115102j:plain

晩御飯:Bird's eye

birdseye.okinawa 4日目のメインイベントのBBQです
沖縄でBBQをしたいと思っていたのですが,浜辺でするBBQは夏しかやっていないし,冬場やっていても人が少なそうでどうしようかなと思っていました
そこで,少人数をメインでやっているBBQがないかなと探すと,Brid's eyeを見つけました
食材を準備する必要はなくて向こうの方がほとんど用意してくれています
また,作るのも手伝ってくれてBBQを一度もやったことがないロボ研でも楽しくBBQが出来ました f:id:masanari7430:20200224175050j:plainf:id:masanari7430:20200224185254j:plainf:id:masanari7430:20200224183048j:plain

場所は港の近くで夜になると夜景もきれいでした f:id:masanari7430:20200224193402j:plain f:id:masanari7430:20200224193356j:plain

五日目(飛行機で神戸へ)

この日は那覇空港でお土産を買って帰りました
f:id:masanari7430:20200225094228j:plain

まとめ

今回の旅行は自分が予定をすべて決めるのではなく,ご飯は友人の一人にまかせたり,そもそも予定を何も入れない時間を入れました
そのおかげで宿の中でダラダラしながら適当に話したり,カードゲームやSwitchをしながら過ごしていました
これからおそらく7人もそろって遊べることはないので最後の旅行にふさわしい思い出になりました

2020/3/4(理系大学院生の沖縄旅行:1~2日目)

人生で初めての沖縄旅行

修論発表も終わり,ロボ研の友人たち6人と沖縄旅行に行ってきました
旅行をするのにあたって「人生で行ったことがない場所に行く」というテーマがあったので,自分が行ったことがなかった沖縄を選びました

日程

2月21日から25日まで4泊5日の日程で,最初と最後の日は飛行機移動に設定しました
また,2日目はシュノーケリング,3日目は美ら海水族館,4日目はBBQとそれぞれの日に一つ大きなものを設定しました
(昔の旅行では午前と午後にそれぞれ何をするかを決めていましたし飛行機ついてからどこかに遊びに行っていましたが,体力がなくなってきたのを実感したので予定の詰込みをやらなくなりました)

一日目(飛行機で沖縄へ)

伊丹空港から沖縄へ飛行機で行きました
ただ,4泊5日分の荷物を持って伊丹空港まで電車で行ったので,この時点で疲れて帰りたくなっていました
f:id:masanari7430:20200304154510j:plain

宿:ゲストハウス海風

沖縄に到着したら宿に直行しました
今回泊まったのは海風というドミトリー形式の宿で,4泊5日で一部屋72000円でした
7人で行ったので一人当たり1万300円ほどで泊まることが出来ました umi-kaji.com 価格が安かったので布団とか設備が古くないかなと心配していましたが,部屋が狭いだけで宿泊するのに何の不便がありませんでした
また,モノレール近くにあるのでレンタカーやタクシーなどを使わずに空港に着いてからすぐに行くことができます

晩御飯:鳥玉

この日の晩御飯は,鳥と卵の専門店「鳥玉」に行きました
沖縄にしかないチキン南蛮のお店です
tabelog.com f:id:masanari7430:20200221185404j:plain 卵にこだわっているお店でタルタルがとても濃厚でチキンも衣がパリパリで,時間がたつとタルタルが衣に染みていって食感が変わるのでとてもおいしかったです
旅行中に2回行きたいと思うほどでした

二日目(シュノーケリング)

昼ご飯:シーサイドリストランテ

シュノーケリングに行く前に昼ご飯で,シーサイドリストランテという場所に行きました
ここは嘉手納基地に近いためアメリカの方がよく来るお店らしく,店内はほとんどがアメリカ人でした kadenafss.com テラス席もあり見晴らしがよかったです
f:id:masanari7430:20200222120207j:plain 注文したハンバーガが櫛で刺さないと立つことができないほど大きくて,これがアメリカサイズかと思いながらハンバーガを食べていました
f:id:masanari7430:20200222113837j:plain 少し驚いたのが,支払いが現金でも可能ですがその日の円ドルレート換算されてドルでおつりが返ってくるらしいです
なので,クレカで友人が払ってくれました

シュノーケリング

ロボ研には体力がないのは目に見えているため,最も体力を使うであろうシュノーケリングを最初のイベントにしました
沖縄で有名な海は「青の洞窟」と呼ばれる場所で,沖縄の中部にあり那覇市から車で1時間程度です

お世話になったのはVoice Plusという青の洞窟でシュノーケリングが出来るお店です
www.voice-plus-okinawa.com
シュノーケリング代は2980円,度付きゴーグル500円でした
最初は青の洞窟の近くの浅瀬でシュノーケリングの方法をレクチャ―してもらい,青の洞窟を一周して最後に魚に餌をあげながら戻ってくるというツアーでした
2月末でしたが,ウエットスーツのおかげで海に入ってもそれほど寒くありませんでした
よくテレビでは沖縄の海が青くてきれいなのは知っていましたが,生で体験するのはテレビで見るよりもきれいでした
f:id:masanari7430:20200304160435j:plain f:id:masanari7430:20200304160438j:plain f:id:masanari7430:20200304160442j:plain f:id:masanari7430:20200304160446j:plain

寄り道:道の駅

帰りに道の駅 かでなに寄りました f:id:masanari7430:20200304164004j:plain 嘉手納基地から道路一本隔てた場所にある道の駅で,屋上の展望台から嘉手納基地を見ることが出来ます f:id:masanari7430:20200222161220j:plain f:id:masanari7430:20200222161205j:plain また,Blue Sealというアイス屋さんがあり,みんなでシュノーケリングした後の体を癒すためにアイスを食べました

晩御飯:みかど

シュノーケリングをして,宿まで帰ってくると夜になっていたので,「みかど」というごはん屋さんに行きました
tabelog.com ここは沖縄の食堂みたいなところで,ゴーヤチャンプルーを食べました
給食とかで食べていたゴーヤチャンプルーはずっと苦い苦いと思いながら食べていました
ですが,ここのゴーヤチャンプルーは最初は苦いですが,その苦みが続くことなく噛んでいると苦みが無くなっておいしく感じて不思議なゴーヤチャンプルーでした
f:id:masanari7430:20200222191920j:plain

デザート:雪塩ソフトクリーム

沖縄行きの飛行機に乗っているときに観光ガイドを機内でもらったのですが,その中に雪塩ソフトクリームを見つけました
甘いものが好きな自分はどうしてもこれが食べたくて探していました
そこで,晩御飯のあとに探すと店の近くにあったので食べに行きました
tabelog.com

このソフトクリームは塩がソフトクリームの中に練って入っています
f:id:masanari7430:20200222194627j:plain なので,ポテチとソフトクリームを同時に食べたようなあまじょっぱい味を味わえます
さらにお店のイートインコーナーに色々な塩が置かれています
抹茶やココア,さらにはダイナマイト味といった様々な塩を使って自分の好みの味を探すことが出来ます
(ダイナマイトは微妙でした)

続きはこちら mozyanari.hatenablog.com

2019/10/7(Raspberry PiのROSからpigpioを使ったSPI通信でMPU9250を動かして,Madgwick Filterから姿勢を計算する)

くそ長タイトル

前回はMPU9250の値を取りました

mozyanari.hatenablog.com

MPU9250の値を取るだけでは,重力加速度しか分からないので姿勢を計算していきます
ただ,修論もあるし手軽にROSのパッケージがあるMadgwick Filterを使います

wiki.ros.org

ドローンなら,ラズパイとMPU9250で姿勢が取得出来て,PWMをだしてアンプを動かして飛ばせるのではと思います

環境

前回と同じです Raspberry Pi 3 B
OS:Ubuntu Mate
ROS:Kinetic
9軸センサ:MPU9250

プログラム

github.com pigpioを使ったSPI通信とMPU9250の値の取得は前回の記事を参照してください

センサデータ変換

double acc_x = mpu9250.get_acc_x()/16384.0*9.81;
double gyr_x = mpu9250.get_gyr_x()/130.072*0.01745;

今回は,加速度と角速度だけを使います
imu/data_rawというデータをimu_filter_nodeに与えます
なので,imu/data_rawを自分で作る必要があります

センサデータをimu_filter_nodeが求めている単位に変換して与えます 何度か実験してみた所,
加速度は,m/s2
角加速度は,rad/s2
が必要ということが分かりました
式の意味は前回の記事を参考にしてください

imu/data_rawの作成

sensor_msgs::Imu Imu;
Imu.header.frame_id ="imu";
Imu.header.stamp = ros::Time::now();
Imu.linear_acceleration.x = acc_x;
Imu.linear_acceleration.y = acc_y;
Imu.linear_acceleration.z = acc_z;

Imu.angular_velocity.x = gyr_x;
Imu.angular_velocity.y = gyr_y;
Imu.angular_velocity.z = gyr_z;

もしかしたら,分散の場所に値を入れればMadgwick Filterが上手いこと何か処理してくれるかもしれませんが,ここでは値を入れてpublishするだけです

Madgwick Filterの追加

github.com

ソースにgit cloneで持ってきてコンパイルします
ただ,ラズパイだとフリーズする可能性があります(一度フリーズしました)
なので,makeするときは

catkin_make -j1 -l1

でしましょう

同時に起動するlaunchファイル

github.com

MPU9250から加速度,角加速度を取得するノード,Madgwick Filterノードを同時に起動するlaunchです

この時,パラメータのuse_magをfalhseにします
これで地磁気を使わずに計算します

また,パラメータのreverse_tfはtrueにします これによって,imuリンクからodomリンクを生成します (これがないと,rvizで表示した時に基準となるtfがないために姿勢が変化しているか分かりません)

実験結果

youtu.be

起動するとなぜかodomリンクからyaw軸に90度回転したところから始まります
yaw軸は地磁気がないと補正は難しいようです ですが,十分使える精度だと思います

まとめ

今日はまとめで一日使ってしまった
明日からは研究しよ

2019/10/7(Raspberry PiのROSからpigpioを使ったSPI通信でMPU9250を動かす)

夏シンポが終わってひと段落

前回まででGPIOでLチカをしてみたり,サーボを動かしてみたり,シリアル通信をしてみました mozyanari.hatenablog.com mozyanari.hatenablog.com mozyanari.hatenablog.com

今回は,Raspberry PiのROSからSPI通信でMPU9250を動かしてみます
正直これはマイコンでやればいいんじゃないと思うかもしれませんが,ラズパイでやりたい理由は以下の二点です

  1. すべてをRaspberry PiのROSで処理させて,ROSパッケージの恩恵を受けたい
  2. ロボットに乗るように出来るだけ小さく作りたい

センサを取得したり,オドメトリとのセンサフュージョンをしようと思うときには結局マイコンからラズパイにデータを送る必要があります
例えば,これをやりたいとき wiki.ros.org

また,STMでセンサデータを受信しようとした時,少ないピンの表面実装のパッケージを使えば小さくできなくもないですが,今考えている移動ロボットはLRFが載ってますし結構キツキツなスペースです

なので,出来るだけROS上でセンサデータを取得したいです

今回の目標はMPU9250の加速度と角加速度をSPIで取得して,重力加速度を観測します

環境

Raspberry Pi 3 B
OS:Ubuntu Mate
ROS:Kinetic
9軸センサ:MPU9250

プログラム

github.com さすがにプログラムが長くなってきたので,適宜抜粋しながら解説します

pigpioの初期化

int SPI_MPU9250::pigpio_initialize(){
  pigpio_check = pigpio_start(NULL,NULL);
  if(pigpio_check < 0){
      ROS_ERROR("pigpio Initialize Error");
      throw;
  }else{
      ROS_INFO("pigpio initialize OK");
      return pigpio_check;
  }
}

ここではpigpioの初期化をしています
以前の記事とは異なるのは,初期化が失敗するとthrowをしてノードを落としていることです
また,クラス内変数にpigpio_checkを持たせておくことで他の場所でのpigpioの初期化の結果を使えるようにしています

pigpioのSPIの使い方

int SPI_MPU9250::spi_initialize(){
  //spi config
  unsigned int spi_channel = 0;          //0ch
  unsigned int baud = 500000;            //500kHz
  
  //spi_flags setting
  unsigned int spi_flags = 0;
  spi_flags = spi_flags | 0b00;            //select mm
  spi_flags = spi_flags | (0b000<<2);   //select p0-p3 
  spi_flags = spi_flags | (0b000<<5);   //select u0-u3
  spi_flags = spi_flags | (0b0<<8);     //select A
  spi_flags = spi_flags | (0b0<<9);     //select W
  spi_flags = spi_flags | (0b0001<<10); //select n
  spi_flags = spi_flags | (0b0<<14);    //select T
  spi_flags = spi_flags | (0b0<<15);    //select R
  spi_flags = spi_flags | (0b1000<<16); //select b
  //ROS_INFO("%d",spi_flags);

  //spi open
  spi_handle = spi_open(pigpio_check,spi_channel,baud,spi_flags);
  if(spi_handle < 0){
      ROS_ERROR("SPI Initialize Error");
      throw;
  }else{
    ROS_INFO("SPI initialize OK");
      return spi_handle;
  } 
}

ここではspiの初期化をします
pigpioのSPIの設定は以下のページにあります abyz.me.uk
第一引数には,pigpioの初期化の結果,第二引数にはどのSPIを使うか,第三引数はSPIの通信速度,第四引数には,SPIのその他の設定を入れます

今回は,第二引数は0にして,MISOがGPIO9,MOSIがGPIO10,SCLKがGPIO11,CEがGPIO8のSPIを使います
第三引数は500Khzにしました

最も設定が多くて面倒だった第四引数の設定について説明します
ここには22bit必要で自分はunsighd intを用意しました

  • 0~1bitはSPIモードを設定します

os.mbed.com 立ち上がりでデータを読むかなどを設定するところですが,基本的に00を書き込んでおけばいいと思います

  • 2~4bitはCEがアクティブLowかアクティブHighかを設定します
    ただ,今回はCEピンが動いていない気がしたので,スレーブセレクトは自分でしました

  • 5~7bitはCEをチップセレクト(スレーブセレクト)として予約するかどうか
    予約していますが,自分で動かしているので一つ前の設定も含めてここは少し謎です

  • 8bitはメインSPIを使うか,auxiliary SPIを使うかです
    auxiliary SPIはメインSPIのピンが何かしらの理由で埋まっていれば使えばいいと思いますが,特殊なSPIな気がします

  • 9bitは何線でつないでいるかです
    SPIはチップセレクト(スレーブセレクト)を無視した3線と,チップセレクト(スレーブセレクト)を含んだ4線で通信します
    今回は4線で設定しています
    この設定はメインSPIでしか行えませんので,auxiliary SPIでは ただ,ここも4線で設定していますが結局チップセレクト(スレーブセレクト)は自分で動かしているので設定として間違っているかもしれません

  • 10~13bitはいまいち理解できていないので,調べた物を引用させていただきます

    nnnnの4ビットはMOSIからMISOに切り替わるバイト数を指定する。当然最大15バイトということになる。これはAが1のとき、つまり3本線の場合だけ使える、と書いてある。ということはMOSIとMISOを多重化するということなんだろうか。

decafish.blog.ss-blog.jp

  • 14bitは送信時のMSBかLSBを設定します 0だとMSBから1だとLSBで通信します ただ,この設定はauxiliary SPIだけです

  • 15bitは受信時のMSBかLSBを設定します 0だとMSBから1だとLSBで通信します ただ,先ほどと同様この設定はauxiliary SPIだけです

  • 16~22bitは何ビットで通信するか設定する場所です MPU9250は1byte = 8bitずつ読むので0b1000=8で十分です
    ただ,最高26 = 64bit通信出来るので.マイコンと通信するときにはうれしいかもしれません
    (例えば,オドメトリを受け取るときとか)

ここまでつらつら書いてきましたが,この人のブログが一番参考になると思います decafish.blog.ss-blog.jp

spiのread関数

char SPI_MPU9250::pigpio_spi_read(char address){
  char read_data;
  char send_address = address | set_bit_1; 
  gpio_write(pigpio_check,CS_pin,0);
  spi_write(pigpio_check,spi_handle,&send_address,1);
  spi_read(pigpio_check,spi_handle,&read_data,1);
  gpio_write(pigpio_check,CS_pin,1);
  return read_data;
}

引数では読みだしたいアドレスを取得します
MPU9250でSPI通信を使ったリードを行うときにはアドレスの先頭bitを1にします(ここ大事)
そして,チップセレククトピンを下げて(アクティブLow),読みたいアドレスを書き込み,読み出します
最後にチップセレクトピンを上げて終了します
その結果をread_dataとして返します
ここでは特にエラー処理はしていないので,失敗したとしても分からないのでその点は注意してください (やろうと思えばできますが,加速度や角加速度を取得するたびチェックするのはどうかと思ってやめました)

spiのwrite関数

char SPI_MPU9250::pigpio_spi_write(char address, char write_data){
  char send_address = address;
  gpio_write(pigpio_check,CS_pin,0);

  char result1 = spi_write(pigpio_check,spi_handle,&address,1);
  char result2 = spi_write(pigpio_check,spi_handle,&write_data,1);
  gpio_write(pigpio_check,CS_pin,1);
  if(result1 < 1 | result2 < 1){
      ROS_ERROR("write error result = %d %d",(int)result1,(int)result2);
      throw;
  }else{
    ROS_INFO("MPU9250 OK");
    return 1;
  }
}

引数で書きたいアドレスとデータを取得します
readとは異なりアドレスには何も手を付けません 最初に,チップセレククトピンを下げてアドレスを送信して,その後データを送信します
最後にチップセレククトピンを上げます
書き込み関数の結果は書き込んだバイト数が返ってきます
つまり1byteの書き込みに成功すれば1が返ってくるはずなので,1以下が出れば失敗と判定してノードを落とします

MPU9250のチェック

SPI通信でMPU9250が存在するかチェックします

void SPI_MPU9250::who_am_i_check(){
  char read_data = pigpio_spi_read(who_am_i);
  if(read_data == 0x71){
      ROS_INFO("who am i OK");
  }else{
      ROS_ERROR("who am i Error read data = %d",(int)read_data);
    throw;
  }
}

ここでは先ほどのpigpio_spi_read関数を使ってMPU9250のwho am iが返ってくるかをチェックします 見つからなけばノードを落とします

MPU9250の起動

void SPI_MPU9250::mpu9250_power_on(){
  pigpio_spi_write(wake_up_1,wake_up_ward_1);
  pigpio_spi_write(wake_up_2,wake_up_ward_2);
}

MPU9250 の内部アドレス0x6Bに0x00 を書き込み,内部アドレス0x37に0x02 を書き込みます
ここら辺はMPU9250のマニュアル通りです

加速度,角加速度の取得

int16_t SPI_MPU9250::get_acc_x(){
  int acc_x_h = pigpio_spi_read(ACCEL_XOUT_H);
  int acc_x_l = pigpio_spi_read(ACCEL_XOUT_L);
  int16_t acc_x = ((acc_x_h << 8) | acc_x_l);
  return acc_x;
}

この関数では加速度,角加速度を取得します
リードしたデータはintで取得して,必ずint16t_tに格納します もし,intに入れると4byte = 32bitなので,シフト演算でまとめた時に負の値がおかしくなります

加速度の変換

double acc_x = mpu9250.get_acc_x()/16384.0*9.81;

mpu9250から取得した加速度はそのままだと使えません
なのでこれをm/s2に変換します mpu9250のデフォルトのレンジは,+-2gです
また,分解能は16bit,65536段階,つまり,-32768~32768です
(いや,0を考えると-32767~32768かな?)
例えば,16384という値が来れば 16384/16384 = 1g * 9.8 = 9.8m/s2となります

つまり,出てきた値を16384で割って,9.8をかければ加速度に変換できます
(今回はデフォルトのレンジが+-2gなのでこの計算で出来ます
もし,+-4gなら,1gの値が32768/4=8192なので,8192で割って,9.8をかけたら加速度になります)

角加速度の変換

double gyr_z = mpu9250.get_gyr_z()/130.072

これも同様に変換します
デフォルトが+-250dps = degree/secなので,32768/250 = 131.072の値で割ります
こうすることで,角加速度が出てきます

(ただ,これの単位は度なので,後でラジアンが必要になりました
その場合以下のようにしました

double gyr_z = mpu9250.get_gyr_z()/130.072*0.01745

rad = deg * (pi/180)なので,pi/180 = 0.01745を掛けました)

Raspberry PiとMPU9250の配線方法

f:id:masanari7430:20191007150636j:plain 図のICの名前は違いますが,この方法で結線しました

実験結果

youtu.be accを見ると9.8が出ていて,重力加速度が認識出来ています

まとめ

解説を書くのが長かった
最近,研究の方でも解説を書いているけど,これを書かないと1年後の自分が絶対覚えていないので仕方がないと思いながら書いています
でも,やっていて思ったのがこんなことしていてもいいのかなということです
最近,IPhoneのカメラだけでARを表示してさらにオクルージョンしてるのをみたり,Oculus Questがハンドトラッキングをカメラだけでしているのを見ると,この後の人生で自分が価値のあるものを作れるのかと思います
来年から働きますがこれでいいのかな とりあえずご飯食べてきます

2019/8/15(Raspberry PiのROSからpigpioを使ってGroovy-PIDを動かしてモータを動かす)

タイトルが長い

前回はGroovy-PIDのLEDをROSのpigpio経由で動かしました
mozyanari.hatenablog.com
mozyanari.hatenablog.com

次にRaspberry PiのROSからpigpioを使ってGroovy-PIDを動かしてモータを動かします
前回と同様の環境を使っているので,もしやっていないなら動作確認も含めてRaspberry PiのROSからpigpioを使ってGroovy-PIDを動かしてLチカしてみてください

環境

Raspberry Pi 3 B
OS:Ubuntu Mate
ROS:Kinetic

プログラム


今回のプログラムも前回と同様にgitで配布しているので,git cloneで取ってください
github.com

解説

#include <pigpiod_if2.h>
pi = pigpio_start(NULL,NULL);

説明するまでもなく初期化です
詳しい説明は以前の記事にあります
mozyanari.hatenablog.com



char m = 0x6d;
char s = 0x73;
char space = 0x20;
char zero = 0x30;
char one = 0x31;
char two = 0x32;
char three = 0x33;
char five = 0x35;  
char enter = 0x0D;

モータを動かすコマンドは以下のページにあります
www.omiya-giken.com
今回使用するのは
「m」 「 」(space) 「0」「」(改行)
:オープンループモード
「s」 「 」(space) 「0」「 」(space) 「0」「」(改行)
:モータを止める
「s」 「 」(space) 「0」「 」(space) 「5」「0」「0」「」(改行)
:500の力でモータを回す
この3つが主です
ただ,これをasciiコードで送るのでそれに対応した値を変数として保持しています



int serial_flag = serial_open(pi,"/dev/ttyACM0",57600,0);

ここでUSB接続したシリアルポートを開いています

第一引数

pigpioを初期化した時に返ってきた値を使用しています

第二引数

/dev/ttyACM0を指定していますが,他に接続している物があったり,OSのバージョンによっては違うものが出てくるかもしれませんがその時はここを適宜変更してください

第三引数

Groovy-PIDを動かすのに必要なボーレートは57600なのでここはこの値で固定です


serial_write(pi,serial_flag,&m,1);
serial_write(pi,serial_flag,&space,1);
serial_write(pi,serial_flag,&zero,1);
serial_write(pi,serial_flag,&enter,1);

この部分でシリアル通信でオープンループ設定をしています

第一引数

pigpioを初期化した時に返ってきた値を使用しています

第二引数

シリアル通信を初期化した時の値を使用しています
第一,第二と初期化の時に返ってきた値を使うことで,もしどちらかの初期化が失敗したら動かないようになっています

第三引数

送信したいデータのアドレスを渡しています


//if no [time_sleep], this node don't work
time_sleep(0.1);

オープンループ設定をした後にtime_sleep(0.1)がありますが,これを入れないと自分は動きませんでした
このGroovy PIDは送ったコマンドを適宜コールバックして返してくれています
また,エンター入力した後はTeratermで表示を綺麗にするための改行などの3コマンドを送っています
なので,オープンループ設定をした後にすぐに速度指令を送ると,PICはシングルスレッドなので改行コマンドを送信している時に速度指令を受け取ることになり動かないのではと考えています


serial_write(pi,serial_flag,&s,1);
serial_write(pi,serial_flag,&space,1);
serial_write(pi,serial_flag,&zero,1);
serial_write(pi,serial_flag,&space,1);
serial_write(pi,serial_flag,&five,1);
serial_write(pi,serial_flag,&zero,1);
serial_write(pi,serial_flag,&zero,1);
serial_write(pi,serial_flag,&enter,1);

この部分で速度指令をしています
この例では
「s」 「 」(space) 「0」「 」(space) 「5」「0」「0」「」(改行)
:500の力でモータを回す
を実行しています

実行

sudo pigpiod

まずは絶対にこれを実行します

roscore

ROSではこれが必ず必要です


f:id:masanari7430:20190727165240j:plain
Groovy-PIDのリセットスイッチを押す

rosrun groovypid Groovy_moter_test

これでモータを動かすことができます

そういえばこの記事でいきなりシリアル通信してるからそれに関して少し書きたいな