ク゚ストルヌムの管理゜フトりェアの開発経隓

去幎半はいわゆる非垞に人気がありたす。 ク゚ストルヌム、珟実の生掻で実珟される「郚屋を出る」ク゚スト。 最初のク゚ストに行ったずき、ほずんどのタスクは機械匏ロックのキヌずコヌドを芋぀けるこずでした。磁気ロックはワむダレスむンタヌフェむスはもちろんのこず、クヌルで珍しいものでしたが、さらに、この゚ンタヌテむメントは技術的に難しくなりたした。 冬の終わりに、これらのオフィスの1぀で働いおいる私の友人が、プログラマヌが合䜵し、期限が切れ始めたため、ク゚ストの1぀の制埡プログラムを䜜成するのに助けを求めたした。 タスクは面癜く、お金は悪くなく、善良な人を埗るのは眪ではありたせんでしたので、私は同意したしたが、シナリオ党䜓を知っおいるので、このク゚ストに行かないこずを理解するのはin蟱的でしたが。 最初は期限が非垞に厳しく蚭定されおいたため、開発には䜿い慣れたC ++ \ Qt5.5環境を遞択したした。

あたりよく曞かれおいないTKを䜿っお倚くの愚かさをやったこずがすぐに明らかになりたしたが、誰もがこの間違いを䜕らかの圢で犯したず思うので、それに぀いお曞く理由はありたせん。萜ずし穎ではなく、最も䞀般的な熊手です。



ハヌドりェアの芳点から、ク゚ストの制埡郚分は次のずおりです。





初期蚭定では、タスクは非垞に単玔に芋えたした。MODBUSでデヌタを読み取り、MODBUSでデヌタを曞き蟌み、右の列で適切なタむミングでサりンドを再生し、2番目の画面でビデオを再生したした。 実践が瀺しおいるように、これはすべおそれほど難しくありたせん。 しかし、これを行う方法を理解するこずはそれほど難しくありたせん-それはそれほど些现ではありたせん。



MODBUS



MODBUSは実際には産業甚電子機噚の暙準通信プロトコルであり、TCPたたはcomポヌトを介しお実装されおいたす。 おそらく、TCPで接続されたデバむスがク゚ストで䜿甚された堎合、すべおが少し簡単になるか、そうでないかもしれたせん。 comポヌトでオプションを取埗したした。 このプロトコルの利点は、暙準であるこずです。 短所-シリアルポヌトを介しお9600ボヌの速床で動䜜したす。これにより、最終的に各ポヌトで毎秒玄20リク゚ストに制限されたす。

すべおのMODBUSデバむスには、いく぀かのレゞスタセットがありたす。 私の堎合、フラグレゞスタブヌル倀を栌玍、曞き蟌み可胜、ストレヌゞレゞスタ敎数を栌玍、曞き蟌み可胜、入力レゞスタ敎数を栌玍、曞き蟌み䞍可の3぀が含たれおいたした。 ク゚ストには3぀のリレヌセンサヌ状態が来る8぀の入力レゞスタヌ、リレヌチャネルを制埡する8぀のフラグず調光噚の束実際には5぀のストレヌゞレゞスタを䜿甚し、4぀はチャネルの茝床を制埡し、5぀目は党䜓の茝床がありたした。



ここでは、電子技術者による有胜な蚈画が非垞に重芁です。 たず、アクティブに蚘録しおいるデバむスずアクティブに読み取っおいるデバむスが異なるポヌトにハングしおいるこずが非垞に望たしいです。 私の堎合、これは行われ、1぀のポヌトには調光噚があり、2番目のポヌトにはリレヌがありたした。 第二に、同期蚘録がいく぀かのデバむスに頻繁に行く堎合、それらは隣接するチャンネルでハングする必芁があり、これはトラブルが発生した堎所です。倚くの堎合、䞀緒に燃えるラむトが異なる調光噚にハングし、いく぀かのリク゚ストを送信しなければならないためです貎重な垯域幅。



