[24日目] NAT Traversalって知ってますか

Cerevoアドベントカレンダー2016、最終日です。といっても、どうやら大トリは弊社代表が年末までに昨年のネタの更新版を出すようなので、私はトリらしい何かとかでもなく、テックブログらしく技術ネタを書きたいと思います。
まつけんです。CTOをしています。今日はハードはほぼ関係ない、ソフトというかUDP/IP、TCP/IPな世界の話です。IPレイヤーより上でのお話です。

まず、NATと言われて動作を想像できる方どれくらいいるでしょうか。今や、ルータという名でNATが動作する機器は各家庭にほぼ設置されているのではないかと思いますし、携帯向けネットワークも昨今はLarge Scale NATもしくはCarrier Grade NATの導入という形でちょっと話題になったようにNATが導入されています。そんな世界では、グローバルIPが直接振られるのではなく、ルータやキャリア側でローカルIPからグローバルIPへのアドレス変換が行われるのが一般的です。NATと言いますが、今挙げた例は、正確に言えば、IP masquarade(マスカレード)です。NATはNetwork address translationなのでアドレス変換をするというもう少し広い意味で、グローバルIPとローカルIPが1:1で変換されるようなケースも包含されますし、サブネットを分けたローカルネットワークでの1:1や1:Nでの変換などにも利用されることもあります。

今回は、最も一般的な多:1でローカルIPからグローバルIPへとソースアドレスを書き換えて通信を行う(グローバルIPアドレスを共有する典型例)、ほぼどんな環境でも導入されていると言っても過言でなくなった、いわゆるIPマスカレードされている環境でのP2Pでの通信を実現する、NAT Traversalのお話です。

NAT Traversalとは

まず、NAT Traversal、日本語で言うと、NAT越え(NAT超えかもしれません。ここでは越えで統一します。)はなぜ必要なのか。IPv4アドレスが世に溢れ、すべてのデバイスにグローバルIPが割り当てられている状態であればそもそもNAT越えは必要ないわけですが、現実にはIPv4アドレスは足りないし、ルータ下にいない直接グローバルIPをデバイスがもつというのはセキュリティ的にも推奨されない(デバイス自身がbindしているポートへの通信をローカルネットワーク内のパケットに限定でき、脅威となるデバイスやサーバが容易に直接のアクセスがしづらい)のが現実です。そんなNATがあふれる世界でもP2P通信をしたい、という需要を満たすためにNAT Traversalという技術(というか、手法でしょうか)が考えだされるわけです。これはもうかなり昔からあるもので、様々な資料がネット上にもありますが、一度、自分の整理のためにこの記事を書いてみている次第です。

ルータの下にいるデバイス同士が直接するのはなぜそんなに難しいのでしょうか。まず簡単な通信の流れを下記図を見ながら説明します。もっとも一般的な構成として、ルータ下のネットワークをローカルネットワーク、ルータの外に存在するネットワークをグローバルネットワークとして考えます。そのときに、ルータ下のデバイスがグローバルネットワークと通信とパケットをルータの外のネットワークにあるアドレスに送ります。そのローカルネットワークの内からNATを通して外へという形で出て行く分にはルータがアドレス変換をよしなに行います。これがIPマスカレードです。やることはそんなに難しくなく、TCPの場合、ソースになったIPアドレスとポート(つまり、デバイスのIPとポート)と、宛先になるIPアドレスとポート、ソースアドレス書換後のルータ自身のグローバルネットワーク側のアドレスとポートを、最初にデバイスからパケットが来た時に組み合わせで覚えます。その上で、ソースアドレスをNATが動作しているルータ自身のIPとポートに書き換え、宛先にパケットを投げる、宛先からパケットが返ってくれば覚えてるマップにしたがって、その返信パケットの宛先をローカルネットワークにいる通信元のデバイスに書き換えてパケットを送信します。こうすることで、デバイスはソースアドレス変換が行われたことを知ることなく、外のインターネットな世界と通信ができるわけです。

oneNAT
ここでNAT越えの話に戻ります。でも、宛先はあくまでグローバルIPでなければ(ルータを通してNATを通じて書き換えが行われなければ)、ルータは宛先を書き換える機能を発揮できません(通信双方のアドレスやポートを覚えて変換と転送ができません)。では、相手もNAT下にいる場合、そのローカルアドレスを指定するわけにもいきませんし(ローカルネットワークのアドレスなわけで別ネットワークにいるので届くわけはありません)、グローバルIPはルータがもっているわけなので、ルータ下に居るデバイスと通信するというのは極めて困難なわけです。

NATを越えてデバイス同士が直接通信するには

これの安直な解決方法のひとつがサーバーリレーです。要はデバイス同士が同じサーバに接続をして(この場合、サーバがグローバルIPを持っているのでどちらもルータ下のローカルネットワークから容易に接続ができる)その後の通信はサーバが介在して両者で通信を行います。ただ、この方式、TCPレベルで解決するには宛先を別途アプリレイヤーで指定する必要がありますし、なによりも、トラフィックがすべてサーバを経由するので、サーバの通信量が2倍、そして、サーバを経由するため経路としてはあきらかに冗長に長くなりレイテンシが悪化します。これは、P2Pでの典型的な例である、ビデオチャットやゲーム対戦の特性に対してあまりマッチしません。

ここまで前提を並べてきて、やっと本題にたどり着きました。それぞれのデバイスがルータの下にいたとしても直接パケットをどうにかして届かせたいという必要性が出てきます、それがNAT越えです。ここからはNAT越えを単純な手法から順に説明していきましょう。まずは極めて単純なUDP hole punchingです。これはあとから紹介しますが、特定の動作をするNATでしか通用しません。ここから、NATの種別ごとにどういう形で対応を増やしていくか、というのがこのNAT越えの議論のおもしろいところです。

