メカ設計と3D CADのお話

メリークリスマス!Akerun Advent Calendar 24日目担当のskytthkと申します。 フォトシンスでは主にメカ設計を担当しており、今年は新製品、Akerun Proの開発~量産立ち上げに奔走しました。

今日はメカ設計とCADのお話です

早速ですが皆さん、3D CADってご存知でしょうか?そうです、メカ設計者の必需品、3Dで形状を設計していく、アレです。

この手のソフト、ひと昔前まではプロ仕様のものを買おうとすると1ライセンス数十万~という世界でした。学生時代はSolidworks、前職の携帯電話の設計ではPro/engineerを使っていましたが、自主トレーニングしたいときやモデリングして遊びたいとき、自宅では触れないので学校や会社でいじるしかありませんでした。しかし最近では無料、もしくは個人でも全然買えちゃうような価格で、面白いソフトが出始めています。

f:id:photosynth-inc:20161222211808j:plain

エッジの線が増えるたびにニヤニヤしちゃいます

Fusion360(AUTODESK)を使ってます

そんな新興CADの中でも個人的一押しはAUTODESKさんのFusion360です。これまであまり無かったクラウドベースのCADで、新機能もばんばん追加されます。(最近では板金設計モードやECADのEagleとの統合、ブラウザモードの追加などがアナウンスされました。)図面作成など量産を見据えた機能を一通り押さえつつ、レンダリングや解析までこなせるすごいやつです。特に機能追加のペースの早さは圧巻で、気づいたら色んな機能追加や改善がされています。 細かな点はハイエンドに及ばない所もありますが、弊社では今後の期待も込めてメインの3D CADとして採用しており、Akerun Proの開発でも活用させて頂きました。

前置きが長くなりましたが、先日開発元のAUTODESKさんにお声がけ頂き、Fusion360のMeetupに登壇させて頂きましたので、その時のスライドを元に、ハードウェアスタートアップがどのように3D CADを活用しているかをご紹介させて頂きます。

当日の様子はこちら

3DCADで作ったもの

Akerun Proの内容物はこんな感じです。 本体や付属のセンサーなどに加え、設置用の両面テープや電池の絶縁シート、それからパッケージも、形状のあるものはすべて3D CADを使って形を設計しています。

f:id:photosynth-inc:20161222225000j:plain

部品の製造方法に合わせて形状を考える

単純に見える製品でも、その中身は様々な部品で構成されており、量産するための工法も様々です。Akerun Proのキット内でも、部品の役割や材質に合わせて様々な工法を採用しています。

射出成形

量産品には欠かせない、最もポピュラーな工法です。身の回りのプラスチック製品の多くはこの方法で量産されています。金型に溶けた樹脂を流し込み部品を量産します。(一般的に)複雑な部品形状になるほど金型の構造も複雑化しコストアップに直結するため、その部品に求めらる役割を如何にシンプルな金型で実現できるかが腕の見せ所です。

f:id:photosynth-inc:20161224161541j:plain

プレス加工

金属の板を、プレスで打ち抜いたり、曲げたりして形状を作る工法です。Akerun Proでは、本体を扉へ取り付けるためのプレートや電池端子をこの工法で量産しています。 抜きや曲げなど複数の工程を経て形状が作られるため、工程をイメージしながら形状を考えないとプレス屋さんに怒られます。 Youtubeで「順送プレス」とかで検索頂くと加工の様子がわかるかと思います。

f:id:photosynth-inc:20161224224209j:plain

切削加工

男の子の大好物、いわゆる削り出しです。Akerun Proの中央のボタンは、旋盤加工とマシニング加工と呼ばれる方法で削り出されています。刃物の通る道(ツールパス)を意識して形状を考えます。

f:id:photosynth-inc:20161224224252j:plain

ダイキャスト成形

Akerun Proの顔であるトップカバーは、アルミダイキャストで製造しています。原理的には(ざっくり)射出成形と同じで、金型に溶けた金属を流し込んで形状をつくります。樹脂よりも金属のほうが溶けたときの流動性が高く、冷却も早いため、成形後に「餃子の羽」のようなものが残りますが、マシニング加工できれいにします。

f:id:photosynth-inc:20161224224309j:plain

開発過程とCAD画面

順番が前後してしまいましたが、上記の量産行程に移る前には設計、試作、評価を繰り返します。弊社ではざっくり以下のようなフェーズでメカ開発を進めています。ここでは各フェーズのCAD画面をご紹介します。

f:id:photosynth-inc:20161224224832j:plain

原理試作

製品企画で決まった仕様を満たすメカ的な動きを実現できるかどうか、簡単な形状で試作を行い確認していきます。動きを確認できればOKなので、ほぼ手作り試作です。Akerun Proは通常の物理キーも使えるようにするため、動作時以外はモーターの動力を切るクラッチ機構を実現する必要がありました。歯車やその他の部品を組み合わせて、どうクラッチを実現するか?などをこの段階で検討します。

f:id:photosynth-inc:20161224231256j:plain

サイズ検討&デザインモック

Akerunは「後付け」スマートロックのため、サイズが大きくなるとそれだけ設置できない扉が増えてしまいます。各鍵メーカーさんのカタログとにらめっこしながら、対応する鍵を最大化するためのサイズを考えます。一方で内部には電池や基板やモーターなどの内装部品を入れるスペースを確保する必要があるため、部品の配置も含めて形状を考えなくてはなりません。

f:id:photosynth-inc:20161224232200j:plain

これでいけるというサイズ感が固まると、今度はデザイナーと一緒にデザインを固めていきます。ボタン付近のディテールは内装スペースとデザインのせめぎ合いで、3Dプリンターで何度もモックを作成し検討しました。

