Shinonome Tech Blog

株式会社Shinonomeの技術ブログ
8 min read

【渋温泉ハッカソン: チーム 8】外湯の混雑度を可視化したい

こんにちは、8 班リーダーの Yuji です。 私達の班では、渋温泉の外湯内の混雑度を計測して Web 上でいつでも見れる仕組みを作成しました。

こんにちは、8 班リーダーの Yuji です。
私達の班では、渋温泉の外湯内の混雑度を計測して Web 上でいつでも見れる仕組みを作成しました。

成果物

まずは簡単にハッカソン期間中に作製したものを紹介します。詳細については作業内容で触れていきます。

デザイン・フロントエンド

こちらが 8 班で作成した WEB アプリの画面です。

WEB アプリの画面

ユーモアな方法で混雑度を表現しようとした結果、渋温泉は野生の猿が温泉に入ることで有名ということもあり、混雑していくにつれて猿の人数を増やすことにしました。

渋温泉には 9 個の外湯があるので男女を分けると合計 18 個の混雑度を利用者に届けなければなりません。しかし、それらをすべて 1 つのページに表示すると情報過多になってしまうため、男女別に表示して上の暖簾ボタンで切り替えられるようにしました。

バックエンド

バックエンドの使用技術と構成は、下図の通りです。

構成図

バックエンドの一番のアピールポイントは、クライアントとサーバー間に双方向通信が可能な WebSocket を採用したことで、センサーが人の出入りを検知した時点で WEB ページの混雑度が更新されることです。この WebSocket の実装には Django Channels を使用しました。

さらに、外湯の人数が 0 人になったら利用者に LINE bot から通知が届く仕組みも実装しました。

作成した LINE のトーク画面

入退室検知アルゴリズム

赤外線センサーを出入口に 2 つ設置して、どちら側から入ってきたかを判定するというシンプルな仕組みです。

センサー

センサーと障害物の距離が小さいほどセンサーが出力する信号は大きくなります。
この信号がしきい値(今回は 70)を超えている時間は「人がセンサーを遮っている」とみなして、外側・内側のどちらのセンサーが先に反応したかで入室・退室を判断しています。

アルゴリズム

作業内容

アイデア出し

一番最初のミーティングでは、どんなものを作りたいかを整理するために、FigJam を使って ブレインストーミング を行いました。さすが FigJam はブレインストーミング専用のサービスなのでとても使いやすかったおかげでアイデアの議論に集中することができました。

FigJamでのアイデア出しの様子

ちょっとした工夫としてカードの色を

  • 事実: パープル
  • 意見: グレー
  • 疑問: イエロー

で色分けすることで混乱しないようにしました。
これにより、

  • パープル → 解決したい課題、制限事項
  • グレー → 決めなきゃいけないこと
  • イエロー → 質問しなきゃいけないこと

ということが分かり、次の行動を決めやすくなりました。

デザイン・フロントエンド

「外湯の混雑度を可視化する」という試みには城崎温泉も取り組んでいました。単純に混雑度を数値化して可視化するだけでは、以下のサイトの再現実装になってしまうため、趣向を変えて渋温泉の雰囲気に馴染むようなデザインとしました。

城崎温泉の混雑状況
https://kinosaki-onsen.net/congestion/

フロントエンドとしては、データコースの子がフロントを書いてくれたこともあり、マークアップメインの実装にしました。また、フロントコースの子にはロード時のアニメーションを作成してもらいました。なかなか時間が合わずフロントはギリギリになってしまったのですが、なんとか見せられるものはできて良かったと思っています。

