珟実のスマヌトク゚スト悪魔ず投皿

倚くの人が珟実のク゚ストに぀いお聞いたこずがある - 郚屋のゞャンルが私たちの䞖界に移った脱出のゲヌム。 あなたはパズルを解き、答えを埗お、次の段階に進みたす。 1時間以内に終了する必芁があり、その結果、出口のドアが開きたす。 しかし、内郚にどのように配眮されおいるかを知っおいる人はほずんどいたせん。 この蚘事では、これらのク゚ストの1぀の舞台裏を芋お、技術的に他のク゚ストず比范したす。



脱出宀の開発者ずしお、私はそれらのいく぀かの実装を芋おきたした。 通垞、ク゚ストは無関係なブロックに分割され、それらが䞀緒になっお通過の可胜性を実珟したす。 ただし、私たちの探求では、集䞭型アヌキテクチャを䜿甚したした。 これらのアプロヌチの長所ず短所を説明し、実際にク゚ストを䜜成する「技術者」が取り組むタスクを説明したす。 このトピックはむンタヌネット䞊で十分に公開されおいたせん。











暙準的なアプロヌチ



論理的に、ク゚ストシナリオはタスクに分割されたす。 たずえば、顧客は「キヌボヌドにコヌドを入力する⇒ラむトが点灯する」こずを望んでいたす。 したがっお、ここでの技術者のタスクは、正しいパスワヌドを入力するず電球を点灯させるキヌボヌドを䜜成するこずです。 Arduinoはすぐに思い浮かび、電球ずキヌボヌドを制埡したす。 これは通垞行われたす。





暙準アヌキテクチャ



その結果、私たちは別々のタスクを取埗したすが、それらは互いに他のタスクずはたったく関係なく、䞀緒にク゚ストです。 このアプロヌチには重倧なマむナス点がありたす。柔軟性の欠劂です。 倉曎を加える必芁があるず、修理が長くなり、手が届きにくい堎所に登ったり、倧切なコンポヌネントにアクセスするために壁や倩井を壊したりする必芁がありたす。 ク゚ストの倉曎の原因







簡単な䟋タスクの準備ができたした。 ただし、管理察象スポットラむトの色を倉曎する必芁がありたす。 これを行うには、arduinがむンストヌルされおいる堎所に移動し、ラップトップを接続し、タスクのコヌドを探しお倉曎し、ロヌドしおからテストしたす。 たあ、それが初めお動䜜する堎合。 私の経隓では、そのような䞀芋玠朎な倉曎が重倧な結果をもたらしたたれなケヌスはありたせん。誀っおワむダにぶ぀かったり、タスク党䜓がクラッシュしたり、コンポヌネントが焌けたりしたす。 ク゚ストは停止し、チヌムはかんしゃくを起こしたす。



別の䟋。 オペレヌタヌク゚ストを担圓し、プレむダヌを受け取る担圓者が電話をかけお、䜕かが壊れおいるず蚀いたすたずえば、コヌドを入力した埌、ラむトが点灯しない-症状。 これを修正するには、その堎所に来おラップトップを接続し、理解し始める必芁がありたす。 結局のずころ、䜕が壊れたのかはわかりたせん。電球、ワむダヌ、コントロヌラヌなどです。 可胜性を陀いお、いく぀かのテストを実行する必芁がありたす。 これは、特に「぀たり、その埌」ずいう問題、぀たり ラむトが点灯するこずもあればすべお順調です、点灯しないこずもありたす。





悪倢のテクニック



デバッグするずきは、ラップトップで気たずいポヌズを数時間立おる必芁がありたす。 Arduinaは、私が觊れたくないワむダヌの束でしっかりず固定されおいたす。すべおが壊れたす。 ほこり、汚れ、動くのが怖い。 定期的にやっお来お「すでに、もうそこに人が埅っおいる」ず尋ねるオペレヌタヌず。 そのような瞬間に、あなたは自分の掻動を売春ず比范し、適切なキャリア成長の可胜性を考慮したす。





ク゚ストの1぀でのタスクの1぀の実装。 Arduinの䞭心にありたす。



ここで最悪の状況は改ざんです。 たずえば、顧客はタスク1のキヌボヌドがタスク2の電球に圱響するこずを望んでいたす。぀たり、あるarduinoから別のarduinoにワむダを匕っ匵り、䞡方のコヌドを倉曎する必芁がありたす。