fullconeNAT
UDP hole punchingは上記の図の通り、cone NATが対象である限り、NATのグローバル側のIPとポートさえわかれば、そして、それをサーバで観測すれば、その後はサーバからIPとポートをそれぞれが教えてもらい、そこに対して、UDPパケットを投げ込めば到達できるわけです。
ここで、唐突にでてきたcone NATを含め、NATの動作によって分類をまず行いましょう。

  • full cone NAT
  • address restricted cone NAT
  • port restricted cone NAT
  • sequential port smmetric NAT
  • random port symmetric NAT

というふうに考えると、NAT越えの方法と特性が分類されます。まずはconeとsymmetricの差を考えてみましょう。

cone NATはシンプルな動作です。ルータ下のデバイスがグローバルアドレスに対して通信を開始し、パケットを送信したとき、ルータはソースになるIPとポートを覚えるのみです。それにしたがって、ルータのグローバル側のIPとポートをマップします。つまり、グローバル側のIPとポートに対して、グローバル側にいるデバイスであれば誰でもパケットを送信し、それはルータ下のデバイスにパケットはアドレスを書き換え転送されます。したがって、下記のような流れを経れば、UDPによるP2P通信が可能になるわけです。

  • ローカルネットワークAに存在するデバイスをαとし、ローカルネットワークBにいるデバイスをβとします。αとβが互いにUDPパケットを直接送受信できるのが最終目標です。
  • αとβを仲介するサーバをSとします。まず、P2P通信を開始したいという意思をαとβで共有します。そして、通信を開始するぞとなるタイミングをSから受け取ります。
  • すると、αとβはまず、サーバSに対して、UDPパケットを送信します。すると、パケットはαとβそれぞれのNATされたグローバルのIPとポートを観測することができます(ソースアドレスはNATされたルータのものが見えます)
  • それをαの情報はβへ、βの情報はαへと、サーバから通知を行います。(たとえば、P2P通信開始処理の間は、サーバとの間にTCPがはられていてここでやりとりするとかです。)
  • αはβのルータのグローバルのIPとポートに対して、UDPパケットを投げます。βも同様です。
  • cone NATであるため、ソースアドレスやポートに制限はありませんから、それぞれのUDPパケットは無事、それぞれのデバイスに届くことになります。

さて、cone NATの場合、こういったサーバが介在してアドレスとポートを伝えるという処理はあるものの、まだまだ単純な処理で終わります。次はaddress restricted cone NATとport restricted cone NATを攻略していきましょう。

address restricted cone NAT, port restricted cone NATはそれぞれfull cone NATに比べて制限が増えます。マッピングするときに、ソースのIP、ポート以外に、宛先のアドレスを覚えるのがaddress restricted cone NAT、ポート番号までも覚えるのがport restricted cone NATです。それぞれ攻略をしていきましょう。

address restricted cone NATは割りと簡単です。要は送った宛先のIPからのパケットでないと受け取りません。でも、サーバに送ってしまえば宛先はサーバになるわけでサーバからのパケットしか受けないことになります。では、αからβに送ったパケットはどうしてもNATに阻まれるはずです。でも、ここでcone NATのもう一つの特徴が際立ってきます。
cone NATの定義のひとつに、NATの外側のポートはソースアドレスになるデバイスのポートに従います。すなわち、αがport 30000をbindしてパケットを送ったとしたら、基本的には、NATもport 30000を利用するのがcone NATです。ここからが実際のNAT越えの方法をまた流れに沿って説明しましょう。

α、βそれぞれがサーバに向かってUDPパケットを投げ、サーバはそのIPアドレスとポートを観測します。そして、それをαとβに伝える。
すると、βはαのIPアドレスとポートに対して、UDPパケットを投げます。ここで重要なのは、βはbindするポートをサーバにUDPパケットを送ったときと同じポートを使います。このとき、NATはfull cone NATであれば通りますが、address restricted portやport restricted portでは、サーバとIPアドレスもポートも違う訳ですから通りません。が、β側のNATにはαのIPアドレスとポートへのパケットが記録され、βのIPアドレスとポートは維持されるわけです。ここで、αがβのIPドレスとポートに対してパケットを投げたとします、そうすると、βはさきほどのパケットはNATに阻まれたとはいえ、NATのマッピングができあがっているため、αからのパケットはβに到達します。また、このパケットでも、αはサーバへのUDPパケットを送ったポートをbindしていればNATには同様のマッピングがβのIPアドレスとポートに対してできあがるわけです。これで、αとβはそれぞれのNATを越えて通信ができるようになりました。

ここまで、cone NATの場合のNAT越えを説明してきました。実はこれはすでによくある方式として、STUNという形で標準化されています。実際はユーザ認証なども含みますが、P2Pの経路開通を行う方式はまさにいままでの説明通りです。いくつかのアプリケーションではSTUNが実装されているので参考にしてみてください。

ここからが、難しく解決できない問題に対して考えて行く形になります。
Symmetric NATです。これはcone NATと違い、ポート番号が再利用されません。つまり、ソースとなるデバイスでポートを固定したとしても宛先によって、別ポートが割り当てられることになります。そのため、サーバで観測したとしても、そのポートを再利用する方法がないのです。

さて、この場合、どういった方法でSymmetric NATを攻略するかを考えます。Symmetricの何がツライかというと、NATの外側のポートを観測してもそれを利用できないことです。いや、それは本当でしょうか。観測できることではなく、NATでどのポートが利用されるかと言い換えられるわけで、つまるところ、NATのポートは当たるなら予測でも良いわけです。では、予測可能か、が重要になります。Symmetric NATと言われるのもを更に分類しましょう。といっても、NATの内(ソースとなるデバイスのポートは固定)から外への通信が起こった際に、ポートがシーケンシャルに変化するか、ランダムに変化するか、です。