最終発表会のときにデザインに対して、「混雑度の表示を数値ではなく画像で表示するのは分かりにくいのではないか」という質問を頂きました。私はこれがずっと頭の中に残っています。すぐに「システムは常に正確な人数を表示できるわけではないので、正確な情報を表示するよりも少しぼかした方がむしろ良いのではないか。」という回答は思い付いたのですが、成果物が不完全という印象を与えるのではないかと思って口に出すのを躊躇ってしまいました。しかし実際は、センサーの前に人がずっと居たり Wi-Fi が止まったりなど外的要因もあり得えます。なので私はあのとき胸を張って「システムは完璧には作れない。」と言っても問題なかったのだと気づき、その後悔で忘れられないのかもしれません。デザイン・フロント担当のnacchanです。この質問に関してデザイン的な回答ができていたら良かったと思うことがあります。「観光客は外湯の狭さを知らない人も多いので仮に"4人入っている"という情報を得てもそれが"混雑している"という認識に繋がらない可能性がある、また海外のお客さんも多いのであまり言語での表現は避けたかった」ということです。直感的に混んでいるのか空いているのかを伝える手段としても画像で良かったのではないかと思っています。その場ではうまく回答することが出来ず私も後悔している点であります。

バックエンド

PlayGround のバックエンドコースの受講中のメンバーに多くの範囲を実装してもらおうと思っていたので、使用技術はコースで扱っているものとほとんど同じにしました。このおかげで、バックエンドの開発はかなりスムーズに進みました。

しかし、せっかくのハッカソンでコースと同じ技術で、より簡単な構成のアプリを作るのはもったいないなとも思っていました。偶然、レビュワーの私の担当領域の進捗も終盤に急に良くなったので、急遽 WebSocket を採用して未経験の技術にチャレンジをすることにしました。このチャレンジは無事成功し成果物が一層良いものになりました。

今回の構成は目指していたものというより、トライ・アンド・エラーを繰り返した結果成功した一例です。そのため、Arduino と Django サーバー間の通信で認証を行えなかったため、誰でも人数を変更するリクエストをサーバーに送信すれば一時的に偽の混雑度が表示させる事ができてしまいます。これは、Arduino IoT Cloud を経由せずに Django と直接通信すれば避けられそうですが、エラーが解決できなかったので諦めました。

必要最小限の機能要件を満たすのは意外となんとかなりますが、UX の向上やセキュリティを考慮すると数倍のコストとスキルが必要になるのだと感じました。ただ、世の中のサービスの差とはこのようなところで生じているので、今回 WebSocket を採用したように可能な限りつぎ込んでいきたいですね。

入退室検知アルゴリズム

アルゴリズムの担当だった私は普段 Python で機械学習を始めとするデータ分析のコードを書いているので、IoT 開発は完全に未知の領域でした。そのため、技術的制約がかなり大きかったのでアルゴリズムはできる限りシンプルにしました。しかし、処理を大まかにしたことで信号に含まれる細かいノイズが無視されるというメリットもありました。

最終的に、人が通った方向に応じてデータベースの人数が増えたり減ったりすることが確認できました。この機能は 8 班の成果物になくてはならないものだったので、これができたときは歓喜の瞬間でした。

私としては、「結構良い」アルゴリズムができたと思っています。ただし、この定性的な表現では審査員は何も評価をすることができないのではないかと、最終発表会での聞き手の反応や自分が聞き手として他の班の発表を聞いているときに感じました。もしセンサーの前を様々なパターン通る実験を十分な回数行った結果を提示していたら順位は変わっていたのかもしれません。
この一手は成果物の説得力を「とりあえず動いてる」から「動くことを保証する」に進化させるので、重要度を見誤っていたと最終報告会を聞きながら感じました。

感想

Yuji

センサーの前を人が通ったときの信号をアルゴリズムが解析して人が通ったことを検知できたらサーバーにリクエストが飛んでクライアントの表示が更新される。そして、これが全てリアルタイムに実行される。このシステムを Arduino という固有名詞を初めて知ってから 2 週間弱で完成させることができた。そう振り返ると、めちゃくちゃすごいことをしたんだなという感慨深いものがあります。
今後、ハードウェア開発に関わる予定はないので、今回身についた技術が何かに直接活かされる機会はないかもしれませんが、間違いなく技術とは別の、エンジニアとして大切なものをこのハッカソンで成長させることができた気がします。