f:id:photosynth-inc:20161224233030j:plain

開発試作

駆動部分の設計方針とデザインが固まると、今度はそれを結合していきます。この段階の試作を、開発試作と呼んでいます。 開発試作では試作と評価を繰り返し製品全体の品質をブラッシュアップしていくと同時に、上でご紹介した工法を意識しながら「量産できる形状」に落とし込んでいきます。

Fusion360トップダウンモデリングボトムアップモデリングのどちらでも設計できますが、今回はボトムアップモデリングっぽいアプローチでアセンブリファイルを作成しています。部品点数が増えてくると、こちらの方が後々パーツ管理しやすいです。

f:id:photosynth-inc:20161224233319j:plain

開発試作~外装部品の設計~

外装部品は、ベースとなる形状を1つ作り、それを使いまわしながら設計していきます。

f:id:photosynth-inc:20161224234243j:plain

開発試作~アセンブリ

合致(ジョイント)機能を極力使わないようにするため、部品同士の原点を合わせるだけで組み立て状態になるように内装部品の原点を設定しています。部品点数が増えてくると隣接する部品も増え、依存関係がどんどん増えていきます。そうすると形状変更による意図しない位置関係のズレが発生することがあるので、このような方法をとりました。

f:id:photosynth-inc:20161224235851j:plain

開発試作~シミュレーション~

3Dプリンターの試作と量産時の部品では材料や製造方法が違うため、強度にも差が出てしまいます。大企業だと試作のために金型を起こして評価したりできますが、スタートアップにはなかなかそんな余裕はございません。 筐体の歪みなど気になる部分をシミュレーションで事前に確認し、形状をブラッシュアップしていきます。

f:id:photosynth-inc:20161225001051j:plain

出図

開発試作での評価試験をクリアできれば、量産に向けて本格的に動き始めます。量産部品をサプライヤーさんへ発注するためには図面が必要になりますので、一つ一つ作成していきます。最終的に60部品ぐらい図面を書きました。 ここが一番の山場です。

f:id:photosynth-inc:20161225003120j:plain

とっても、、大変でした、、

f:id:photosynth-inc:20161225005703j:plain

量産立ち上げ

残すは楽しい楽しい量産立ち上げです。製品の出荷を見届けるまで、工場に張り付きます。自分が設計した部品がどんどん形になっていくのはとても感動的で、メカ設計の醍醐味の一つです(大変なトラブルも付き物ですが!) こっちも別に機会があればご紹介できればと思います。

最後に

少し長くなってしまいましたが、ソフト屋さんと比べてメカ屋さんの情報ってあまり出てこないので、ちょっとでも興味をもってもらえたら嬉しいです。

ちなみにFusion360ですが、恐ろしいことに個人利用ならなんと無料で使えてしまいます。インストールして損はありません。これから3Dプリンターに挑戦したい個人の方はもちろん、量産を見据えたハードウェアスタートアップを始めたい方にもおすすめですので、ぜひ試してみてください。 また、開発元のAUTODESKさんですが、少し先の、未来のものづくりを考えていて個人的にすごい好きです。(例えばジェネレーティブデザイン。今後Fusion360にも搭載される予定とのこと!) ソフトの世界と比べて長年変わらずに来たメカ設計の世界ですが、いつか大変革が来た時に取り残されないよう、こういう新しいものにはどんどん触れて行きたいなーと思いつつ日々頑張っています。

Fusion360

株式会社フォトシンスでは、Webエンジニアを募集しています。ハードチームと連携して楽しいことができますよ!

www.wantedly.com

こんにちは、@taku33です。 今回はiOSペリフェラルのデータ通信を中心に、実際の開発時に有益そうなお話をします。

設計

大量のデータをwirte/notifyする場合などは、 BluetoothSIGの仕様により一回の通信でやりとりできるデータのサイズは20バイほどが基本単位 になっています。
複数機種でのデータ依存性をなくす目的でなら、これに忠実に通信を設計(セントラル、ペリフェラルともに)した方が良いです。

元の大きなデータを20バイトほどに細切れにして、それを何回も送るというやり方です。

特定の相手を認識

近距離の複数の同種類のセントラル端末との通信を想定する場合、Writeリクエスト受信時に呼ばれるコールバック didReceiveWriteRequests requests: [CBATTRequest]
が呼ばれた際、writeリクエストしてきた相手(request.central)を保持しておきます。
そうすることで、その後の通信(notification、writeリクエストなど)はこの特定の相手とだけ通信するように判定できるようになります。

Notification

Notificationするためのメソッド updateValue:forCharacteristic:onSubscribedCentrals: は BLE 通信が混在している場合にNO を返すことがあります。
NOが呼ばれた場合は送信に失敗したことになります。
これは、iOSハードウェア自体が処理可能な量より多くのデータをアプリ上では生成できるため、らしいです。

実際にも大量のデータを送る場合などでNOが返ることがありますので、これを考慮した実装は必須かと思います。
対策としては再送可能になった時点で peripheralManagerIsReadyToUpdateSubscribers:
デリゲートで通知されるので、この通知を受け取ったら再送するようにしましょう。

また、Notificationがセントラル側からキャンセルされた場合に呼ばれるコールバック didUnsubscribeFromCharacteristic
が呼ばれた場合、Notification送信途中でもNotificationはできなくなるので注意してください。

通信データ構造