つまるところ、方法としては、例えばこうです。ソースとなるデバイスからサーバに対して、複数のパケットを打ちます。その際、bindするポートを固定します。そして、サーバの受けるポートはパケット数分変化させます。ここでは3発のパケットをサーバに対して投げてみます。そして、サーバからポートを観測します。このとき、ポートがどう変化するかです。例えば、+1されていく、+2されていく、-3されていく、ランダムに変化する、様々なパターンが見えるはずです。ランダムに変化する場合を除いて、NATの特性を予測するわけです。+1される場合はどうするか、もう分かりますね。NAT下のデバイスが1つしかなく、ほかの通信がないと仮定すれば、αからβへの通信を同じポートをbindした上でパケットを投げます。サーバで観測されたポート番号+1されたβはパケットを投げ込みます。そうすることで、NATのグローバル側のポートは予測され、そこにパケットを投げ込めば、おそらくは疎通するはずです。

ここからが考えどころです。実際にはNAT下のデバイスは複数あって他のUDPパケットが送られてポート番号はずれるかもしれません。もしくは、同じbindしたポートから通信しても、宛先のアドレスが違えば外側のポートが変わるかもしれません。前者はリトライでカバーするか、複数のポートをつかってα、βから送ってどれかが疎通したらその後はそれを使うかなどいくつかの方法が考えられますね。宛先のアドレスが違えば届かないことを考えると、サーバも複数のIPアドレスを持ち、それぞれに対しておくったときのポート変化も観測する必要があります。このあたりから観測の方法がどんどんと複雑化していくため、これに対して、どう対処していくかがNAT越えの最大の難所です。いままで、cone NAT, SymmetricNATという類型で説明してきましたが、昨今、この類型に意味がないと言われる所以がこのあたりから始まります。(とはいえ、NAT Traversalという技術を理解するにはこの類型も私は有用だと思っています。)

とはいえ、越えられないひとつに、ランダムにポートが割り当てられるSymmetric NATは対処のしようがなさそうです。この場合のみサーバーリレーを行うというのが疎通する確率を100%にする一つの方法です。そうではなく、ランダムにポートを開けるNATに対するポート予測方法をなんらか確立できる手法もあるかもしれません。もし、すでに公知だよという場合はぜひ情報へのポインタを教えてください。

ここまでで、UDP hole punchingのなんとなくの基本を学んできました。cone NATへの対処はSTUNの仕様、規格を読んでみてください。たぶん、この文章よりはよっぽど分かりやすいです、ここまで読んでいただく方にそう言うのもアレですが。また、実際、Symmetric NATの場合の方法としては、 https://tools.ietf.org/html/draft-takeda-symmetric-nat-traversal-00 を読むのがおそらく一番詳しく丁寧です。そういった意味でも、ここでの解説は初歩の初歩です、じゃあどう実装するんだというのから、サーバで何を観測するのか、そもそもNATが複数段あったらこの手法は果たして通用するのか。観測を複雑にしていけばいくほど、開通までの時間がかかります、それは本当にターゲットのアプリケーションにとって許容できるのか。Large Scale NATではこの穴開けが通用するのか、キープアライブはどうするか、セキュリティ的に必要な相手のパケットだけを見分けられるのか、認証はどうするか等、現実世界では、この抜け穴のような手法に対しての課題は山盛りです。そんなところの実地調査として、UDP hole punching自体はあまり表に見えない手法ではありますが意外なところで結構導入されていたりしますので、とあるゲーム機なんかで、P2Pで対戦通信しているな?とおもったときに、パケットキャプチャしてみるのもオススメです。

さて、最後に、いままでは、UDP hole punchingをベースに説明をしてきましたが、ではTCPの場合はどうなるでしょうか。まず、TCPにはcone NATという概念はまずあり得ません。それは、宛先との通信はステートをもって(つまりシーケンス番号を使って)通信されるため、宛先を限定しないポートマッピングというのはほぼ意味がありませんし、ほかのパケットを転送するというのはただのセキュリティホールです。なので、通常は、上記類型で言えば、Symmetric NATしか存在しません。また、さらに面倒くさいところが、TCPの通信シーケンスの始め方です。接続元はSYNパケットを送り、接続先はSYN、ACKをセットにして送ります、そして、接続元からACKが送られて、はじめてTCPでの通信は始まります。つまり、UDP hole punchingのように最初の一発のパケットはなかったことにするわけにはいきません。あくまで、SYNパケットは両者に届かないわけにはいかないのです。この通信開始の流れを3-handshakeと呼びます。

でも、それでもTCPでNATを越たい、という人にはヒントはあります。まず、TCPでの仕様では、3-handshakeだけでなく、4-handshakeでも問題なく通信は開始できます。つまり、αからSYN、βからもSYN、その後、双方からACKが送信されるようなケースです。ここから見えてくるのは、要はSYNをUDP hole punchingの最初のパケットとしてつかって複数送ったとしてもひとつだけ届けば通信は確立されるということです。これは、どこかで少し話題になりましたが、TCPの仕様に実際、TCP Simultaneous Openという名前で記載があります。ここまでくればあとの考えは分かりますね。これで、Symmetric NATと同じ手法でNAT越えはおそらく可能になります(これは私は実際に実装したことはないので、たぶん)

さて、というわけで……。ざっと、通常言われるNAT Traversalの手法の入り口を紹介してきました。STUN以上のもので簡単な実装を見られるものはいくつかあります。また、Symmetric NATへの対処の実装も、いくつかGitHubを漁ればでてきます。 https://github.com/zerotier/ZeroTierOne など。