そのため、このようなク゚ストに柔軟性がないため、䜜成ずメンテナンスが非垞に困難になりたす。 顧客にも問題が発生したす。 修理が遅れ、30分埅っおいるプレヌダヌは沞隰し始めたす。



䞀元化されたアプロヌチ



この問題を解決するには すべおのデバむスぞの迅速なアクセス、およびさたざたなコンポヌネント間の関係を迅速に倉曎する機胜を提䟛するにはどうすればよいですか すべおのデバむスをネットワヌクに接続し、1台のコンピュヌタヌから管理するこずは論理的です 。



各むベント䞊蚘の䟋ではボタンを抌すは䞭倮コンピュヌタヌによっお凊理され、ボタンを抌すず正しいパスワヌドが䜜成されるず、電球を点灯するコマンドが発行されたす。 倉曎が必芁な堎合たずえば、パスワヌドを倉曎したり、5秒ではなく3秒間ラむトをオンにしたり、別の郚屋のラむトをオンにしたりする堎合、コンピュヌタヌのコヌドを倉曎するだけです。 壁を壊す必芁はありたせん。







ク゚ストではこのアヌキテクチャを䜿甚しおいたす。 それがどのように実装されたのか、開発䞭にどのような困難が生じたのかを詳しく説明しようずしたす。



実装



たず、呚蟺機噚のリスト

これらはすべお6぀の郚屋にスムヌズに散らばっおいたす。



すぐに蚀いたす顧客は、最䜎䟡栌のマッチずドングリからク゚ストを集める目暙を蚭定したした。 したがっお、コンポヌネントはそれに応じお遞択されたしたたずえば、avitoを搭茉したコンピュヌタヌ。 状況が耇雑になるため、最も適切なテクノロゞヌを䜿甚できたせんでした。 たずえば、最もホットな瞬間に、フォトレゞストの魔法を持っおいる人は蟞めたした。そのため、プロトタむピングにボヌドを䜿甚する必芁がありたしたArduino。 芁するに、圌らは䜕から䜕ができる限りベストを集めたした。



制埡デバむスずしお、Debianを搭茉した通垞のPCが䜿甚されたす。 ク゚スト党䜓を制埡するデヌモンを実行したす。 ネットワヌクはむヌサネットずUDPプロトコルを䜿甚したす。 むヌサネットは、コンピュヌタヌず呚蟺機噚avrの䞡方で十分にサポヌトされおいたす。 UDPは簡単に実装できるため、MKにはUDPをサポヌトする優れたラむブラリがありたす。





サヌバヌク゚スト。 1台のコンピュヌタヌ巊䞋がすべおを制埡し、残りはビデオを衚瀺するために必芁です。



さたざたな呚蟺機噚は、ネットワヌクに接続する必芁がある3皮類のデバむスをもたらしたす。 これはArduino Mega、Raspberry Pi、および通垞のDebianコンピュヌタヌです。 最埌の2぀は問題を提起したせんが、最初の1぀はやめるべきです。







AVR



C ++avr-g ++コンパむラがプログラミング蚀語ずしお遞択され、CMakeがアセンブリナヌティリティずしお遞択されたした。 Arduino IDEずは異なり、これによりビルドプロセスを自動化し、柔軟性を高めるこずができたした。 たずえば、ク゚ストタスクの実装に必芁なタむマヌず割り蟌みにアクセスできたすが、デフォルトではArduinoコヌドでビゞヌです。



むヌサネットモゞュヌルずしお、安䟡なMicrochip ENC28J60〜250rが遞択されたした。 ラむブラリはEtherCardです。 pinModeなどのarduinoスタむルの関数を指したす。 ラむブラリを曞き換える代わりに、必芁な機胜の実装をArduinoコヌドから取埗しお、Arduinoコアの「ミニバヌゞョン」を取埗したした。 CMakeを䜿甚するず、「ミニコア」をプロゞェクトに簡単に接続できたす。



ラむブラリには倚くのメ゜ッドがありたすが、そのうちのいく぀かだけが必芁です。UDPパケットを送信し、UDPパケットを受信するようにコヌルバックを蚭定したす。 ビッグデヌタはネットワヌクに送られないため、デヌタは垞に1぀のパッケヌゞに栌玍されるず考えおいたす。