データを送る場合、ヘッダデータ + ペイロード で分けるとわかりやすいと思います。
ヘッダデータには通信サービス識別子、連番数などを定義するのが一般的かと思います。
ペイロード内での同類のデータを区切ったり全データの終了判定をするには、 番兵として0x00や0xffを使って判定することができます。 もちろんその場合は、余計なところで0x00や0xffを入れないことが前提となります。

逆にデータを受け取る場合は、防御的に入力値を判定するべきです。
例えば仕様で決めた範囲から受け取ったデータが外れるような場合はそのデータを弾くようにした方がいいです。 (サイズが小さすぎる、ヘッダデータの形式が異なる など)

また、実際の運用においては、通信するデータ構造の仕様や説明はドキュメントなどでも共有しておくと良いと思います。

おまけ swift スニペット

UInt8作成
let nullTerminal:UInt8 = UInt8.init(0)

UInt8からNSData作成
let data = NSData(bytes: [nullTerminal] as [UInt8], length: 1)

NSDataをUInt8型Arrayに変換
var arr = Array(UnsafeBufferPointer(start: UnsafePointer(data.bytes), count: data.length))

UInt8をそのまま文字列に変換
String(format:"%02x", nullTerminal)

Akerun。コーヒー豆を挽ける、だだひとつのスマートロック

この記事はAkerun Advent Calendar 22日目の記事です。

本日も昨日に引き続きエンジニアの@koichi222が担当します。

先日バルミューダトースターがIoT化 されたことにより、フォトシンス社内で優雅な朝食をいただくことが可能になり従業員のQOLが向上しました。

しかし、最高の朝食にはまだ足りない物があります。


そう、コーヒーです。


私も毎日コーヒーを飲んでいますが、インスタントコーヒーは少々物足りなくなってきました。 しかしいいコーヒーメーカーを買うのはちょっと敷居が高いし、毎朝手動ミルで挽くのも億劫・・・


そうだ、我々にはAkerunがある。

ということでAkerunとコーヒーミル連携を実装しようと思います。

今回はこちらのコーヒーミルを使用します。

ではAkerunと連携(物理的な意味で)させていきましょう。

コーヒーミルの取っ手とフタを外すとこのような機構になっています。

f:id:photosynth-inc:20161222204228j:plain:w300

元々付属している金具を利用し、3Dプリンタで作成したアタッチメントと組み合わせ、このようなアタッチメントを作成しました。

f:id:photosynth-inc:20161222203952j:plain:w300 f:id:photosynth-inc:20161222204035j:plain:w300

アタッチメントをミルに取り付けます。

f:id:photosynth-inc:20161222204527j:plain:w300

現代アート感が出てきましたが続けます。

ちなみにこの時点でツマミ部分を手回ししてみましたが、かなり硬い・・・
仕事柄これまで多種多様の鍵を回してきましたが、それらと比較しても歴代トップクラスの渋さです。

大丈夫だろうか・・・

百聞は一見に如かず、やってみましょう。 そこらの木でサクッとAkerunの台座を作り、アタッチメントにはめ込みます。

f:id:photosynth-inc:20161222205255j:plain:w350f:id:photosynth-inc:20161222205233j:plain:w350

一気にコーヒーメーカー感が増しました!いいですね!

いよいよアプリから操作してみます。緊張の一瞬・・・

f:id:photosynth-inc:20161222214036g:plain

ギリギリですが、なんとか豆は挽けるようです!

しかし新たな問題も発覚しました。

Akerun Proは様々な種類の鍵に対応するために解錠位置と施錠位置の角度を自由に設定できるようになっているのですが、 設定位置した位置に達すると動作を停止するため、コーヒー豆を挽くのに適した仕様になっていないのです。


困り果ててファームウェアエンジニアの@ishturkに相談したところ、停止を指示するまで回り続ける特別なファームウェアを用意してもらうことができました!これでどんどんコーヒー豆を挽いていきます。

勿論、アプリだけでなくAkerun Remoteを経由した遠隔操作も可能です。

朝家をでる頃に遠隔操作すれば、出社した頃には引き立ての豆が用意されているという素晴らしい体験ができますね。

しばらく動かした後、挽いた豆はこんな感じになりました。

f:id:photosynth-inc:20161222222045j:plain:w300

けっこう粗いですね。

肝心の味はどうなんでしょうか。

f:id:photosynth-inc:20161222222004j:plain:w300

うーん、何とも言えない味です。

香りはいいし、悪くない!が、何かがたりないような・・ ただ一生懸命に挽いてくれたAkerunのことを思えば自然と美味しく感じてきます。



以上、Akerun。コーヒー豆を挽ける、だだひとつのスマートロック、でした!いかがだったでしょうか?

優雅な朝を過ごしたい方は、ぜひAkerunバルミューダトースターとAkerunコーヒーミルをお試しください!

最後に

コーヒー豆も挽けるほどのトルクのAkerun Proのご購入はこちらから。 akerun.com

株式会社フォトシンスでは、中の人としてAkerunを公式にハックしたいWebエンジニアを募集しています。 www.wantedly.com

Akerun Developersサイトもやってます。AkerunをAPIで他のサービスとの連携を考えたい方はぜひ。 photosynth-inc.github.io

【動画あり】Google AssistantでスマートロックAkerunを音声操作する

f:id:photosynth-inc:20161222062533p:plain

この記事はAkerun Advent Calendar 21日目の記事です。

はじめまして、エンジニアの@koichi222です。主にサーバーサイドを担当しています。

突然ですが、フォトシンスのエンジニアたちが常日頃考え続けておりしばしば社内で議論になる問いがあります。それは、

最高の鍵の開閉方法は何なのか?です。