MODBUSパケットを手動で䜜成したいずいうわずかな欲求も感じなかったため、最終的にlibmodbusラむブラリを䜿甚したした。これは非垞に䟿利で安定しお動䜜したす。 qModMasterプロゞェクトは、読み曞きの基本機胜が実装され、デバッグにHHD Free Serial Virtual Portsその無料機胜は十分すぎるほどずDiagSlave Modbus Slave Simulatorを䜿甚しお非垞に圹立ちたした。 もちろん、ModbusツヌルキットのModbus Slaveははるかに䟿利ですが、1か月間無料で䜿甚するずカボチャに倉わりたす。1぀のプロゞェクトのために賌入したくはありたせんでした。



MODBUSを䜿甚する際に理解しおおくべき重芁事項

1.各ポヌトを個別のスレッドに凊理したす。 ほずんどの堎合、ポヌトが1぀しかない堎合でも、ポヌトの垯域幅党䜓を䜿甚したい堎合は、远加のスレッドなしでビゞュアルむンタヌフェむスを操䜜するこずはできたせん。



2.キュヌむングシステムず優先順䜍を考えたす。 最終的には、ポヌトを凊理するクラスに、曞き蟌みキュヌず読み取りキュヌの2セットのキュヌがありたす。 蚘録では、最初のキュヌは完了する必芁がある1回限りのタスクに割り圓おられたすたずえば、リレヌを閉じる/開く、残りのキュヌは特定のデバむスであり、倀の長いシヌケンスを曞き蟌む必芁がある状況で䜿甚されたすが、すべお曞き蟌たれるこずは重芁ではありたせんたずえば、調光噚制埡ランプの点滅はこの方法で実装されたす、各読み取りキュヌには特定のデバむスからの読み取り芁求が含たれたす。 読み取り優先床も蚭定されおいたす。適応メ゜ッドを思い付かず、カスタムチュヌニングの必芁がないため、定数ずしおコヌドに挿入したした。 読み取り優先順䜍ずは、読み取りキュヌず曞き蟌みキュヌの䞡方にゞョブがある堎合、Xの曞き蟌み操䜜ごずに1぀の読み取り操䜜が保蚌されるこずを意味したす。



読み取り/曞き蟌みキュヌ内では、回転システムが䜿甚されたす。 タスクは最初の段階から取埗され、次に2番目の段階から実行されたす。その埌、円が繰り返されたす。 録音キュヌの堎合、これは別のニュアンスに぀ながりたした。垞に最初のタスクを実行するず、キュヌを完了する時間はキュヌの数に比䟋しお長くなりたす。 このような状況では、ポヌトの負荷に応じお、同じキュヌの長さでランプが10秒間フレアアップするこずを実珟するこずは䞍可胜であり、10秒間、1分間、2秒間フレアするこずができたす。 幞いなこずに、このタスクは非垞に簡単に解決されたす。キュヌからタスクを完了するずき、トップタスクを取埗する前に、キュヌの数だけタスクを砎棄したす圓然、すべおのタスクが実行される遞択された最初のステヌゞの堎合を陀きたす。



3.䞍芁なアクションを実行しないでください。 センサヌが必芁ない堎合は、センサヌから読み取らないでください。センサヌからのアクティベヌション信号を埅っおいお、2番目のセンサヌが必芁ない堎合は、このセンサヌに関連するすべおのタスクをキュヌから消去したす。 かなりお粗末なように聞こえたすが、ハヌドりェアでの最初のテスト䞭に、キュヌが蓄積されたために、必芁なセンサヌがオンになっおから玄5分埌に尋問され始めた状況に盎面したした。 しかし、それから私はただ読曞のための回転線を持っおいたせんでした。



4.ラむトの明るさを制埡する堎合、調光噚には256階調の明るさがあるこずがわかりたすが、0から1、1から10、および64から255ぞの倉化は、脈動する光たたは滑らかな焌き付けを行う必芁があるずきはほが同じですただ真実は段階的ですこれを考慮に入れなければなりたせん。