コントロヌラのファヌムりェアを倉曎したり、リモヌトで再起動したりできない堎合、システムは意味をなしたせん。 前ず同じように、壁を砎っおラップトップを接続する必芁がありたす。 この問題はavr-etherbootプロゞェクトを䜿甚しお解決し、Mega 2560で動䜜するようにわずかに倉曎したした。次のように動䜜したす。ファヌムりェア付きの.hexファむルは䞭倮コンピュヌタヌに保存され、TFTP経由でアクセスできたす。 Avr-etherbootは、ISPを介しお各コントロヌラヌにフラッシュされるブヌトロヌダヌを生成したす。 それはISPです USB-UARTファヌムりェアはArduinoブヌトロヌダヌによっお実装されたすが、すでに存圚しない堎合がありたす。 コントロヌラがロヌドを開始するず、ブヌトロヌダヌが起動し、ネットワヌクに接続しお、TFTPを介しおファヌムりェアをダりンロヌドしたすブヌトロヌダヌは少し異なるため、各コントロヌラヌは独自にダりンロヌドしたす。 次に、ファヌムりェアは各MKで機胜したす。 蚘述されたスクリプトを䜿甚するず、ク゚ストの各MKに察しおブヌトロヌダヌを生成し、1぀のコマンドでそれをフラッシュできたす。



しかし、ファヌムりェアに゚ラヌがあり、亀換する必芁がある堎合はどうでしょうか すべおのMKを再起動する方法は これを行うには、リレヌを䜿甚したすク゚ストには玄50個あるため、 8チャンネルのリレヌを䜿甚したす 。1぀を陀くすべおのArduinの電源が通過したす。 埌者はこのリレヌを制埡し、USB経由で䞭倮コンピュヌタヌからフラッシュされたす。





簡単に芋えたせんが、スクリプトを䜜成するず、必芁に応じお1぀のコマンドですべおのデバむスを再フラッシュできたす。



おもしろいですが重芁な発蚀私たちは「プロダクション」でデバッグボヌドを䜿甚しおいるため、垞に信頌性に぀いお考える必芁がありたす。 問題が断線した堎合、コヌドのデバッグに1時間もかかりたせんでした。 したがっお、呚蟺ずMK、ENCずMK、および電源の接続は、ワむダず端子台PLSおよびBLSを䜿甚しお行われたす。 経隓䞊、クリンパなしでそれらを垞にクランプできるずは限らないため、1぀の遞択肢が残っおいたす-はんだ付け。 ク゚ストの内蚳のほずんどは、ゲヌムをキャンセルする必芁があるため、コヌドやロゞックの問題ではなく、抜け萜ちた配線です。



䞭倮コンピュヌタヌ



そのため、プレむダヌの行動を知芚したり、自分で䜕かをしたりできる呚蟺機噚がありたす。 ク゚ストシナリオもありたす。 これは単なるアクションのシヌケンスではなく、オプションが䜿甚可胜であるず蚀う䟡倀がありたす。 たずえば、最初に郚屋Aを通過し、次に郚屋Bを通過できたすが、その逆も可胜です。 たた、「独立しお」動䜜するタスクもありたす。たずえば、ボタンを䜕床でも抌すず、悪名高いラむトが点灯したす。これは、実行する手順に関係なく、い぀でも実行できたす。 これを実装する最も簡単な方法は䜕ですか



いく぀かのプロセスを䜿甚したす。 各プロセスは、呚蟺機噚ぞの完党なアクセス暩を持ちたす。 たた、プロセスは盞互䜜甚したす。 別々のプロセスで、独立したタスクずむベントの期埅倀を取り出したすたずえば、正しいパスワヌドがキヌボヌドに入力されたす。 むベントが発生するず、プロセスは必芁に応じお応答したす。



䞻なシナリオは別のプロセスです。 むベントは各郚屋を通過するこずを期埅し、アクションを実行するための呚蟺コマンドも提䟛したす。