nacchan

デザインでは、上に書いたように質問にいつでも回答できるように、デザインを言語化する癖を日常的につけておき、メモしておくべきだなと感じました。普段後輩と関わる機会がほとんどないので、フロントを書いてくれる後輩が3人ってなった時は正直どう進めていいか戸惑ってしまったのですが、現地で一緒に作業できて楽しかったです。深夜にみんなで焦りながら作業するあの感覚はやっぱりなんとも言えない楽しさがあって、オフラインで集まれる環境でできてよかったなと思います。

arisa

システムの構想から完成までの一連の工程をこんなにも近くで見ることができたのは、このハッカソンが初めてでした。約2週間という中で、アイデアだったものが実現されていき、ワクワクの連続でした。
しかし、その感動とは裏腹に、自分のふがいなさを痛感していました。できることはやる!頑張る!という意気込みで参加したものの、できることがあまりに少なすぎて、むしろ先輩方の迷惑になっていたと思います。技術力、プレゼン力共に今後の課題です。
このように、感動と自分の力不足を強く感じた今回のハッカソンは、自分にとって貴重な体験でした。この経験を無駄にせず、次はプロジェクトの重要な一員になって誰かの役に立てるよう、勉強していきます。ありがとうございました。

Ryohei

初めて開発現場を間近でみることができ、普段からリーダーの方達はこんなふうに開発しているのか、ということが分かりました。同時に、開発を教えてもらいながら先輩方からplayground初期の頃のお話まで聞けて、なんとなくどんなグループなのかということも掴めた気がします。
自分はチームにとって足を引っ張る存在でしたが、最終課題序盤で詰まっていたところから、「GitHubの使い方、効率の良い調べ方」などを対面で教われて、なんとか進められる希望が見えた気がします。ありがとうございました。

Airi

今回のハッカソンでは色々な刺激を受けることができたと思います。幅広い知識を持っているかたがいたり、すごく技術の高い方がいたり、魅力的なプレゼンをする方がいたりと自分と同じ世代にも関わらず自分にはないものを持っている方がたくさんいるんだと改めて実感しました。開発に携わるのが今回で初めてだった私はできることが本当に少なく、チームの方々にたくさん迷惑をかけてしまいました。そんな私にも優しく教えてくださった先輩方には感謝の気持ちでいっぱいです。今度はチームの迷惑にならずに貢献できるように今まで以上にプログラミングの勉強を頑張って先輩方のようになりたいと思いました。この経験を生かしてこれからも頑張りたいと思います。ありがとうございました。

Ayu

このハッカソンは驚くことばかりで、とても刺激のある良い経験になりました。特にチームでの開発が初めてだったので、githubが他の人によって更新されていく様子や自分が担当した部分が実装されたりと、一人で開発している時には味わえないものを体験させていただきました。
技術も理解力も足りず、ご迷惑をおかけすることが多かったと思いますが先輩方には優しく丁寧に教えていただきました。また、先輩方のプログラミングに対する知識の量や、私達への教え方、仕事の振り方などためになるものばかりでした。本当にありがとうございました。この経験を活かし、これからはさらに頑張っていきたいと思います。

(あとがき)ハッカソンというのは技術的にも期間的にも制限が大きいので、班に限らず多くの新入生にとっては大変な期間だったと思います。もし、何かに躓いたときに頼るというのはチームにとってはプラスにはたらくので、このような機会では迷惑とは微塵も感じずにどんどんしても大丈夫です。
また、このイベントは腕試しという良いアウトプットの機会でしたが、50 人くらいがそれぞれの武器を持って切磋琢磨してるので、知見を増やして自分のスキルを深めたり広げるという最高のインプットの機会でもあります。魅力的に感じた技術を一つでも多く持ち帰るという一番大切なアクションはみんな出来ていたと思います。これを次回以降や普段の勉強会でも続けていくといつか最優秀賞を持ち帰ることができるかもしれません。