音

圌らは、特定のチャンネルでサりンドを再生するず述べた。 圌らは簡単だず圌らは蚀った。

おそらく、このタスクの䞭で、音ほど私をノックダりンしたものはないでしょう。 サりンドカヌドを遞択するのは問題かもしれないず思っおいたしたが、厳密に定矩されたチャンネルでサりンドを再生しお他のチャンネルに挏れないようにするこずはそれほど䞀般的ではないず思いたした。

Qtツヌルはすぐに姿を消したした。このラむブラリにはこれに近いものすらありたせん。 サりンドラむブラリを調べおみるず、普通の人は3次元のシヌンを䜜成し、移動するサりンド゜ヌスを割り圓おる必芁がありたすが、特定の列で再生する必芁はないこずがわかりたした。

最初に実珟したオプションは、非垞に汚いハックのように、私の䞭にありたす。 単䞀チャネルのwavファむルを取埗しお゜ヌトし、新しいwavファむルを䜜成したした。チャネルの数は8ずしお瀺され、サンプルは正しいものに曞き蟌たれ、残りはれロになりたす。 このアプロヌチの欠点は非垞に明癜であり、他の圢匏でのサりンドの解析は非垞に耇雑であり、wavファむル内のどのチャネルがどの列に行くかに぀いおの単䞀の暙準はありたせん぀たり、サりンドカヌドを倉曎するず、すべおを再構成する必芁があるかもしれたせん別のチャンネルで再生したいずき。 このオプションは䜕ずか機胜したしたが、率盎に蚀っお私には合わず、怜玢を続けたした。 怜玢は報われたした、私はunsseen開発からBASSラむブラリを芋぀けたした。 この矎しいラむブラリでは、サりンドを再生するずきに、目的のチャンネルを蚭定するだけで目的の効果を埗るこずができたす。 もちろん、ここにも萜ずし穎がありたす。

たず、サりンドの再生は別のストリヌムで行われる必芁がありたすが、ラむブラリでは行われたせん。

次に、サりンドカヌドドラむバヌのすべおの皮類の仮想3DシヌンDFXなどのサりンドのすべおの皮類の調敎を含むを泚意深く監芖および無効にする必芁がありたす。そのような蚭定の存圚は、チャンネル党䜓に音を汚したす䞀般的にすべお。

第䞉に、BASSには文曞化されおいない小さな機胜がありたす。 ベヌスラむブラリのみを䜿甚する堎合、この方法で1぀のチャネルで再生できたすが、サりンドを耇数のチャネルにミックスするこずはできたせん。耇数のチャネルのフラグを適甚しようずするず、ラむブラリによるこの蚭定が無芖されたす。 幞いなこずに、この問題は同じ開発者のBASSmixラむブラリを䜿甚しお解決されおいたす。 耇数のチャンネルでの最終的な再生ただし、同じzvukovuhi内は次のようになりたす



bool res = BASS_SetDevice(device_);//device_ -    if(!res) { int code = BASS_ErrorGetCode(); if(code == BASS_ERROR_INIT) BASS_Init(device_, 44100, BASS_DEVICE_SPEAKERS, 0, 0); else { //  } } mixer_ = BASS_Mixer_StreamCreate(44100, 8, BASS_MIXER_END); if(mixer_ == 0) { //  } for(uint j = 0; j < channel_.size(); j++) { HSTREAM chan = BASS_StreamCreateFile(false, path_.toLocal8Bit().data(),0,0,BASS_STREAM_DECODE|BASS_SAMPLE_MONO);//     - res = BASS_Mixer_StreamAddChannel(mixer_, chan, channel_[j]); //channel_ -     channels_.push_back(chan); if(!res) { //  } } res = BASS_ChannelPlay(mixer_, true); if(!res) { //  }
      
      







映像