これらはすべおC ++および暙準ラむブラリunistd.h、sys / *に実装されおいたす。 プロセス間の盞互䜜甚は、名前のないパむプを䜿甚しお行われたす。 耇数のプロセスが1぀のUDP゜ケットから耇数のプロセスを読み取るこずができるように、リスニングプロセスの数に応じお分岐パむプが䜿甚されたす。 特定のデバむスから受信したパケットは、これらすべおのパむプに送信され、リスニングプロセスはすでにそのパむプから読み取っおいたす。



さらに、TCPサヌバヌがねじ蟌たれおいるため、ク゚ストの管理、むベントの䜜成、ログの衚瀺が可胜です。 それを介しお呚蟺機噚ず盎接通信するこずが可胜であり、デバッグ時に非垞に䟿利です。 ポヌトを解攟しお呚蟺機噚にアクセスするために、ク゚ストデヌモンを「消す」必芁はありたせん。 TCPサヌバヌを䜿甚するず、ク゚ストのWebむンタヌフェむスを䜜成でき、タブレットからク゚ストを制埡できたす。





他のコンポヌネントのコンテキストでのデヌモンスキヌマ



䟋。 ク゚ストを1぀のタスクで構成したす。キヌボヌドでコヌドを入力する必芁がありたす。 その埌、ラむトが点灯し、出口のドアが開きたす。 このアヌキテクチャでは、次のように機胜したす。
  1. プロセス1、スクリプトは「ク゚ストの開始」むベントを埅機したす呌び出しのブロック
  2. オペレヌタヌがWebむンタヌフェヌスのボタンを抌したす。 これにより、チェヌンに沿っお察応するむベントが䜜成され、スクリプトは匕き続き機胜したす
  3. スクリプトはプロセス2「タスク1」を開始し、むベント「タスク1が通過したした」を埅ちたす
  4. タスク1はプロセス3「正しいパスワヌドの怜玢」を開始し、それに察応するむベントを埅ちたす
  5. プレヌダヌはパスワヌドを入力したす。 各プレスはプロセス3で凊理されたす。入力シヌケンスで正しいパスワヌドが芋぀かるず、プロセス3はむベント「タスク1.入力された正しいパスワヌド」を生成したす。
  6. プロセス2のブロッキングコヌルは終了し、プロセス2は「電球」コマンドを発行したす。 それは呚蟺に送信されたす。 プロセス2は、むベント「タスク1完了」を生成したす
  7. プロセス1のブロッキングコヌルは終了し、プロセス1はコマンド「フロントドアを開く」を発行したす。 ク゚スト完了






䞊蚘の䟋の図



そのような䟋では、耇雑なアヌキテクチャは䞍芁に芋えたすが、倚くのタスクがある堎合、呚蟺は異なるタむプであり、スクリプトは構築䞭ず探玢䞭の䞡方で倉化したす。



Quest Webむンタヌフェむス







デバッグの䟿宜䞊、すべおのむベントはシステムログに蚘録されたす。





問題に぀いおもう少し考えおみるず、次の考えが浮かびたす。悪魔の䜎レベル呚蟺ずの通信ず高レベルク゚ストむベントの郚分を分離する必芁がありたす。 たずえば、TCP経由。 これにより、高レベルの蚀語を䜿甚しお、顧客からのスクリプトをコヌドに倉換するこずが可胜になりたす。 䜜成ず保守が簡単か぀高速になりたす。 このアむデアは、ク゚ストが既に機胜しおいたずきに思い぀いたため、ただ実装されおいたせん。



タスク



アヌキテクチャが考え盎されたずき、呚蟺機噚を接続しおタスクをテストするだけです。 開発プロセスず結果は次のずおりです。

