FC2ブログ

makopi23のブログ

makopi23が日々の生活で感じたことを気ままに綴るブログです。

エアロバイクをGoogleマップに連携して、おうちで自転車旅できるアプリ作った

エアロバイクをGoogleマップに連携して、おうちで自転車旅ができるアプリを作ってみました。
エアロバイクのペダルを漕ぐと、こんな感じでGoogleストリートビューの画面が前に進みます。


これで、緊急事態宣言下でも自転車日本一周の旅を再開できるぞ・・・!

アプリ開発の経緯


事の発端は、TwitterのTLに流れてた以下の記事を目にしたことでした。



なんと・・・素晴らしい企画だろうか!

私も自転車が趣味の一つで、まとまった休暇が取れると自転車で日本中を旅しています。
前回の終着点から旅を再開するスタイルで、ゴールデンウィークも鹿児島から自転車日本一周を再開する予定だったのですが、生憎、コロナ緊急事態宣言のために延期・・・

そんな矢先にこの記事を目にして、じゃあ折角だからゴールデンウィークを使って俺も作ってみようと思い立ったのでした。
いちおう職業はITエンジニアだし、大学も電気電子情報工学科だったので、プログラミングも電子回路もそれなりに出来る・・・ハズ・・・

今回、技術的な話はこちらを参考にさせていただきました。(上記記事の元ネタです)

せっかくなので、私が作ったアプリや電子回路の仕様とか実現方法をブログに纏めておこうと思います。

動作仕様


Webアプリケーションなので、ブラウザさえあればPCでもスマホでも動作させることができます。PCだとこんな感じ。
画面上部のテキストボックスに緯度と経度を入力し、「ストリートビューを表示」ボタンを押すと、その地点から出発することができます。ペダルを漕ぐと前に進みます。
cycling_at_home_01.jpg

緯度と経度はGoogleマップから簡単に取得することができるので、これを↑のテキストボックスにコピペするだけで、どこからでも出発することができます。
cycling_at_home_03.jpg

もちろんスマホでも動作するので、エアロバイクの前にノートPCを置くことができなくても、ペダル漕ぎながらスマホの画面を眺めれば旅を楽しむことができます。
cycling_at_home_02.jpg

道を曲がるには、PCならマウスでドラッグしたりクリックすることで進行方向の変更が可能です。
幸い、私のノートPCは液晶画面がタッチパネルになってるので、マウス不要です。
スマホも同様に、液晶画面をクリックすることで曲がったり進行方向を変更することができます。

ドラッグすることで視界も360度ぐるっと変更可能なので、周りの景色も楽しむことができます。

構成図


構成図はざっくりこんな感じです。
cycling_at_home_05.jpg

エアロバイクとRaspberry Piを有線接続し、ペダルを漕いだデータをRaspberry Piで処理して、ノートPC(またはスマホ)に通信で飛ばします。
ノートPC(またはスマホ)のブラウザに地図(ストリートビュー)を表示し、通信で受け取ったデータを元にストリートビュー上を移動させます。

用意したもの


自宅で埃を被っていたラズパイとかブレッドボードとかを活用したので、出費はほとんどありませんでした。
詳細は以下のとおり。

もともと自宅にあったもの


エアロバイク (2015年に購入)
Raspberry Pi (2014年に購入したのでかなり古い型番です)
Wi-Fi USBアダプタ (Raspberry PiをWiFi接続するためのUSBアダプタ。元々はPlayStation Vita用に買ったものを流用。無い場合はLANケーブルでRaspberry Piと繋げばOK)
・ブレッドボード
・ジャンパー線
・発光ダイオード
・抵抗

新たに購入したもの


ステレオジャック 3.5mm