とはいえ、NATの越方は様々、この上でどういう通信をするかも様々です。UDPでしか通信できない経路ではアプリケーションでは使い勝手が悪い場合もあります。そういう場合には、TCP over UDPを実装してあげてVPN的に使うのもよいかもしれません(OpenVPNが使っているようなTUN/TAPデバイスという仮想トンネルデバイスはLinuxではよく使われますね)また、NATに関わらず通信するためのサーバリレーの方法としてはメジャーなのがTURNを使った実装でしょうか。越えられなかったらTURNをつかってサーバリレーをするというところまでフローを実装するとより使いやすくなります。また、今回は出てきませんでしたが、ルータに実装されているUPnP実装では静的なポートマッピングが可能なものが多く存在します。UDP hole punchingとは別の方法で、NATの外→内の通信を可能にできる方法なので、こちらも組み合わせるとより多くのNATに対応できるはずです。でも、この場合も複数段NATがある場合はじゃあどうする、みたいなことがなかなかに難しいポイントです。まずは、ローカルネットワークとグローバルネットワークを見分けるような方法を実装しなければなりません。方法はいくつかありそうですが、ICMPでTTLを変化させて使うとできそうな気もします。要はtracerouteですね。

昨今、IPv6も徐々に普及し始め、NAT Traversalは不要になるかと思っていましたが、NATはIPマスカレードではなく、1:1のアドレス変換として生き残る雰囲気も少しだけ感じます。そんな中で、意外にNAT Traversalは必要とされる技術なのかもしれません。WebRTCは特性上、P2P通信ができれば好ましく、NAT TraversalもSTUNなどを使って行われるケースもあるようです、同時にTURNも使われる例の最たるものとしても。

今後どうなっていくか

さて、最後に、将来はというところを少し。これまでは、UDP/TCPの話をしてきました、それ以外もあります。SCTPが一番最有力なのではないかと思います。現状、メジャーではないものの、すでに実装はLinuxではしっかり入っていますし、途中経路のルータさえしっかり対応すれば(これが一番大変なんですが)、様々な課題を解決しています。ここから、SCTPを解説しはじめると、この記事はいつになっても終わらない形になってしまいますので、NAT Traversalにまつわるアレコレはここまでで一度締めさせていただきます。年末年始の空いた時間でSCTPを調べていただくときっと楽しいのではと思ったりしています。

最後に

この記事が果たしてアドベントカレンダーの最後に相応しかったかどうかはよくわかりませんが、NAT Traversalという古くからあるけれどマイナーな、でも、結構有用だと思っている技術の導入となる方がいたりすると幸いです。
途中から図がなくなったのは気力が間に合わなかったので、後で追加できたらしたいなと思っています。

[23日目] メカ設計の経験がゼロでも筐体の製造原価を見積もる方法。プラスチック編

~スマホケースでメカ設計・原価計算の基礎をちょっとだけ学ぶ~

こんにちは。
株式会社Cerevoの柴田と申します。以前は某社炊飯器・掃除機の筐体・機構設計に携わっていました。
現在デザインエンジニアとしてスマート・ビンディング「XON SNOW-1」のメカ設計を担当したり、最近ではニッポン放送、グッドスマイルカンパニーとのコラボレーション企画、BLEラジオ「Hint」プロジェクトにて、プロダクトマネージャーを兼任しています。

プロダクトマネージャー(PM)として仕事する機会が増えてきて、仕様が固まる前に製品の見積もりを作ることが度々あります。仕様が固まる前なので、当然のことながらそれぞれの部品は設計前です。経験があれば、「これくらいの製品は、まあこんなもんだろう!」と決めることもできるかとおもいますが、最初の見積もりで製造原価を安くしてしまうと量産するときに製造原価を割ってしまい、利益が出ない製品となってしまうかもしれません。

PMとして、それは絶対に避けるべきであり、ある程度現実的で根拠のある製造原価を概算でもいいから、知る必要性があります。

なにもわからないと設計前の部品をどうやって見積って製造原価をイメージすればいいのか?と悩んでしまうでしょう。
今回は特にプラスチックのメカ部品を設計する前に、どうやって製造原価を見積っているか、スマホケースを例にお話ししたいと思います。メカ設計の経験がないけど、ハードウェアのPMやってみたい!という方は参考にしてみてください。

内容としては、樹脂を使ったメカ設計・原価計算の基礎的なことを掻い摘んで解説したもので、計算結果も概算となります。製造業で同業の人にとっては釈迦に説法となる面も多いですが、あしからず。

 

スマホケースでみる製造原価の見積もり方

①材料の選定、見積もりのための材料の価格決定

まず見積もりを考えるにあたり材料の選定をします。ここについてはズバリ、「黙ってABS」です。ABSとはアクリロニトリル-ブタジエン-スチレンという樹脂の頭文字をとって付けられた名前です。
世の中にあるプラスチック製品、特に身の回りの家電は、かなりこの樹脂が使われています。ちなみに、お掃除ロボット「ルンバ」にも使われています。Amazonの商品説明にも記載されています。
他にもPP(ポリプロピレン)とかPC(ポリカーボネート)とかあるのですが、それはまた別の機会に。

次に、材料の価格です。樹脂はペレットという顆粒の状態で購入するのですが、業者でもないのにわかるわけない……と投げ出してはいけません。
そんなときは、オフィス用品/現場用品のASKUL(アスクル)です。意外かもしれませんがアスクルで樹脂ペレットが売っています。

アスクルで「ABS ペレット」と検索すると実験用の樹脂ペレットがヒットします。製造現場で樹脂のペレットは25kgごと(=1袋)の単位で購入するのが一般的です。アスクルも25kgで購入することができます。
アスクルの価格を使うと1kgあたり約800円となります。正直この数字はちょっと高めです。実際は1kgあたり300~500円くらいですが、今回は800円で進めます。

②スマホケースの重さを求める

プラスチック部品の製造原価を知るために重さは一番重要です。すでに部品のデータが出来ていて3Dプリンターで出力しているのであれば、その重さを測定します。
デザインが出来ていてデータもあるけど3Dプリンターで出力していないという場合は、3D-CAD(モデリングソフト)を使って体積を求めましょう。色々なCADがありますが、測定ツールの中に体積を測定するコマンドがあって、何回かのクリックだけで、体積を測定することができます。体積がわかったらABSの密度を掛け算して、算出することができます。