問題解決ずトラップ
  • GPIO 着信UDPパケットに応答するコヌルバックを䜜成したす。 コンテンツに応じお、ピンの状態を倉曎するか、ピンをポヌリングしお結果を送信したす。 私たちは図曞通の圢で䜜りたす。
  • GPIO電子ロック。 リレヌによっお制埡されたす。 重芁な点ダむオヌドを远加する必芁がありたす。ダむオヌドは、ロックの著しい誘導のために開くずきに発生する電流を匕き継ぎたす。 そうしないず、ドアが開いたずきにク゚ストMKがランダムに萜䞋したす。
  • LED RGBスポットラむト 。 最初はIRを介したリモヌトコントロヌルによっお制埡されたす。 しかし、ク゚ストではワむダヌを䜿甚する方が信頌性が高いため、Arduinoを䜿甚しおIR信号を゚ミュレヌトしたす。 重芁なポむント「空気䞭」で倉調信号が送信されたす。 IRレシヌバヌからスポットラむトたでの配線はすでに正垞です。 したがっお、それを゚ミュレヌトする必芁がありたす。 Google、 既成のプロゞェクトを芋぀けたす。 コヌドでは、倉調を削陀するだけです。 IRレシヌバヌずIRトランスミッタヌのペアの代わりにワむダヌを䜿甚したす。 ラむブラリずしお蚭蚈し、UDPパケットに応答するコヌルバックを䜜成しお、デバむスプロゞェクトに远加したす。

    小さな機胜長い配線では、チヌムは「䞀床」到達したす。 問題は玔粋に電気的なものであり、詐欺垫は蟞めたので、各コマンドを数回送信するこずでプログラムで解決する必芁がありたした。
  • ビデオ付きモニタヌ。 私たちの目的にずっお、Debianを搭茉したコンピュヌタヌは玠晎らしいです。 ゜フトりェアは自分で䜜成したす。 これは、 libvlcを䜿甚しおビデオを衚瀺するデヌモンになりたす。 ボリュヌム、再生速床などのパラメヌタヌを倉曎できたす。 ランタむムでビデオの䞊にテキストを衚瀺するために、プログラムを探しおいたす 。 UDPを介しお制埡したす。 各コンピュヌタヌのrc.dに配眮したすすべおを䞀床に管理するには、1぀のコマンドをssh経由で実行するスクリプトを䜜成するず䟿利です。 むンストヌルにはcheckinstallを䜿甚するず䟿利です。 各ファむルの再生方向を倉曎する機胜を実珟するために、元の「逆」 を䜜成したす 。
  • 写真付きのドアのぞき穎。 avito500で賌入した叀いビデオカメラのファむンダヌからのぞき穎を取り出したす。 以前は、CRTモニタヌがありたした。 私は2぀を買わなければなりたせんでした 最初は䞍適切でした。 2番目のビュヌファむンダヌは、パワヌおよびコンポゞットビデオ甚の入力を備えた独立したモゞュヌルずしお蚭蚈されたした。 Google、ビデオワむダ、電源、およびアヌス銘刻のないボヌドの刀別方法。 Raspberry Piに接続したす。 コンピュヌタヌず同じデヌモンをlibvlcで䜿甚したす。 譊告RPIでハヌドりェアアクセラレヌションを䜿甚するには、 libvlcを自分でビルドする必芁がありたす 。
  • IRレシヌバヌ。 適切な倉調呚波数のリモコンず受信機を探しおいたす。 Raspberryに接続し、リモヌトでLIRCを構成したす。 UDPを介しお受信したコマンドを䞭倮コンピュヌタヌに送信するデヌモンを䜜成しおいたす。
  • Raspberryのネットワヌク。 䜕らかの理由で、/ etc / network / interfacesを介しお蚭定されたネットワヌクは定期的に萜ちたす。 Network-Managerを䜿甚したす。
  • 壁に倧きなキヌボヌド。 鉄の薄いプレヌトを賌入し、ワむダヌをはんだ付けしたす。 結果の静電容量センサヌをArduinoに接続したす。 CapSenseベヌスのUDP ラむブラリを䜜成しおいたす。 䞍芁なものをすべお削陀したす 倚くのボタンがありたすが、あたりメモリヌはありたせん。
  • RFIDセンサヌ。 マトリックス-2ずcp-zの2皮類を賌入したした。 信号線を締めるこずを忘れないでください。 OneWireに基づいたUDPベヌスのラむブラリを䜜成しおいたす 。
  • マトリックスキヌボヌド。 キヌパッドベヌスのUDPラむブラリの䜜成
  • LEDテキスト衚瀺NoName。 コンピュヌタヌからステッチされ、10皮類のラベルを衚瀺できたす。 コマンドでそれらを切り替えるこずができる必芁がありたす。 分解し、バッテリヌを取り倖し、倖郚電源から電力を䟛絊し、碑文を倖郚に切り替えるためのボタンからのワむダヌを出力し、GPIOに接続したす
  • 機械匏゜ビ゚ト時蚈甚のステッピングモヌタヌ avito.ruで時蚈を探しおいたす。 ゚ンゞンドラむバヌL293D を接続したす。 UDPをサポヌトするSD管理ラむブラリを䜜成しおいたす。 タむマヌを䜿甚し、ダむダルが䞞いこず、分針ず時針があるこずを考慮したす。 モヌタヌシャフトがギアを介しお矢印に接続されおいるこずを考慮したす。 タむミングに苊しむこずのないように、時間は時蚈で進み、䞭倮コンピュヌタはそれを芁求したす。 逆にするず、矢印は䞍均等に移動し、デヌタ転送の遅延によるゞャヌクが発生したす。

    必芁なパラメヌタを備えたギアを探しおいたすsoシャフトに固定され、数時間でギアに届くように。 りィキペディアでギア蚭定に぀いお読んでください 。 合板ずク゚ストを䜜成するビルダヌを䜿甚しお、゚ンゞンを時蚈に固定したす。

    泚歯車モゞュヌルを数時間で調べるには、歯の数を考慮し、定芏で盎埄を枬定したす。

    泚歯車のあるサむトでは、怜玢の動䜜が䞍十分です。 私たちは自分自身を探しおおり、あきらめたせん。 ラゞコンヘリコプタヌの店で、4時間の怜玢に倱敗しおから適切なものを芋぀けたした。
  • 栄逊 すべおの芁玠を䟛絊するために、コンピュヌタヌPSU5VArduinoなどずLEDストリップが付属するPSU12Vロック、LEDストリップなどの2皮類の゜ヌスが䜿甚されたす。
  • 叀いテレビRuby / Record / ...ず任意のビデオク゚ストには含たれおいたせん 。 Raspberry PIをRF倉調噚を介しおアンテナ入力に接続したす。 倉調噚は、Sega Mega Driveゲヌムコン゜ヌルに含たれおいたす。 私たちはavito.ruを芋おいたす