実際にこれまでの弊社プロダクトも、スマートフォンアプリでの鍵の開け閉めに始まり

  • アプリの位置情報で鍵を開けるハンズフリー機能
  • スマートウォッチ対応(Apple watch, Android Wear)
  • ブラウザから鍵を開けることのできるURL鍵
  • スマホをかざして鍵が開けられるAkerun Touch
  • Sucicaで鍵が開けられるNFCカード対応

などなど、続々と新たな鍵を開ける方法をユーザーへ提供してきました。 (先日のAdvent CalendarではAmazon Dashボタンで鍵を開けるというのもありましたね!)

そこで今回は、前々から試したかった音声でのAkerunの操作をチャレンジしてみようと思います。 これまではなかなか1エンジニアが試すには敷居の高かった音声認識ですが、最近はオープンなSDK,APIが充実してきて敷居が下がってきています。今回は最近Developer向けに公開されたGoogle AssistantのActionが作成できるActions on googleを利用して実装したいと思います。

developers.google.com

処理の概要

手順の詳細に入る前に、下図で処理の全体像を頭にいれてもらうとわかりやすいかと思います。

f:id:photosynth-inc:20161222061356p:plain

それぞれの役割は、ざっくりと以下のような形です。

Google Actions SDK

  • ユーザの音声入力を解釈する処理を書くためのSDKです。
  • このSDKを利用してコードを書いていっても良いのですが、今回はAPI.AIを利用してラクをすることにしました。

API.AI

  • Google Actions SDKで行うような処理を、すべてGUIで設定できるツールです。 api.ai

  • イベントのトリガとなるキーワードを指定することは勿論、ユーザの音声入力中の特定ワードをパラメータとして指定することで抽出することも可能です。

  • 今回やろうとしているのは抽象化すると "ユーザが「◯◯」と話したら、☓☓をする。" ということなのですが、◯◯の部分を定義し、検知するのがAPI.AIになります。☓☓の内容を記述するのは後述のwebhookの送信先で、API.AIでは一切扱いません。API.AIはあくまでwebhookで処理の橋渡しをするだけです。
  • 今回は、「Open door lock」と言われたら、処理を開始するように設定します。

webhook送信先

  • 前述の"ユーザが「◯◯」と話したら、☓☓をする。"のうち"☓☓をする。"に相当するビジネスロジックを記述するのがここです。例えば外部サービスのAPIを叩いてゴニョゴニョするなどです。
  • githubにテンプレートが用意されているので、参考にして処理の部分を追記するとよいです。
  • GCPでもHerokuでもAWSでもよいのですが、API.AIからのリクエストを受けられる場所でアプリケーションが起動している必要があります。
  • 今回は、Akerunの開閉APIを叩く処理をここで行います。

Akerun API

  • 弊社が提供しているAkerunを操作したり、情報を取得するAPIになります。
  • 残念ながらAkerun開閉のAPIは2016/12/21時点では一般には非公開ですが、今回は開発用のものを利用します。

手順

では具体的な手順に入っていきましょう。 エージェント、インテントなどいろいろ新しい概念が登場するのですが、まず動かすところまでたどり着く!をゴールに、概念の説明は省いてサクサクとやることを並べていきます。最後まで進めるとそれぞれ概念の意味合いがなんとなくわかってくるのではと思います。

① [API.AI] エージェント作成

下記にアクセスしアカウントを作成、ログインします。 api.ai

エージェントを作成します。 https://www.evernote.com/l/ABrKZomUN-lBc71OdPMU5sBbKU3iGhRZkD4B/image.png

② [API.AI] インテント作成

エージェントの次はインテントを作成します。 https://www.evernote.com/l/ABpHqjGg5uhAKbxFCh-0BYgyZ0jd-qyY9PcB/image.png

API.AIでは画面右側に表示されている入力欄から常に最新版エージェントの動作が確認できます。 ここまでの動作を確認してみましょう。
https://www.evernote.com/l/ABpeVmV2yvtB7q0SIKWYaBk4KI8lpx-4vCsB/image.png
このような特定の入力値に反応して固定の文言を返す、と言ったシンプルなbotでしたら、ここまでの作業で完成してしまいます。 便利ですね。

③ webhook用のアプリケーションを作成

まずGoogleが公開しているテンプレートを手元にcloneします。 github.com

app.jsを開きます。 関数responseHandler内にロジックを記述するようコメントがあるので、Akerun APIを叩く処理を追記します。

app.js

 26 app.post('/', function (req, res) {
 27   const assistant = new Assistant({request: req, response: res});
 28   console.log('Request headers: ' + JSON.stringify(req.headers));
 29   console.log('Request body: ' + JSON.stringify(req.body));
 30 
 31   // Fulfill action business logic
 32   function responseHandler (assistant) {
 33     // Complete your fulfillment logic and send a response
 34 
 35     // 処理開始時に話す
 36     assistant.tell('Start Opening');
 37     // Akerun開閉APIを叩く ※ 非公開のため、仮のurlです。
 38     var options = {
 39       uri: "https://api.akerun.com/v1/akerun/xxxx/open",
 40       headers: {
 41         "Content-type": "application/x-www-form-urlencoded",
 42       },
 43       form: {
 44         "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
 45       }
 46     };
 47     request.post(options, function(error, response, body){});
 48   }
 49 
 50   assistant.handleRequest(responseHandler);
 51 });

新しく利用したモジュールがあればpackage.jsonも更新しましょう。

④ webhook用のアプリケーションをデプロイ

②のアプリケーションをデプロイします。 デプロイ先はどこでもよいのですが、Google Couldかherokuが手軽でおすすめです。 自分はこのあたりを参考にGoogle Couldにデプロイしました。 qiita.com