今回はあくまでもCADを使わずに見積もります。

Photo_16-12-11-03-28-17.004

まず、スマホケースなのでスマホの大きさを測定します。写真のスマホはだいたい縦15cm、横7cmです。これに厚さを決めて体積を求め、密度を掛けて重さを計算します。(スマホの上下・両サイドを覆う箇所は、ややこしくなるため割愛します。)
厚さ、一体どれくらいにすればいいか悩んでしまうかもしれませんが、ここもノウハウ「とりあえず2mm」です。プラスチック部品はどれも1mmから3mmくらいの肉厚です。手近にプラスチック製のコップがあれば見てほしいです。なんとなく1~3mmくらいです。細かい話はあるのですが、それくらいの厚さじゃないと作れないと思っていいです。スマホケースに限らず、樹脂の肉厚でどうすればいいか決まっていないときは、なにも考えずに2mm(0.2cm)と仮定しましょう。

体積=縦 15cm x 横 7cm x 肉厚 0.2cm =21cm³
となります。

これに、密度を掛け算すれば重さがでます。ABSの密度をさっそくググって……もいいですが、覚えておいて損はない(はず?の)うんちくがあります。おおよそ「プラの密度は1(g/cm³)」です。
単位は[グラム パー 立方センチメートル]です。物性によって前後しますが、おおよそ1と考えていいです。プラスチックは1辺1cmの立方体だと約1gということになります。正確な数値は各材料メーカーによって異なりますので、ご確認ください。

重さ=21cm³ x 1 g/cm³ = 21g

よって、重さは21gとなります。

③1個あたりの作業時間と④作業者の人件費

製造原価を決める上で、重さに次いで重要なのが作業時間です。作業時間が長ければ長いほど製造原価が上昇してしまいます。
実際に工場に行ったこと無いし、プラスチック部品がどうやって作られているなんて……と嘆く前に「YouTubeで動画を検索」しましょう。”射出成形 動画”で検索してください。工場に行ったことが無くてもどんな感じか、なんとなくわかります。動画から作業時間を仮定します。注目してほしい動画は時間が短い4分未満の動画です。時間が長い動画は、射出成形(=プラスチック部品を作る工法の名前)の解説動画だったりするので、別途勉強したいときに観てください。
時間が短い動画で、淡々と射出成形の様子が撮影されているものがあるので、その動画の動作を注目してください。

工作機械の中にある金属の塊同士(=金型)が重なって数十秒止まった後に、金型が離れて中からプラスチック部品が出てきます。これが射出成形の動作であり、プラスチック部品が出来上がる1個あたりの作業時間です。
動画では、またすぐに同じものを量産し続けます。動画から1個あたりの作業時間を30秒と仮定します。

作業時間が決まったら、人件費です。YouTubeだとロボットアームが動いていたりしますが、今回はそこまで豪華な設備が無いことを仮定します。工作機械のオペレーターがいて、その人が金型からプラスチック部品を取り出す場合、時給を支払わなくてはいけません。
今回は時給1000円と決め打ち。1秒あたりの費用まで落とし込みます。

1時間あたり1,000円=1分あたり167円=1秒あたり2.8円

時給1,000円は1秒2.8円となります。

○製造原価算出

今までの数字を合算して製造原価を求めます。

①1gあたりのプラスチックの価格 1kgあたり800円。1gあたりだと0.8円
②スマホケースの重さ 21g
③作業時間 30秒
④人件費 1秒あたり2.8円

製造原価 = ①ABS 0.8円/g x ②重さ21g + ③作業時間 30秒 x ④人件費2.8円/秒
=100.2円

ざっくりですが、100.2円となります。この計算から、スマホケースの製造原価は100円くらいだとわかります。
また、① x ②を原価計算の用語で、直接材料費(略して直材費:Direct material cost)、③ x ④を直接労務費(直労費:direct labor cost)と呼んだりします。詳しくは原価計算の本で勉強してください。

今回の仮定はだいぶラフで、高めに算出されています。憶測ですが実際はもっと安いと思います。

◇主な製造原価の低減案

  • 安価な樹脂の選定:今回はアスクルで販売している実験用の樹脂で計算したため割高。
  • 軽量化:厚さを薄くすれば体積が減って安くなる。
  • 金型に同じ部品を複数配置し、複数取りにする。:2個取りにすれば1個を作る時間で2個作ることができる。
  • ロボットアームによる時短:人間よりも無駄な動きがない。作業効率アップ。
  • 人件費が安いところで製造:日本国内ではなく、アジア近隣諸国(中国など)で作る。

逆に、製造原価を上昇させる要素もあります。不良率(100個作った内、何個が不良か?)や工作機械のメンテナンスに使った油の費用(間接材料費)、管理費等などです。ただ、それを加味しても、この計算の数値から大きく外れることはないでしょう。ちなみに、私が持っているスマホケースはポリカーボネート製で14gでした。材質こそ違いますが、そんな感じでしょう。

○まとめ

・製造原価=1gあたりのプラスチックの価格 x 重さ(体積x密度)+作業時間(秒)+人件費

数式は自体は簡単なので、その数式のための仮定がどこまで現実的か、がポイントです。

  • 材料選定迷ったら「黙ってABS」で。
  • 詳細設計してなくても肉厚は「とりあえず2mm」にしよう。
  • 体積わかったら「プラの密度は1(g/cm³)」だから重さもわかる。

慣れてしまえば難しいことはありません。実際には、金型の取り数、成形機の型締力、部品点数や組立工賃など、様々な要素が追加されてメカ全体での製造原価が算出されます。
プラスチック部品の製造原価の算出について、全くピンとこないから不安だ……というときはちょっとでも参考にしていただけたらと思います。