ビデオの再生も、顧客の芁件に関連するいく぀かの問題に関連しおいるこずが刀明したした。 テレビはク゚ストに搭茉されおおり、画面の感芚を匕き起こさないはずなので、りィンドりがちら぀かないこずが重芁でしたが、ビデオはすぐに再生を開始したした。 残念ながら、私はただこの問題を完党に解決できおいたせん。

最初のオプションはQtを䜿甚しお実装されたした。 䞀般的に、圌はすべお順調でした。QDesktopWidgetを䜿甚しお、黒でペむントされた子QVideoWidgetを䜜成し、QMediaPlayerを䜿甚しおビデオを出力し始めたした。 すべおが正垞で、アヌティファクトもちら぀きもありたせんでしたが、残念ながらQt5.5では、ビデオの再生がき぀くハングするこずがありたす。 䞍芏則で、予枬䞍胜で、宣戊垃告なし。 そしお、それはただハングし、リブヌト埌にのみ消える途方もない声の挔技で音を詰たらせたす。 このバグがQt 5.6で解決されたかどうかはわかりたせんが、フォヌラムで刀断するず、ビデオの再生時に別のバグが発生し、到達可胜なすべおのプロセッサリ゜ヌスを䜿い果たしおしたいたす。



別のラむブラリをすばやく芋぀けるこずができたせんでした自分でフレヌムシヌケンスを解析し、サりンドをそれらず同期させたいずいうわずかな欲求も感じたせん。そのため、コマンドラむンから起動するための非垞に匷力なツヌルを提䟛するVLC Playerを遞択したした。 フラグの最終セットは次のずおりです。



--qt-minimal-view --no-qt-fs-controller --qt-start-minimized --qt-fullscreen-screennumber = n --fullscreen --play-and-exit --no-osd --no -qt-bgconeファむル名



このキヌのセットを䜿甚するず、プレヌダヌは最小化されお起動しりィンドりが画面䞊でちら぀きたせん、ビデオを展開しお目的のディスプレむで党画面衚瀺し、コントロヌルずファむル名を衚瀺せず、再生の最埌にプログラムを終了したす。



この最埌の時点で、ただ解決されおいない問題が発生したした。 ク゚ストのむベントの䞀郚はビデオ再生の最埌に発生し、QProcessの最埌でのみサヌドパヌティプログラムで再生の終わりを远跡できるため、再生の最埌で終了する必芁がありたすが、プログラムが終了するず、アヌティファクトの束を持぀最埌のフレヌムが0.5秒間衚瀺され、党䜓が台無しになりたす写真。 これたでのずころ、私は顧客にビデオを再マりントするように招埅したした。1、2秒の終わりに黒さを远加したす。アヌティファクトは衚瀺されないはずですが、䜕が起こるか芋おみたしょう。



このメ゜ッドを䜿甚するもう1぀の機胜は、QtがQDesktopWidgetsたたはQScreenのリストを受け取るず、システム内の画面の番号付けに関係のないある皮の順序で゜ヌトし、キヌのVLC --qt-fullscreen-screennumber = nはシステム番号のみを必芁ずしたすただし、1からではなく0から番号が付けられたすので、最終的にQScreenリストを取埗し、デバむス名から画面番号を切り取りたすそれから、VLCの番号を取埗するためにナニットを枛算したした。そのようなもの



  QList<QScreen*> screens = QGuiApplication::screens(); for(int j = 0; j < screens.size(); j++) { QString name = screens[j]->name()+" [" +QString::number(screens[j]->size().width())+"x" +QString::number(screens[j]->size().height())+"]"; int num = screens[j]->name().section("DISPLAY",-1).toInt(); ui->videoDeviceList->addItem(name, screens[j]->name().section("DISPLAY",-1)); }
      
      







画面はDISPLAY1、DISPLAY2などず呌ばれないため、この方法は* nixシステムでは動䜜しないず思われたすが、プログラムはWindowsで玔粋に開発され、他のシステムでは実行されないため、ポむントがわかりたせん。



All Articles