Herokuだと以下などが参考になると思います。 1000ch.net

デプロイが終わったらurlを控えておきます。

⑤ [API.AI] webhookurlを設定

左メニューからFulfillmentを選択し、webhookの設定をします。
Google Cloudにデプロイした方への注意点なんですが、コンソールでデプロイ時に表示されるurl(https://xxxxxx.appspot.com)でなく、 そのurlをブラウザで開いたときにリダイレクトされるurl https://xxxxxx.appspot-preview.com/ を設定してください。

https://www.evernote.com/l/ABpuSY92a0BKFaIRepAIQx-45W9E8EIu-2EB/image.png

ここまでで、API.AIのwebhookがちゃんと動作できているかを確認しましょう。

https://www.evernote.com/l/ABoliQaTzgVJYrYkZkekJPNeu0tkP9k6Y6IB/image.png

念のため④でデプロイしたアプリのログも確認しておくと良いかと思います。
ここでうまくいけば、あともう一息です!

⑥ [API.AI] Actions on googleとのインテグレーション設定

Actions on googleとの連携を設定します。

https://www.evernote.com/l/ABoQtczsFkpFoIUEz3LglljXZeAScNFKJx0B/image.png

設定が終わったら「AUTHORIZE」を押します。 すると少し時間が合った後、以下のようにダイアログ右下の表示が変わります。

https://www.evernote.com/l/ABoAR906b2JMsqe7gB-QLzb7F5gpNgRduTQB/image.png

「PREVIEW」を押して少し待つと、画面右下に以下のようなポップアップが出ますので、 ここからWeb simulatorへと遷移します。

https://www.evernote.com/l/ABqHtGxQhX1P3JApMOfUcOTdd-KUF3cAB-AB/image.png

https://www.evernote.com/l/ABqIy6S49ElGbIPo90r2bEDzZbOflm4erkcB/image.png

⑦ [Actions on Google] Web simulatorで動作確認

⑥が正常に終われば、Web simulatorが利用できる状態になっているはずです。

https://www.evernote.com/l/ABqx9_yQR2pNBLojqxS8H-apGjXLmd4X664B/image.png

ではマイクから音声入力してみましょう。

音声であけるん #googleassistant #akerun

koichi saitoさん(@koichi222)が投稿した動画 -


来ましたー!!
テンション上がりますね、これは。

⑧ [Actions on Google] 作成したActionを審査&デプロイ

ここまでで作成した一連の処理を、Google AssistantではActionと呼んでいます。シュミレータ上でActionの動作は確認できましたが、実際のGoogle Homeデバイスで利用したい場合には審査を経て本番環境へのデプロイが必要になります。今回は詳細手順は省略しますが、興味のある方は下記ドキュメントを参考に試してみて下さい。日本でもGoogle Homeの発売が待たれますね!
Deploy your Actions  |  Actions on Google  |  Google Developers



以上、Google AssistantでスマートロックAkerunを音声操作する、でした。いかがだったでしょうか?今回は鍵の操作のインターフェースとして音声入力を紹介しましたが、日常で音声による操作がかっちりとハマるユースケースについては、まだまだ埋もれているものが多いと思います。今回の記事を気に入った方はぜひGoogle Assistantを利用して、サクッと音声操作をプロトタイピング&トライしてみて下さい!

Developerサイトのドキュメントも充実していますので、興味のある部分からぜひ読んでみることをオススメします!
Conversation Actions  |  Actions on Google  |  Google Developers

最後に

株式会社フォトシンスでは、最高の開閉体験を提供することに情熱を燃やせるWebエンジニアを募集しています。 www.wantedly.com

Akerun Developersサイトもやってます。AkerunをAPIでハックしたい方はこちらをどうぞ。 photosynth-inc.github.io

Akerun Proのご購入はこちらから。年内はキャンペーン価格でお得のようです。 akerun.com

IoT企業社内便利ツール③ IoT製品なら必須の地味だけど大切なバイナリ置換の話 / Akerun Advent Calendar 20日目

みなさん、Akerunしてますか?(挨拶)

この記事はAkerun Advent Calendar 2016 - Qiitaの20日目の記事です。

今日は社内バイナリ職人のkazuphが担当します。

IoT企業ならバイナリ置換するよね??

Linuxじゃないマイコンレベルの組み込み前提

あ、いきなりですがしない方法もあります。マイコンへはすべての個体で一律にファームウェアバイナリを書き込んでおいて、別個でユニークなIDをメモリに書き込むパターン。 僕らはやったことないですが、そうやっている企業も多い?でもメモリへ直接のインターフェースをつくるか、工場出荷時のみマイコン経由でメモリへつながるインターフェースをつくるか?そういう悩みが発生しそう。

あとはソースコードが参照している認証情報をまとめているファイル自体を置換して、その後コンパイルするパターン。これならバイナリ自体は置換する必要ない。

で、最後にコンパイル後に生成されるバイナリの中身を置換しにいくパターン。

単にガジェットならID管理する必要すらないかもだけど、ネットにつながるなら、BLE使うなら認証系の鍵・証明書はもちろんユニークに埋め込むわけで。何かしらの方法でやっているはずかなーって。

で、この前は発表自体はしなかったのですが、アップロード時の資料にはこんなスライドを追加していました。

f:id:photosynth-inc:20161221000409p:plain

f:id:photosynth-inc:20161221000412p:plain

f:id:photosynth-inc:20161221000414p:plain

f:id:photosynth-inc:20161221000417p:plain

f:id:photosynth-inc:20161221000419p:plain

カジュアルにUnix上でmakeできるような良心設計なマイコンSDKが提供されているならまだいいですが、Windows環境でしか条件を満たすバイナリを生成できないケースもあったりするので、どうせ置換するならバイナリ置換に倒してもいいかなと。

一応ソース置換の話

#!bin/bash
perl -i -p -e "s/(__ID) (.*)?$/\$1 ${ID}/" $CONFIG_SOURCE_PATH

#define で定義してある箇所をPerlワンライナーで置換する。それをシェルスクリプトで束ねて、引数でIDや認証情報を食わせればそれで完了。 まあ実装は楽でしたね。一瞬。

バイナリ置換の話

で、メイン。

うわー、俺Web系だからバイナリとか置換できないょぉ、みたいな感じだったのですが、やったら案外できたみたいな。

まず親しみを込めてVimからバイナリを眺める

普通に開くとこんなん。

$ vim hoge.bin

f:id:photosynth-inc:20161221002439p:plain

蕁麻疹出るやつ。

でもこの状態で、

:%!xxd

とするとこうなる。

f:id:photosynth-inc:20161221002550p:plain

ちなみに -g オプションを付けると、区切る間隔を変更できる。

:%!xxd -g16

f:id:photosynth-inc:20161221002801p:plain

(;´Д`)ハァハァ このままVimで置換しょぉ

$ vim -b <IMAGE_NAME>.bin +'%!xxd' +'%s/9999 9999/7777 7777/g' +'%!xxd -r' +wq

一応1行に必ず出てくる一部の文字列ならこれで対応できます。

VimからPerl

そうそうに"それVim"を切り上げてPerlで置換しにいきます。ですが、今回はバイナリです。どうやるのでしょうか?

こうやります。

# 文字(数字)をPerlが認識するバイナリ形式に変更
num_to_binary () {
  echo $1 | perl -ane '@ary = $_ =~ /.{2}/g; @x = map{"\\x".$_} @ary;print @x;'
}

perl -pi -e "s/`num_to_binary $BEFORE_ID`/`num_to_binary $AFTER_ID`/" ${FW_PATH}.bin

$BEFORE_ID などに入っているのは 8F3A145B...みたいな1バイトを16進数表示で並べた文字列です。2文字ずつ区切って処理しています。 これなら、一度binを人間が読めるテキスト形式にせずともバイナリの世界のまま置換してくれます。

元データが文字列の場合は以下の様になります。

# 文字(ASCII)をPerlが認識するバイナリ形式に変更
string_to_binary () {
  echo $1 | perl -ane 'map{$str = unpack("H*", $_);@ary = $str =~ /.{2}/g; @x=map{"\\x".$_} @ary;print @x;}@F'
}

perl -pi -e "s/`string_to_binary $BEFORE_NAME`/`string_to_binary $AFTER_NAME`/" ${FW_PATH}.bin

BEFORE_NAME へは akerun_name みたいな文字列が入ります。

単純なバイナリなら、これで完璧です。

IntelHex形式をbin形式へ

ここでmake時にデフォルトでIntelHex形式を吐き出すツールチェインもあります。

Intel HEXはバイナリ情報をASCIIテキスト形式で運ぶためのファイル形式である。マイクロコントローラやEPROMなどのプログラム可能なデバイスのプログラム書き込みのために広く用いられている。典型的な利用用途としてはコンパイラアセンブラがプログラムのC言語アセンブリ言語などのソースコード機械語に変換し、HEXファイルとして出力する。

Intel HEX - Wikipedia

詳しくはウィキってもらうとして、マイコンに書き込むバイナリは、単なる01を羅列したバイナリじゃなくて、このIntelHex形式じゃないと正しく動作しない場合もあります(IntelHexからbinへの変換は書き込む位置の情報が失われる)。

見た目はこんな感じのやつです。

f:id:photosynth-inc:20161221010633p:plain

今までの方法を使いたいなら、単純にIntelHex形式をbinに変換しましょう。binにした結果必要な情報が失われて結果正しく動作しないファームウェアになってしまう可能性もありますが、その場合は後で示すIntelHexを直接置換する方法を実践しましょう。

ここでPythonさんの登場です。

github.com

pip install intelhex

これでhexからbinに変換するコマンドも一緒にインストールされます。

$ hex2bin.py $FW_PATH.{hex,bin}

これでOKですね!

IntelHex形式に対して直接置換行為をはたらきたい

これはちょっと苦しめられました。特にPerlワンライナーで全部やろうと腹を決めていた自分に取っては屈辱的でしたが、ここでRubyさんを召集することにしました。

#!/usr/bin/env ruby

# チェックサムを計算する
def calculate_checksum (line)
  ary = line.sub(":", "").each_char.each_slice(2).map(&:join)
  sum = ary.map{|x| x.to_i(16)}.inject(0){|a, i| a + i }
  "%02X" % (((sum ^ 0xffff) + 1) & 0x00ff)
end

# バイナリデータの部分だけ抽出する
# 本当はもっと色々やってる
File.open("org_intelhex_file.hex") do |file|
      leading_codes << line.slice(0, 9)
      data += line.slice(9, 32)
end

# ソース中で使ってるデフォルト設定を引数で受け取ったデータで置換する
replaced_data = data.sub("1A3F56...", ARGV[1].upcase)

# データ部分を元のIntelHexの形式であるn文字区切りにする
data_ary = replaced_data.each_char.each_slice(n).map(&:join)

# データの先頭についていたコードを付け直す
leading_codes.each_with_index do |code, i|
  line = code + data_ary[i]
  # 末尾のチェックサムは計算し直し
  checksum = calculate_checksum line
  hex += (line + checksum + "\r\n")
end

# 最後に書き出して完了
File.open("new_intelhex_file.hex", "w") do |f|
  f.puts bin
end

端折ったのでこのソースのままでは動作しませんが、やりことはなんとなくわかるかなと思います。 IntelHexのデータ部分だけ抽出したあとに、置換処理を実行し、元のIntelHex形式に戻しているだけです。

固定長のデータの置換であることが前提ですが、これでIntelHex形式のファイルすら置換できました。

まとめ

日夜自分が書いた置換ツールが工場で動き続けていると思うと (;´Д`)ハァハァ しちゃうなぁという感じです。 日本でこんなにバイナリの置換行為をしている(させている)のは自分だけなんじゃないかと思ったりもしますが、上には上がいると思うのでその辺はコメントをお待ちしております。


Akerunをつくっている株式会社フォトシンスでは、APIやWeb管理画面を良くしてくれる、Railsエンジニアを募集しています! www.wantedly.com

Akerun Developersサイトもやってます。Akerun APIについては、こちらをご覧ください。 photosynth-inc.github.io

Akerun Proのご購入はこちらからどうぞ! akerun.com

AkerunPro x さくらIoTが最高にかっこよかった \( IoT )/

こんにちは。 す〜 ( @ksksue ) です。 Akerun Advent Calendar 19 日目の記事です。

これまで、ざっくりこんな感じで書き進めてきました。

  1. さくらIoTさわってみる
  2. nRF52 BLEとつなげてみる
  3. Akerun Pro 遠隔で開けてみる ← イマココ

今回はAkerunProにさくらIoTをI2Cで繋いで遠隔開閉をしてみたいと思います。

さくらIoTをAkerun Proにくっつける

ということで、できました

\( IoT )/

f:id:photosynth-inc:20161219211349p:plain

\( IoT)/

f:id:photosynth-inc:20161219211651p:plain

\( i□t )/

f:id:photosynth-inc:20161219211819p:plain

か、かっこいいです///

仮面◯イダー スーパー1 的なかっこよさがあります。

そして、緑の基板がかっぱの頭のようでとってもかわいいです

(女子社員に見せたらおもわず「かわいい」ともらしていました)

さくらIoT経由でAkerun Proをあける

あけました しめました


Akerun Pro with Sakura IoT Platform beta module

反応がはやいところもかっこいいです。

コマンドを叩くとクラウド経由でも1〜2秒ほどで鍵が開いてしまいます。

 $ ./akerun_close

※ 上記コマンド中身は前回記事pythonコード参照

ということで、とってもカンタンにAkerun ProをLTE化できました。

まとめ

最後は駆け足でしたがボクがやりたかったことができたので満足です。

さくらIoTをさわってみての感想は

  • さくっとIoT化できるからおもしろい
  • 低消費電力化は今のところ厳しそう(いくつかあるローパワーの仕組みが未サポート。今後に期待)

ということでホビーユースではいろいろ遊べるいいツールです。

全3回にわたりご拝読ありがとうございました。

別の機会に、今度はFPGA x LTEとかわりとロマンなのでそのあたり妄想中です。

それでは。

※ 本記事の写真は開発機Akerunです。製品版ではこのような改造はできません。

参考

nRF52 I2C Driver for Sakura IoT Platform beta https://github.com/ksksue/sakura_iot_beta_nrf52_i2c

告知

2016年12月中にブログ経由で申込みしていただいた方限定でキャンペーン実施中。 詳しくは資料請求からお問い合わせください! akerun.com

Akerunをつくっている株式会社フォトシンスではRailsエンジニアを募集しています! www.wantedly.com

Akerun Developersサイトもやってます。Akerun APIについては、こちらをご覧ください。 photosynth-inc.github.io

IoTデバイスのアップデート管理 / Akeurn Advent Calendar 18日目

qiita.com

この記事はAkerun Advent Calendar 18日目の記事です。 Akerun Remote開発担当 @KoheiAKitaが担当します。

一度リリースしたら組み込みのソフトウェアは更新できないは過去の話、ユーザー自身でCD-ROMを用いてソフトウェアアップデートを行ったり、OS自体が自動でアップデートを行ったりなど、ソフトウェアの更新を行い、最新のプログラムを提供するのが当たり前になっています。

IoTデバイスもネットワーク機能を有している端末が多く、搭載しているソフトウェアを常に最新にアップデートを行いたいと思うことでしょう。もしくは、不具合を見つけてしまい、不具合修正版を配信したいという場面もあるでしょう。

弊社で採用している手法、パッケージ管理のtipsについて紹介したいと思います。

1. IoT アップデートシステム

弊社でのソフトウェアアップデートは、端末自身が行う自発的アップデート方式でなく、命令して初めて実行するアップデート方式です。 端末管理者がアップデート操作 → MQTTサーバー → Akerun Remote という流れでアップデート指示を出すことで、端末一つ一つにアップデートを行います。なぜ命令によるアップデート方式を採用したかについては、

  1. バイスの使用状況に応じ、きめ細かい対応が必要である。
    (自発的アップデートの場合は、状況ごとの処理わけをあらかじめ組み込んでおかなければならない)
  2. エラー発生時に人間の判断で様々な対応ができる
    (自発的アップデートの場合は、ありとあらゆるエラー時の処理を組み込んでおく必要がある)
  3. 端末でのアップデート処理をシンプルにできる
    (自発的アップデートは処理が膨大、テストが複雑に)

という大きな3つの理由からです。 そして、IoTデバイス側に、MQTTメッセージを用いてサーバーへ端末状況をPublish(発行)するようにしておけば、MQTTサーバー側でそのメッセージをSubscribe(購読)するようにし、細かい処理を組むというポリシーにすることで、柔軟な変更が可能になるメリットがあります。アップデート時の処理に変更がある場合でも、IoTデバイス側に影響なく変更が可能になる部分が多くなります。

2. パッケージ作成

次にアップデートするファイルは、Debianなら.debファイル、RedHat系なら.rpmとご使用のOSによって異なります。 ただ、IoTデバイスではDebian系のOSの割合は非常に高いのではないでしょうか。ここでは弊社でも採用している.debファイルを扱うことを前提としてお話していきます。

Debianでのアップデートファイル作成は、Debianが定めているディレクトリ構成、必要ファイルを用意します。どのようなファイルが必要か、どのようにディレクトリ構成すべきかは、公式サイトに詳しく説明されています。
参考:(Debian公式サイト)第4章 debian/ ディレクトリー以下に無くてはならないファイル

こちらでも非常に詳しく説明されています。
Debianパッケージの作り方と公開方法: groongaを例にして - ククログ(2010-01-18)

その後、自身のアプリケーションなどをビルドディレクトリ配下に置き、debuildコマンドを実行すると、パッケージのビルドの後自動的にLintianコマンドにより静的チェックを行い、エラーが発生しなければ晴れて.debファイルが作成されます。
参考:(Debian公式サイト)第6章 パッケージのビルド

このファイルが、apt-getから取得でき、インストール可能なファイルとなります。

3. パッケージ管理

さて、アップデートパッケージができたところで、このファイルの管理が必要です。 パッケージ管理は、弊社ではaptlyを使用して行っています。

aptlyはサーバーへのアップロードはもちろんのこと、コマンド実行だけでリポジトリの作成、ミラーの作成、スナップショット、マージ、リリース、バージョン管理を一元管理できるので便利です。 aptlyのできることを公式ページにて図解しています。
https://www.aptly.info/img/schema.png

一般的な手順としては以下のようになります。

  1. aptly repo create -distribution=[ディストリビューション名] -component=[コンポーネント名] [リポジトリ名]
    ローカル環境に、指定した名前でのリポジトリを作成します。

  2. aptly repo add [リポジトリ名] [.debファイル]
    1.で作成したローカルリポジトリに、作成したアップデートパッケージ.debファイルを指定し、登録します。

  3. aptly snapshot create [スナップショット名] from repo [リポジトリ名] 指定したリポジトリにある最後のデータのスナップショット(コピー)を作成します。

  4. aptly publish snapshot [スナップショット名] [サーバー名]
    3.で作成したスナップショットを、サーバーに初回アップロードし、リポジトリを作成します。 ここでいう"初回"とは、サーバーにリポジトリがまだない状態のことです。[サーバー名]でより詳しい指定をすることで、リポジトリ構成をしています。

例として、Amazon S3にアップロードし、debianのフォルダをトップディレクトリに作成、その配下にリポジトリを展開する場合は: s3:[URLアドレス]:debian となります。そうすると、以下のようなディレクトリ構成が自動で作成されます。

[URLアドレス] - debian - dists - [ディストリビューション名] - [コンポーネント名] - binary-XXX
                     ∟ pool - [コンポーネント名] - t - [ディストリビューション名]

"binary-XXX"はアーキテクチャ名によって変化します。Intel CPU環境であればi386amd CPU環境であればamd64など。

dists配下が最新のアップデートパッケージとして配信されるデータフォルダ、pool配下が最新バージョンを含む履歴データのフォルダです。 apt-get install [パッケージ名]=[バージョン]として指定した場合に取得できるデータですね。

2回目以降にアップロードする場合、"publish snapshot"ではなく、"publish switch"に変化しますのでご注意ください。

aptly tips

ここで、aptlyでのtips、、、というほどではないですが、google先生に伺い立てても公式ページ以外はあまりいい内容は出てこなかった、一度登録したデータの削除方法についてご紹介します。 登録データはaptlyシステム内で依存性があり

publish済み >> snapshot作成済み >> データベースに登録のみ

の順で実施するコマンドが増えます。

  1. aptly publish drop [ディストリビューション名] [サーバー名]
    publish済みはここから実行します。いろいろ試しましたが、サーバーのデータを削除するのには、一度リモートリポジトリを削除するしかないようです(もし、リモートのパッケージのみ削除する方法があれば是非お知らせください。)

  2. aptly snapshot drop [スナップショット名]
    snapshot作成ずみの場合はここから実行します。

  3. aptly repo remove [ディストリビューション名] [パッケージ名]
    データベース作成済みの場合はこちらからです。パッケージ名の指定が少し異なり、追加するときは「package_v1.2.0.deb」のように拡張子付きで指定しましたが、削除時は「package_v1.2.0」と、拡張子無しで指定しないといけないようです。この点が分からずにハマっていました。

  4. aptly repo drop [リポジトリ名]
    最後に、リポジトリの削除です。必要なくなった場合はこちらのコマンドでローカルリポジトリを削除できます。

まとめ

ざっくりとした説明でしたが、IoTデバイスでのアップデート管理は、
* アップデート実行方法
* パッケージ管理
の方法が重要で、特に、「アップデート方法」についてのシステムは、システム運用する方法、顧客の状況などを鑑みて設計する必要があり、一番肝となる部分です。 この点を注意し、常に最新のソフトウェアで動作し、安定した運用ができるアップデートシステムを構築していくことになるかと思います。

Akerunをつくっている株式会社フォトシンスでは、Railsエンジニアを募集しています! www.wantedly.com

Akerun Developersサイトもやってます。Akerun APIについては、こちらをご覧ください。 photosynth-inc.github.io