自分があまり詳しくないことでプロジェクトがうまく進まないときは、特に腑に落ちないものです。でも、ちょっとでも知っていれば納得できることもあります。その知識やノウハウは、過去の経験や実績からくるものではなく、やる気を持って、逃げずに・真摯に物事を取り組む姿勢がきっかけとなって、体得できるのだなと、Cerevoで日々痛感しております。

ハードウェアのPMに興味はある、でも経験がないから……と尻込みしているなら、まずは弊社の採用面接を受けてみてはどうでしょうか?プロダクトマネージャー絶賛募集中です!!

 

[22日目] 出張先は展示会ではなく、城塞都市での大規模コスプレイベントだった

またひとつ、素敵な物語が最終回を迎えてしまいました、今一番行きたい場所はバルセロナ大聖堂、谷口です。
普段は調達業務を担当していますが、最近は、海外出張に行かせてもらう機会が増えてきました。先月頭イタリアで行われたイベントのレポートを書いてみたいと思います。

 

イタリアと言えば、ローマ、ミラノ、フィレンツェなど、美味しい食事に綺麗な風景が楽しめ、計画を練ってじっくり巡るもよし、ぶらり街歩きするもよしということで、旅行経験ある方も多いのかなと思います。
けれど、そのなかのルッカという城塞都市で行われる「Lucca comics & Games」というイベントをご存知でしょうか。
とりあえず城塞都市ってこの響き、やばいですよねわくわくしますよね。
ルッカはフィレンツェから北西に車で約1時間、電車でも1.5時間程の距離にある古き良き街並みを残した、普段はとても穏やかな田舎町です。ただし年に1度、このイベントの期間中は35万人(昨年期間合計)もの人が集まり、大通りはある時期の国際展示場並みに混雑します。
今回わたしはそのイベントのJAPAN TOWNと呼ばれるエリアで、ドミネーターの展示・販売をしてきました。日本のアニメグッズ企業さんや、和装小物や浅葱の羽織販売のお店などが集まるエリアです。

Lucca_03
茶色は建物、黄緑は芝生、黄色がブースの特設テントなイメージです。

ゲームやコミックや映画、ジャンルで大まかにエリアが分かれてはいますが、街中の広場や公園にテントを建てているので良くも悪くも点在しています。お目当てを巡りながらお腹が空いたらピザ食べて、ちょっと疲れたらジェラートで回復して、気ままに歩き回れる雰囲気、よかったです。

規模感で言えば世界最大級の集客数を誇る!割に、パリのJapan Expoや、欧米諸国でのコミコンに比べ、あまり日本では情報を見かけないように感じます。正直私も、今回の出張が決まるまでイベントの存在すら知りませんでした。
今回の日程は10/28~11/1の5日間、日ごとに入場券の購入が必要で、平日は€34~、日曜で一番賑わうだろう10/30は€80! にも関わらず、チケットはSold out。

お客さんの一人が、イタリアや近郊諸国ではとても有名なイベントで、この日の為にお金を貯めて年一の楽しみにして来るんだよと話してくれました。華やかなイメージと対照的に、失業率の話題がシビアなイタリアで、その規模を維持しているのは凄いなというか、多くの人に求められてる空間なんだろうなとも感じました。

改めてすごいなと思うのは、石畳に煉瓦の壁にゴシックな教会、中世を感じる街並みでした。雑多なくらいにジャンルが入り混じったコスプレでも、雰囲気があいまって全てにハクもたせてくれるのが、本当にすごい。

Lucca_01

アニメキャラも映画のヒロインも、リビングデッドな仮装も、カップルや友人同士やファミリーも。歩いてるだけ座ってるだけでも鮮やかで、単純に目が楽しかったです。

Lucca04
城壁といえばやっぱり思い出すのはこのアニメ、こう、なんというか、込み上げてくるものがあります……思わず右手胸にあてましたもん……、ショコラティエの前はズルかったなーーー

ある海賊一味が騒ぎながら通り抜けて行ったり、ある自宅警備員さんも海外派遣されていたり。ポーズをとってても自然な表情でも、どこでシャッターを押しても、無機質なものが写り込まないってことが、作品としての物語の背景にすらなってくれてるような存在感でした。

Lucca_02
青空の元、歴史的な建造物の乳白を背景に撮るもよし。並木がちょうど紅葉する時期、城壁の上の遊歩道で夕日をちょっと見下ろすアングルでコントラストつけて撮るもよし、異世界ファンタジーな格好もよし、中世スチームパンクな装いは馴染みすぎてとてもよし。
遊園地のハリボテではない普段は人が生活している空間なのに、こんなにも非日常な風景になるのが冷静になるととても不思議で、でも、半数と言ってもいい位沢山の人がコスプレしている事で説得力が出るのかなと思いました。

アニメ好きさんだけという訳ではなくハロウィンということも相まって、観光客やイタリアの人もお祭り気分で来るようです。おかげで、普段あまり見ていただく機会がなかなか少ない小学生や年配の方々にも触ってもらえました。ドミネーターは元々開発メンバーとして関わってきた製品でもあるので、「Figata!!」って驚く顔やリアクションと、笑顔を沢山見れて、好きや楽しいを共有できるの嬉しいなと素直に感じました。
また製品からアニメ原作に興味持ってくれた方も多かったので、これをきっかけに作品がまた盛り上がってくれるといいなと思いました。

現地では残念ながら写真をあまり撮れなかったので、絵日記風にしてみました。が!機会があったら、ぜひともカメラを持っておめかしして、不思議空間を楽しみに行ってみてください。

[21日目] LiveShell Xに装着できる「角度調整足 兼 microSDカードカバー」の作り方

はじめまして。デザインエンジニアの横田です。最近は、ライブ配信機器「LiveShell X」のデザインとメカを担当しました。そこで、せっかくなので今回のアドベントブログのテーマもLiveShell Xに関係するものにしてみました。

LiveShell Xに見られるネジ穴たち

LiveShell Xの筐体をよく見ると、今までのLiveShellシリーズの筐体と比べるとネジ穴の数が多い事がわかるかと思います。