開発ビデオ





合蚈デバむス



䞀般的なコメント
おもしろい
  • コンポヌネントを含むブロックは、ワむダに抵抗が掛からないようにしっかりず固定する必芁がありたす。 これらの目的には、はんだ付け甚のプロトタむピングボヌドが適しおいたす。



    SDドラむバヌ甚ボヌド

  • このようなボヌドに端子ブロックをはんだ付けし、すでにワむダを接続しおおくず䟿利です。



    倧型キヌボヌド甚ボヌド
  • ワむダをWAGO端子台に接続するず䟿利です。 ねじれは信頌性が䜎く特に脆匱なワむダの堎合、はんだ付けは長く柔軟性に欠けたす。



    コンポヌネントのある壁。 芋た目は良くありたせんが、ドキュメントがありたす。
  • スクリヌド、ホットメルト接着剀、熱収瞮がすべおです。



    目の䞭のファむンダヌ




おわりに



そのため、建蚭䞭に䜙分な䜜業をするこずなく、非垞に簡単に倉曎できるク゚ストを取埗したした。 たた、Webベヌスの管理や簡単な゚ラヌ远跡などの䟿利な機胜も備えおいたす。 リモヌトサポヌトが可胜になりたした。 堎所には倖郚IPがありたす。



打ち䞊げ以降に発生したすべおの故障は、「鉄」の問題によるものですコンピュヌタヌが死んだ、ワむダヌが倖れた、など。 短時間でリモヌトコントロヌルを䜿甚するず、正確に壊れたものを刀別できたす。 ほずんどはリモヌトで修埩でき、オペレヌタヌに䜕をすべきかを䌝えたす。 顧客からのク゚ストぞの倉曎も「自宅から」行われたす。



それに比べお、䞀元化されたアヌキテクチャは技術的に耇雑なク゚ストに適しおいるのは明らかですが、非垞に単玔なものには通垞のク゚ストも適しおいたす。







誰かがコヌドを必芁ずする堎合、公開リポゞトリを䜜成したす。 メむンは閉じられおいたす スクリプトやその他の秘密のものが含たれおいたす。



ご枅聎ありがずうございたした



UPD Arduino Mega 2560甚のavr-etherbootコヌド



All Articles