というわけで、今回の出費はステレオジャックの799円だけ。
5個入りで、使ったのはそのうち1個だけなので、実質は160円くらい?(笑

作成した電子回路


エアロバイクのサイクルメーターに接続されてるプラグを抜いて、購入したステレオジャックに差し込みます。
ステレオジャックの両端にジャンパー線をセロテープ(笑)でくっつけ、ジャンパー線をブレッドボードに刺して簡単な電子回路を作り、Raspberry Piの端子と接続します。

cycling_at_home_04.jpg

エアロバイクのサイクルメーターの原理は、前述したこちらのサイトで詳しく説明されています。

回路図はこんな感じ。
GNDとGPIO 0ピンの間にステレオジャックを接続し、サイクルメーターのプラグをステレオジャックに差し込みます。
これでペダルの回転を検知し、GPIO 0ピンでINPUTとして受け取ります。
cycling_at_home_06.jpg

開発したソフトウェア


ペダルの回転データをRaspberry Pi上に配置したJavaプログラム(Spring BootとPi4J)で処理し、HTTP通信でPCやスマホに飛ばして、ストリートビューをGoogle Maps JavaScript APIで制御します。
ソースコードはGitHubに公開しておきました。
https://github.com/makopi23/CyclingServer

もしご自分の環境で試してみる場合は、以下2ファイルの修正が必要です。

■1.
CyclingServer\src\main\resources\static\js\cycling.js
 → const URL = 'http://192.168.3.6'; (ここをご自分のRaspberry PiのIPアドレスに変える)

■2.
CyclingServer\src\main\resources\templates\home.html
 → 23行目の https://maps.googleapis.com/maps/api/js?key=xxxx&callback=init
    (xxxxの部分を、ご自分のGoogle Maps PlatformのAPIキーに変える)

 ※Google Maps PlatformのAPIキーを事前に取得しておく必要があります。この辺は前述のie4さんのQiitaに書いてあります。

開発環境/ソフトウェア


・Windows 10
・Java 8  ・・・ プログラミング言語(ホントはJava 11以降を使いたかったんだけど、Raspberry Piの諸事情により・・・ )
Spring Boot ・・・ Javaフレームワーク
Pi4J ・・・ Raspberry Piを制御するためのJavaライブラリ
Google Maps JavaScript API ・・・ ストリートビューを制御するためのJavaScript API

使用ツール


Eclipse (Pleiades All in One Eclipse リリース 2020-03) ・・・ Java統合開発環境(IDE)
Tera Term ・・・ Windows10からRaspberri PiへSSHで接続してコマンド操作するためのツール
WinSCP ・・・ Windows10からRaspberri Piへファイル転送するためのツール

実行方法


Raspberry PiにJava 8とPi4Jをインストールしておきます。
また、Windows10からRaspberry Piへ、Tera TermでSSH通信、WinSCPでファイル転送ができるように設定しておきます。
この辺はググれば情報出てくると思います。

次に、前述のGitHubからソースコード(プロジェクト)をcloneし、Windows10のEclipseにインポートします。
Mavenでビルドしてjarファイル(CyclingServer-1.0.0.jar)を作ります。
cycling_at_home_07.jpg

Windows10上で作成したjarファイル(CyclingServer-1.0.0.jar)を、WinSCPを使ってRaspberry Piへファイル転送します。
以降、Raspberry PiのIPアドレスは 192.168.3.6 で、転送先のディレクトリは /home/pi/cycling として説明します。
cycling_at_home_08.jpg

Windows10からTera TermでRaspberry Piに接続し、jarファイルを実行します。
コマンドはこんな感じ。Pi4Jへもパスを通しています。
sudo -i java -jar /home/pi/cycling/CyclingServer-1.0.0.jar -classpath .classes:/opt/pi4j/lib/'*'
cycling_at_home_09.jpg

Raspberry Piのメモリ512MBしかないのにSpring Bootアプリがちゃんと起動するの凄い(笑

アプリが正常に起動したら、PCやスマホのブラウザからアプリにアクセスします。URLは以下のとおり。
http://192.168.3.6:8080/start

Spring Bootに内蔵されているTomcatが8080ポートで起動しており、以下のスタート画面が表示されます。
スタート画面を表示する際に、Raspberry PiのGPIOを1回だけ初期化しています。
cycling_at_home_10.jpg

画面に表示されているリンクをクリックすると、ストリートビューが表示されたTOP画面へ遷移します。
この状態でエアロバイクのペダルを漕ぐと、ストリートビューが前進して、前に進むことができます。
cycling_at_home_11.jpg

処理概要


Raspberry Pi上にデプロイしたアプリケーションは、ペダルの回転をRaspberry PiのGPIO 0ピンで検知するたびに、データベース(Spring Bootに内蔵されているインメモリデータベースのH2DB)にレコードをINSERTしていきます。
また、データベースに入っているデータを取得するためのREST API(URIは /cycling )も用意し、クライアントに向けて公開しておきます。

クライアントのブラウザにロードされたアプリからJavaScriptでREST APIを1秒ごとに呼び出し、Raspberry Pi上のデータベース(H2DB)に新しいレコード(ペダル回転データ)があれば、ストリートビューの自分の位置を前に進めます。

たった、こんだけ。

ちなみにGitHubからCloneしたCyclingServerプロジェクトは、Raspberry Piにjarファイルとしてデプロイする以外にも、Windows10のEclipseからもクライアントとして起動することができます。
その場合、アプリのURLは http://localhost:8080/ になります。(ただし http://192.168.3.6:8080/start の実行は必要)
クライアントのJavaScriptのコードを弄りながらアプリを改善しながら動かしたい場合は、こっちの方が楽です。
(Rapberry Piへいちいちデプロイする操作が不要になるので)

まとめ


やっぱ自分が本当に欲しいものを自分で作るのは楽しいですね。
エンジニアで良かったと思う瞬間です。
機能拡張も自分で無限大に出来るので、いろんな便利機能もこれから足していけるといいなー

ちなみに、これまでの自転車日本一周の経路はこちら。
これまではクロスバイクで旅をしてきましたが、おうちのエアロバイクで旅が再開できるようになったぞ!


20190814_310.jpg

日本一周とは別に、以下の場所へも自転車で旅をしてます。


まだまだ緊急事態宣言は続くようなので、おうちからこのアプリでどっか自転車旅してみようと思うのでした~

「Developers Summit 2020」に参加しました

2020/2/14(金) 「Developers Summit 2020」に参加してきました。

公式サイト
https://event.shoeisha.jp/devsumi/20200213/timetable#day02

20200214_010.jpg

1日目(2/13)は仕事の都合で参加できなかったけど、なんとか2日目(2/14)は参加することができました。
気になったセッションをメモ。

【14-C-1】 レガシーコードからの脱却


セッション: https://event.shoeisha.jp/devsumi/20200213/session/2399/




みんなでアジャイル、という本を翻訳した。
どうやって全員でアジャイルになるの?という本。

レガシーコードからの脱却
レガシーコードからの脱却 ―ソフトウェアの寿命を延ばし価値を高める9つのプラクティス
David Scott Bernstein
オライリージャパン
売り上げランキング: 1,611


「レガシコード」ってタイトルにつけると売れるらしい
レガシコードっていろんな定義がある
レガシーソフトウェア改善ガイドによる定義 → 保守または拡張が困難なコード
これはみなさんのイメージに近いかな

議論のときは、まず共通認識は何かを確認するとよい
このセッションでは、レガシーコードの定義を
「理由は問わず、修正、拡張、作業が難しいコード」とする。

ソフトウェアと変更の切り口で考えてみた

使われるソフトウェアは変更が必要になる
変更を先にすべて予測するのは無理
変えたくなったら変えられるように作ろう、という割り切り
その反対がレガシーコード
すぐ治せる技術スキルが必要
変更のコストを下げたい

時間の使い方に問題があるケースが多い
80%のコストが障害対応に使ってる
強烈に無駄

理由
・急ぎすぎている
・たくさん作ろうとしすぎている
・etc


レガシコードを作ったら負け。最初から作らないようにする。
どうすればいいかというと、開発プロセスに着目する

開発のやりかただけに着目しがち
作り出す成果が何よりも大事
何によって決まるかと言うと、コードの綺麗さだけじゃ決まらない

問題設定力 ・・・ その問題って本当にお客さんが抱えているんでしたっけ
×
開発力
×
チーム力

アジャイルで、スクラムだけで技術的には何もやらない、はない
XPやデザイン思考などと組み合わせる

レガシコードを作らない9つのプラクティス
1.やり方より先に目的、理由、誰のためかを伝える
2.小さなバッチで作る
3.継続的に統合する
 アジャイルマニフェストでもいってる
4.協力しあう
 心理的安全性のもとに
5.CLEANコードを作る
 それぞれの頭文字
6.まずテストを書く
7.テストでふるまいを例示する BDDみたいなの
8.設計は最後で行う
9.レガシーコードをリファクタリングする

人間が覚えられる個数は7プラスマイナス2くらい
スクラムとXPからプラクティスを抽出している。

1.やり方より先に目的、理由、誰のためかを伝える
役割の違い
 ・POの責任
 ・開発チームの責任
役割が違う
明確に分断をしている

whatとhowを分離している
POの領域は、何をほしいか、なぜほしいか(What)
やりかたは開発者の領域(How)
物事のやりかたは1つでないく、やり方ごとにトレードオフがある
howを指示されるとコードが手続型になる
オブジェクト指向にならなくなる
作るうえで重要なのはコンテキストを共有・理解すること

ユーザーストーリー
何が、なんのために、誰のために、存在するかを一文で表したもの
仕様書じゃなくて、機能について会話できるレベル
会話によってしか共通理解は成り立たない
ユーザーストーリーをベースにお互い会話する
知識はドキュメントでなくコード(テスト含む)にまとめるべき
ストーリーがシンプルで1つのことを語ってると、テスト可能になる
ハッピーパスを一本通せばよい
動くようになってから足していけばいい
最初から良い設計って見えない
やりながら見えてくる
すこしずつ積み重ねて設計を見直していく

2.小さなバッチで作る
どかんとウォーターフォールでやると、結合試験でいろんな問題でる
リリースしてから、こんなの頼んでない、となる

鉄の三角形
ウォーターフォールはQCDSを全部固定しようとする
同時に約束できるのは2つまで、と言われている
Qは通常変えないほうがいい
Qを調整すると、後から辛い目にあう
品質はいじれない
元の品質が低すぎると、リリーススプリントでテスト、で間に合わない。高リスク

コストを調整する、というのは人を増やすこと
人を増やしてもコミュニケーションコストが増える
オーバーヘッドになりリニアに生産性は増えない
「遅れているプロジェクトに人を足すとさらに遅れる」


時間を調整してもよいが、多くのビジネスでは時間が重要
一番調整すべきなのはスコープ
およそ半分の時間はほとんど使われない
使われないものを作るのをやめよう、というのが一番合理的
大事なものから順番にやっていこう

スコープ調整しながらするとき、タイムボックスによるアプローチをする
同じ時間区切って、延々と繰り返す
固定のリズムの中で仕事する
1週間でやるのがお気に入り
小さくやるので設計量も開発量もすくない、バグもすくない
ウォーターフォールだと、最初の計画は大嘘になる
アジャイルは、短いイテレーションで小さな嘘をつく
軌道修正しやすい

同じリズムを刻むことで負担を少なくして、異常に気付く
ペースメーカーがあると、すごい気づく

1サイクルを長くするほど、リソース効率を目指しやすい
同時に手を付けるものが増える
タスクの切り替えが増えて集中力が落ちる
分担したほうが効率的、という幻想のもと、分担してしまう

サイクルを短くすると、プロセス効率があがる
1個ずつやっていくしかない


モブプログラミング=究極の1個流し
進捗90%ばかり複数ならんで、どれも終わってない、となりがちだが、
1個流しだと、完成したものが1個ずつ確実にでてくる
多少おそくなっても、1個ずつ出してお金を稼げたほうがビジネスにとっては幸せ

ソフトウェアの評価は、顧客にとって価値あるものにもとづいて評価すべき
完成して初めて価値になる
価値実現までの時間が短すぎるのもだめ
全体として出荷できるものを作る
効率より効果★
効果が出てから効率を求める

フィードバックをたくさんうけたほうが当たる確率が当たる
小さなバッチでフィードバック回数を上げる
継続的にお客さんやPOに見てもらう
フィードバックを受け入れないと意味が無い

5.CLEANコードを作る
品質は最初から作りこむしかない
検査で品質は上がらない

良くないコードの例はたくさんあるので、全部避けるのは難しい
→ 模範になるパターンを覚える
→ CLEANコード

Cohesive (凝集性)
1つの部品は1つの責任に集中する
1つのことをやってればはっきりした名前を付けられる
データってついたクラスや、チェックってついたメソッドは怪しい

Loosely Coupled (疎結合)
オブジェクト間の関係を明確な意図をもった状態に保つ
あとで差し替え可能にする。サービスを直接呼ばない

Encapsulated (カプセル化)
中を隠す
呼び出し側の観点で機能を作る

Assertive (断定的)
フィールドを持つなら、それを管理する挙動も持つ

Non Redundant (非冗長)
dry原則

テストのしやすさと設計のよさは相関関係がある
テストコードが書きにくいなら設計がよくない

早くテストしてバグを直さないと、後から見つけて直すとと640倍のコストがかかる
バグを作りこんでからの経過時間が長いほど、修正コストはかかる

明日のベロシティのために今日品質を上げる
速度って焦ってやっても早くならない
日々の積み重ねによってしか実現できない

素早く働く=綺麗に働く
散らかしながら進むのではない
繁盛しているお店ほど綺麗

これって5Sだった
整理、整頓、清掃、清潔、躾

テクニカルいくらがんばっても5Sができないと上手くいかない

まとめ
コーはド変更できるように書くべき
目的、理由、誰のため、を伝える。
小さく分けて意味のあるものからやる
小さなバッチでみんなで協力
テストコードも含めてCLEANを維持
継続して見直し。最初から完璧は無理。

【14-D-2】 エンプラアジャイル導入の守破離


セッション: https://event.shoeisha.jp/devsumi/20200213/session/2408/




【14-E-4】 アジャイル開発の原則を守りつつ、マルチサイト開発を行なう! ~ベトナムのメンバーとともにつくる~


セッション: https://event.shoeisha.jp/devsumi/20200213/session/2418/
アジャイル開発の原則を守りつつ、マルチサイト開発を行なう! from Arata Fujimura

自転車で山梨から伊豆への旅 4日目

2020/2/8(土)~2/11(火)の4日間、山梨県の河口湖から伊豆の下田まで、自転車で旅してきました。
このブログはその4日目(2020/2/11)の旅日記になります。

1日目の日記はこちら
http://makopi23.blog.fc2.com/blog-entry-349.html

4日目(2020/2/11)のスタート


4日目は静岡県の修善寺温泉街からほど近い「さくら堤公園」からスタートです。
20200211_010.jpg

2日目の夜にネカフェで読んだ「ゆるキャン△」 8~9巻で、なでしこ達が鳥羽先生の車に乗って伊豆キャンに向かった国道414号をメインに、下田へ向かいます~

「道の駅 伊豆月ケ瀬」でトイレ休憩~
20200211_020.jpg

天城峠を上っていきます。
20200211_030.jpg

天城峠の途中にある伊豆の観光名所、「浄蓮の滝」で休憩~
20200211_040.jpg

浄蓮の滝 伊豆の踊り子像。
20200211_050.jpg

浄蓮の滝は狩野川にある高さ25mの滝で、地元の女郎蜘蛛に関する伝説にも登場するそうな。
日本の滝百選の一つでもあるそうな。
20200211_060.jpg

天城峠の頂上近くにある「道の駅 天城越え」で休憩~
20200211_070.jpg

わさびで有名なんだそうな。
ゆるキャン△ 8~9巻で、なでしこ達一行が下田に行く前に立ち寄った場所でもあります。
20200211_080.jpg

20200211_085.jpg

わさびソフト。わさびは注文してからすりおろして、ソフトクリームの側面に付けてくれますw
20200211_090.jpg
20200211_095.jpg

天城峠の頂上には、長さ800mの新天城トンネル。
20200211_100.jpg

新天城トンネルを抜けると河津町です。
20200211_110.jpg

国道414号に沿って南下し、河津七滝ループ橋へ。
20200211_120.jpg

ゆるキャン△ 8~9巻で、なでしこ達一行が下田に行く時に通った場所で、伊豆の観光名所の1つです。
下る側なので助かった・・・・上りだとかなり傾斜が辛そう・・・
20200211_130.jpg
20200211_135.jpg

河津町ではちょうど昨日から河津桜まつりが開催されています。綺麗~
20200211_140.jpg

河津桜は1月下旬から2月にかけて開花する早咲き桜だそうな。
ゆるキャン8~9巻で渋滞に巻き込まれた原因w
20200211_150.jpg

20200211_155.jpg

河津駅前。河津桜まつりの観光客で混んでます。
20200211_160.jpg

河津駅からちょっと進むと海が見えてきます。
20200211_170.jpg

海沿いの国道135号を南下し、尾ヶ崎ウイングで休憩。
伊豆半島の外周は高低差が大きく、サイクリストにとって厳しいコースとして知られていますが、ほんと坂が多くてキツい・・・
20200211_180.jpg

白浜神社へ。伊古奈比咩命神社とも言うそうな。
20200211_190.jpg

伊豆最古の神社なんだそうな。こちらは拝殿。
20200211_200.jpg

参道を登ると、「これより御本殿聖域」と書かれた立札があります。
20200211_210.jpg

参道を上がったところに本殿があります。
20200211_220.jpg

白浜大浜海水浴場。砂浜が綺麗です。
20200211_230.jpg

まどが浜海遊公園へ。
20200211_240.jpg

ゆるキャン△の8~9巻で、リンちゃんが訪れた場所です。
20200211_250.jpg
20200211_255.jpg

海遊の足湯。
20200211_260.jpg
20200211_265.jpg

毘沙子島。
20200211_270.jpg
20200211_275.jpg

黒船?
20200211_280.jpg
20200211_285.jpg

「道の駅 開国下田みなと」へ。
20200211_290.jpg

道の駅内にあるRa-maru。
ゆるキャン△ 8~9巻で、なでしこ達が金目鯛バーガーを食べる場所です。
下田バーガーのことなんですね。
20200211_300.jpg
20200211_305.jpg

ペリーロードヘ。
ペリー艦隊が下田に上陸し、300人の部下を引き連れ了仙寺まで行進した約400メートルの道だそうな。
20200211_310.jpg

今回の旅の終着点、伊豆急下田駅へ。
駅前にある黒船 サスケハナ号。
20200211_320.jpg

自転車を輪行袋に詰め、伊豆急下田駅前から輪行で帰ります~
20200211_330.jpg

最終日は56kmほど走りました。
20200211_340.jpg

まとめ


山梨県の河口湖から出発し、静岡県伊豆半島にある下田まで、とっても楽しい旅でした。
真冬で寒いけど、防寒対策をすれば道中もテント野宿もなんとかなりますね。

今回のルートはこんな感じ。
1日目: 17km
2日目: 81km
3日目: 43km
4日目: 56km
---
合計: 197km
20200211_350.jpg

花粉症シーズンに突入してしまったので、しばらく自転車旅はお預けです。
ゴールデンウィークになったら、また自転車旅を再開したいと思います。
今度はどこへ行こうかな~
次のページ

-->