これは、いままでのシリーズを使われているお客様の貴重なご意見も参考に、リグ、ラックをはじめ、いろいろな場所に取り付けられること等を想定した為です。最終的には「右側面、左側面にそれぞれM4ネジ穴を2つ(合計4つ)」「底面と側面に三脚用のネジ穴を1箇所ずつ(合計2つ)」を搭載することになりました。

そんなネジ穴たちですが、いろんな箇所への取り付けに使えるのはもちろんの事、工夫次第で色々使えそうな気がしてきますよね。そこで、今回は固定以外の使い方の一例として、録画中にうっかりSDカードがはずれないような「角度調整足 兼 microSDカードカバー」になるような部品をレーザーカッターで作ってみました。作り方を簡単に紹介してみたいと思います。

1. 外形図のpdfをダウンロード

LiveShell X公式サイトのSPECのページから、外形図のpdfをダウンロードすることができます。まずはそちらをダウンロードしましょう。

2. 部品のデータを書く

ダウンロードした外形図のpdfをイラストレーターで開き、ネジ穴の位置に合わせ「角度調整足 兼 microSDカードカバー」のデータを作成します。


↑外形図から側面のみを抜き出し、それに合わせて部品データを作成します。


↑レーザーカッターで切り出すために、部品だけのデータにしておきます。

3. レーザーカッターで切り出し

データができたら、アクリル板(厚さ2mm)をレーザーカッターで切り出します。


↑レーザーカッターで切り出し中。


↑切り出された部品。

4. 組み立て

完成した部品を、M4のローレット飾りねじで筐体に取り付けます。

5. 完成

完成状態は下記写真のとおりです。


↑アクリル板部品でmicroSDスロット部分を覆い、直接microSDカードを触れないようにしています。microSDカードが差さっているかどうかが確認出来るように、アクリル板は透明を使用しました。


↑同じ部品を反対側側面にも装着すると、角度調整足にもなります。通常状態から角度調整足状態にするには、ローレットねじを緩め部品を回転させ、くぼみに合わせてネジをとめればOKです。


↑卓上に置いた時に角度がつけられる。

最後に

今回は、LiveShell XのM4ねじ穴の、固定以外の使い方の参考として「角度調整足 兼 microSDカードカバー」の作り方を書いてみました。あくまで一例ですが、参考になれば幸いです。

[20日目] 基板を起こしてモータを動かそう

男の子ならいくつになっても動くオモチャって楽しいですよね。エンジンやモータが好物です。電気エンジニアのべーたです。

今回は簡単にモータを回して遊ぶ方法をご紹介します。
趣味で工作をされる方にはArduinoやmbedで動かしている人が多いので、それらとは違うアプローチで動かしてみます。
 

サーボモータを動かす

ラジコンサーボを動かしてみましょう。ラジコンや工作をする方にはおなじみのアクチュエータですね。こんなやつです。

DSC_0677

MG-90S (Tower Pro 社製)

制御回路やモータドライバ、ギアやポジションセンサがパッケージングされている便利なモータです。

電源と、たった1本の信号線を繋ぐだけで動作させられるので簡単に扱うことができます。サーボモータは目標角度の指令を入力すると出力軸が目標角度まで回転します。ミニ四駆に入っているようなブラシモータとは違って何回転も回すことはできませんが、ある角度の範囲内であれば大きな力で指令の向きまで出力軸の向きを変えてくれます。

どんな信号が必要か

一般的な小型のサーボでは電源電圧に4.8から6Vを与えます。位置指令はパルスの長さで与えます。このとき、パルスの長さが1.5ms(ミリ秒)で中央となり、そこから±0.5ms程度でそれぞれ両端まで動くサーボが多いようです。これについては様々な方が解説してくれているのでそちらへ譲ります(「サーボ 動かし方」などでググって下さい)。

ところで、サーボへ入力するパルスの電圧振幅はどれくらいが良いのでしょうか。一般的には、LレベルはGNDでHレベルはサーボに与えている電源電圧でしょう。

では、ちょっと真面目に考えてみます。サーボモータのトルクを目いっぱい使いたい時には6Vの電源を用意するでしょう。しかし6Vの信号を出力できるマイコンはそうそう無いはずです。逆にマイコンが5Vや3.3Vで動作している場合はサーボの電源も合わせて5Vや3.3Vを供給しなければならないでしょうか?

私が実際にサーボモータに6Vを供給し、マイコンから3.3Vのパルスをサーボに与えてみたところ、正常に動作することを確認しました。手元で1台動いたからと言っても100台で正しく動くでしょうか?1000台では……?設計者がもしもこのままサーボを量産で使ったとしたら歩留まりが気になって眠れなくなってしまいます。実際にはどれくらいの電圧の信号が許容されるのでしょうか?エビデンスを残しましょう。

その答えはサーボモータに内蔵されている制御回路を司るICのデータシートにありました。電気エンジニアにとっては非常にメジャーなICメーカに新日本無線という会社があります。このメーカがサーボに内蔵されている制御用ICを製造しているようです(互換品をルネサスや中国メーカも製造しています。電気的仕様もほぼ同じようです)。

では、NJM2611のデータシートを見てみましょう。注目すべきは「電気的特性」の表です。

電気的特性

NJM2611データシートより

「最小パルス電圧」という項目がありました。所謂「Hレベルの入力電圧VIH」と同様のパラメータでしょう。これによると「最小1.85V」とあります。言い換えると、Hレベルが1.85V以上のパルスを与えれば良いということになります。

これで3.3Vや5V振幅のパルスで問題ないというエビデンスが得られました。すっきりしましたね。(どうやら他メーカのサーボコントローラICも同様の入力特性であり、おおよそTTLレベルと考えて良さそうです)
 

マイコンを動かそう

さて、どのような信号を用意すれば良いのかがわかったので実際に信号を作っていきましょう。マイコンからはパルス幅が最小1ms, 最大2msのワンショットパルスを出力することにします。それをタイマ割り込みで20ms程度毎に出力すれば良いでしょう。こういう場合にトラディショナルなマイコンであれば、

タイマのレジスタを探す → ワンショット動作&ピン出力に設定 → コンペア値をセット

というような手順を踏むかと思います。最近の高級な開発環境であればタイマ周りの設定をするAPIが提供されていて、それを叩く方が多いでしょうか。そこで、今回はモータを回すのが目的なので、面倒な設定を考えずに済むPSoC5LPを使ってみます。PSoC5LPとは、ARM Cortex-M3コアとプログラマブルロジックを搭載したマイコンです。このプログラマブルロジックを使うにはGUIで線を繋いでいくだけできます。ペリフェラルを自由に構成することができるため、PWMをたくさん欲しい時に重宝します。他にどのような活用方法があるのかは拙著のプレゼン資料をご覧いただくか、ちょうど PSoC Advent Calendar 2016 が開催されています。こちらを眺めてみると良いでしょう。私が初めてPSoC5を使った時はマイコンのアーキテクチャを意識せずに扱えるのがとても新鮮だったことを覚えています。

今回はPSoC Creator にて提供されているPWMコンポーネントを使います。ツリーからPWMと出力ピン、クロックを持ってきてこのように繋ぎました。リセットを操作するためにControlRegを接続しました。

コンポーネントの配置と配線

コンポーネントの配置と配線

パルス幅の分解能を10us単位にすると扱いやすそうだったのでクロック入力は100kHzとしました。8bit幅なので0.01msから2.55msまでのパルスを生成できます。続いてPWMコンポーネントをダブルクリックして表示されるダイアログを設定します。

PWMコンポーネントの設定

PWM

PWMコンポーネントの設定

こんな感じにしてみました。

ポイントは Run Mode を “One Shot with Single Trigger” にするところでしょうか。デフォルトの “Continuous” のままでは間髪入れずにパルスが出続けてしまいます。ワンショット動作であれば、Trigger後に1つしかパルスが出ないので、トリガをソフトウェアから適切なタイミングで与えるようにします。
 

基板を作る

サーボを動かせそうな目処が立ったので、せっかくなので基板を起こしてみます。そのほうがたくさんのサーボを接続するのが楽です。

最近は無料でもそれなりの機能をもっていて、回路図から基板ガーバ作成までできるソフトウェアが増えてきました。CircuitMaker(オススメ)KiCAD(日本語文献が豊富)DesignsparkPCBなどが流行っているようです。更に、格安で基板を作れるサービスも増えてきました。スイッチサイエンスPCB(日本語で利用可)やSeeedStudioのFusionPCB(オプション豊富で安い)、ElecrowのPCB Prototyping service(基板だけでなくステンシルも安い)などが非常に安価に利用可能です。5cm角の両面基板なら10枚で10ドル程度から製造してくれます。ユニバーサル基板と変わらない値段ですね。

では、まずは好きなCADを使って回路図を引きます。PSoCはIOピンを非常に自由に割当可能なのでざっくり適当に引きます。

回路図

これを

ここから基板を引きます。モータ用電源はマイコンとは分離してアートワークするのがポイントです。

基板

こうして

こうしてできたデータを今回はElecrowで製造してみました。基板が9.5ドルと送料がOCSで13.23ドルでした。

こうじゃ

こうじゃ

部品をはんだ付けして完成です。

要求電流の見当がつかない上に、電流をたくさん流せるような電源コネクタを用意するのが面倒だったので、横着して圧着端子直付けにしてしまいました。良い子のエンジニアは真似しないでくださいね。これは後々サーボの評価とキャリブレーションに使う予定です。
 

ソースコード

PWMやControlRegはAPIを使って操作します。APIのリファレンスはデータシートを読んでいただくとして、叩く必要のあるAPIは以下で済みそうです。

void PWM_Start(void)

void PWM_WriteCompare(uint8/16 compare)

void ControlReg_Write (uint8 control)

これらを、タイミングよく操作するために一定間隔で割り込みを発生させます。プログラマブルロジックをなるべく消費したくないので、ARM系CPUが必ず持っているSystickと呼ばれるカウンタを使ってみます。設定は以下です。

CyIntSetSysVector(15,<割り込みルーチンへのポインタ>);

SysTick_Config( (<バスクロックの周波数>) / <割り込み周波数>);

これらを使ってサイン波のテーブルを順次読み出すようにしてみました(ソースはこちら)。

動作確認ができました。この基板はサーボをたくさん接続できるようにしたので、せっかくなので繋いでみます。Creator上でコンポーネントを並べます。コピペを多用します。

PWMコンポーネント1つあたり2本のPWMを出せます

PWMコンポーネント1つあたり2本のPWMを出せます

コードも同様にコピペで増やします(ソースはこちら)。

それぞれのサーボが独立して動いているのがおわかりいただけるでしょうか。ハードウェアタイマを使って16本のPWMを出力しています。他のマイコンではなかなかできない芸当ですよね。

この状態でもまだまだ半分以上のリソースが余っているので50本以上のPWMを出力することができそうです。サーボに限らず一般的なDCモータやブラシレスモータも楽に駆動できそうです。
 

たくさんのモータを回しています

という事で、絶賛開発中のタチコマには20を超えるモータが搭載されています。現在は様々なアクションを楽しんでいただけるよう調整を行っています。もちろん、機能はモータだけではないですよ。これからの発表を是非楽しみにしていてください。

ぼくタチコマ

ぼくタチコマ

※写真は開発中のものです。
 

Reference:

Cerevo Blog: 「攻殻機動隊」に登場するタチコマを現実世界に再現するプロジェクトを開始
Engadget Japanese: Cerevo、1/8スケールの『タチコマ』をニコニコ超会議で披露。クラウド経由で学習内容の並列化機能も搭載予定?