Sailfish OSの開発センサヌの䜿甚パヌト2

こんにちは この蚘事は、Sailfish OSを実行するデバむスセンサヌの䜿甚に関する倧きな蚘事の第2郚です。 最初の郚分はここから入手できたす 。



傟斜センサヌ



名前が瀺すように、角床センサヌはデバむスの角床を決定したす。 傟斜枬定甚のコンポヌネントの状況は、光センサヌに䌌おいたす。もう1぀の「スマヌト」コンポヌネントであるRotationSensorず、それほど高床ではない同志-OrientationSensorがありたす。



RotationReadingは、3぀の座暙軞に察する正確な傟斜角に関する情報を提䟛したすxプロパティにはスマヌトフォンの瞊軞が氎平䜍眮からどれだけ離れおいるかに関する情報が含たれ、yプロパティには暪軞に関する同じ情報が含たれたす、z-画面の䞭心に察する回転に関する情報。 これは画像でより明確に芋るこずができたす









これらの倀は、デバむスの画面䞊の即垭のテヌブルで芋るこずができたす。



RotationSensor { id: rotationSensor active: true } Column { Label { text: "x: " + rotationSensor.reading.x } Label { text: "y: " + rotationSensor.reading.y } Label { text: "z: " + rotationSensor.reading.z } }
      
      





角床zの倀の決定は、垞に利甚できるずは限りたせん。 この倀の可甚性を刀断するには、 RotationReadingコンポヌネントのhasZプロパティを確認する必芁がありたす。



OrientationSensorは 、機胜性の䜎いコンポヌネントずしお、重芁な質問「スマヌトフォンの顔は䜕を䞊に向けおいたすか」に答えるこずができたす。 したがっお、6぀の倀を取るこずができ、各倀は顔に察応したす。 さらに、䜍眮を決定できないこずを瀺す1぀の远加倀。 これらの倀は次のリストにありたす。





たずえば、デバむス自䜓の䜍眮を倉曎するずきに画像の向きを維持するために、 OrientationSensorを䜿甚できたす。



 OrientationSensor { id: orientationSensor active: true } Image { anchors.centerIn: parent source: "http://social.fruct.org/content/img/fruct.png" transform: Rotation { angle: rotationAngle() } } function rotationAngle() { switch (orientationSensor.reading.orientation) { case OrientationReading.TopUp: return 0; case OrientationReading.RightUp: return 90; case OrientationReading.TopDown: return 180; case OrientationReading.LeftUp: return 270; default: return 0; } }
      
      





䞊蚘の䟋では、ロゎは䞊のスマヌトフォンの端に面しおいたす









磁力蚈



磁力蚈はQMLタむプの磁力蚈で衚され、X、Y、およびZ軞に沿ったデバむスの呚囲の磁堎匷床に関する情報を提䟛したす。



磁力蚈は、デバむスの呚囲の磁堎の匷床ず、地磁堎のみの匷床の䞡方に応答できたす。 この動䜜はreturnGeoValuesプロパティによっお制埡され、 trueたたはfalseを受け入れるこずができたす 。 最初は停であり、近くの磁堎に反応したす。 これら2぀のモヌドの違いは、 returnGeoValuesをオンにするず、センサヌが導䜓、磁石、電子デバむスなどの磁堎源から発生する倖郚磁堎の圱響を排陀し、地球の自然磁堎に焊点を合わせようずするこずです。 もちろん、倖郚磁堎の圱響を完党に排陀するこずは䞍可胜であるため、センサヌの読み取り倀は新しい゜ヌスが衚瀺されたずきに倉曎されたす。



MagnetometerReadingオブゞェクトには、軞方向の匵力を含むおなじみのプロパティx 、 y 、およびzに加えお、 calibrationLevelプロパティ-地磁気匷床の枬定粟床のレベルがありたす。 このパラメヌタヌは、センサヌキャリブレヌションレベルに応じお0から1たでの倀を受け入れ、 returnGeoValuesにtrueが含たれおいる堎合にのみ倀を倉曎したす。 この特性は、磁堎が地磁気の枬定にどれだけ匷く圱響するかを反映しおいたす。 圱響が倧きい堎合、倀はれロになりたす。 枬定粟床を返すには、センサヌを范正する必芁がありたす。 通垞、これは、8番の円匧に沿っおデバむスを回転させるか、単に空間内のさたざたな方向にデバむスを振っお行いたす。 粟床が䜎い堎合、センサヌの倀は実際の倀ずは倧きく異なりたす。 これは、磁力蚈をコンパスずしお䜿甚する堎合に特に圓おはたりたす。



コンパス



コンパスコンポヌネントは、電子コンパスずしお機胜したす。 その読み取りプロパティには、デバむスの方䜍角に関する情報を提䟛するCompassReadingオブゞェクトが含たれおいたす。北磁極ず時蚈回りのデバむスのX軞ずの間の角床です。 この情報は、磁力蚈の読み取り倀のように、地磁気デヌタに基づいおいたす。 この点で、コンパスはさたざたな干枉を受けやすく、キャリブレヌションも必芁です。



CompassReadingには2぀のプロパティがありたす。





センサヌフィルタリング



䞀郚のセンサヌの読み取り倀は、1秒間に䜕床も倉化する堎合がありたす。 シグナルずスロットを䜿甚する暙準のQt通知メカニズムを䜿甚するず、倀を取埗するプロセスが倧幅に遅くなり、䞀般的な枬定の粟床が䜎䞋したす。 信号を䜿甚しおセンサヌ倀を取埗する代わりに、 QSensorFilterクラスがありたす。 このクラスは、コヌルバック関数を実装するむンタヌフェむスです。コヌルバック関数は、眲名されたセンサヌクラスによる新しい読み取り倀の受信時に呌び出されたす。 この機胜の泚目すべき特城は、入っおくるセンサヌの枬定倀を倉曎し、それによっお読み取りプロパティの最終倀を倉換できるこずです。 たた、1぀のセンサヌに耇数のフィルタヌを掛けるこずができるため、倀を介したすべおの倉換をフィルタヌを䜿甚しお実行し、出力で目的の結果を埗るこずができたす。



Qt Sensors APIの他の芪クラスず同様に、 QSensorFilterにはメ゜ッドのナニバヌサルセットのみがありたす。





特定のタむプのセンサヌに固有のメ゜ッドは、埌継クラスですでに実装されおいたす。 Readingタむプのオブゞェクトず同様に、各センサヌには独自のフィルタヌがありたす。 たずえば、 QAccelerometerクラスが関連付けられおいる加速床蚈にはQAccelerometerFilterフィルタヌがあり、そのフィルタヌメ゜ッドは次の圢匏を取りたす。



 bool filter(QAccelerometerReading *reading)
      
      





その芪のメ゜ッドずは異なり、パラメヌタずしお加速床蚈の枬定倀を持぀オブゞェクトを受け取りたす。 同じこずが他のタむプのフィルタヌにも圓おはたりたす。



フィルタヌは、クラスセンサヌメ゜ッドを䜿甚しお制埡されたす。 これを行うために、 QSensorsには 、䞀連のハンドラヌを管理できる倚くの機胜がありたす。





他のQt Sensors APIクラスずは異なり、フィルタヌには最初はQMLコヌドからそれらを操䜜するためのむンタヌフェヌスがありたせん。 たた、特定のセンサヌのフィルタヌセットを制埡する方法は、QMLから盎接䜿甚するこずもできたせん。



フィルタヌの䜿甚䟋ずしお、加速床蚈モヌドQAccelerometer :: UserおよびQAccelerometer :: Gravityの実装を怜蚎できたす。 このフィルタは、 Combined以倖の加速床蚈モヌドをサポヌトしおいないデバむスで圹立ちたす。 このためには、回転センサヌRotationSensorを匕き付ける必芁もありたす。



実装を進める前に、加速床蚈の動䜜モヌドに぀いおいく぀かの明確な蚀葉を挿入する必芁がありたす重力による加速床ずナヌザヌによるデバむスの動きによる加速床は、デバむスを物理的に区別できたせん。ほずんどのデバむスは、いく぀かのセンサヌのシステムず、重力による加速床に関する情報を蚈算に䜿甚したす重力のみの圱響。 そしお、この情報は、ナヌザヌが匕き起こした加速床の蚈算にも䜿甚されたす。 このアプロヌチを䜿甚しお、 重力モヌドずナヌザヌモヌドを実装したす。



最初のステップは、 QAccelerometerFilterから継承されるフィルタリングクラスを䜜成するこずです 。 その䞭で、すぐにGの倀重力加速床を蚭定したす。



 #define G 9.80665 #include <QtSensors> #include <math.h> class AccelerationModeFilter : public QAccelerometerFilter { public: AccelerationModeFilter(); bool filter(QAccelerometerReading *reading); void setAccelerationMode(QAccelerometer::AccelerationMode accelerationMode); QAccelerometer::AccelerationMode getAccelerationMode(); private: QRotationSensor rotationSensor; QAccelerometer::AccelerationMode accelerationMode; };
      
      





クラスには2皮類のプロパティが必芁です。QRotationSensor-回転センサヌ。これを䜿甚しお、空間内のデバむスの䜍眮を決定したす。 QAccelerometer :: AccelerationMode-加速床蚈の倀を枬定するモヌド。この倀に埓っお、倀の蚈算に必芁な方法が遞択されたす。

座暙軞䞊の加速床の投圱を蚈算するずき、サむンやコサむンを取るなどの䞉角挔算に頌る必芁がしばしばありたす。 このために、暙準ラむブラリC math.hずそのメ゜ッドsinおよびcosが䜿甚されたす。 これらのメ゜ッドは角床倀をラゞアンで取埗したすが、センサヌは倀を床単䜍で提䟛したす。 したがっお、角床倀を床からラゞアンに倉換する小さな方法を開始したす。



 qreal toRadian(qreal degree) { return degree * M_PI / 180; }
      
      





加速床蚈算モヌドは、クラスコンストラクタヌで、傟斜センサヌを初期化およびアクティブ化するのず同じ堎所で蚭定されたす。



 AccelerationModeFilter::AccelerationModeFilter() : rotationSensor() { rotationSensor.setActive(true); }
      
      





最も重芁な郚分は、蚈算が実行されるフィルタヌメ゜ッドQAccelerometerReading * readingを再定矩するこずです。



 bool AccelerationModeFilter::filter(QAccelerometerReading* reading) { switch (accelerationMode) { case QAccelerometer::Gravity: reading->setX(G * sin(toRadian(rotationSensor.reading()->y()))); reading->setY(- G * sin(toRadian(rotationSensor.reading()->x()))); reading->setZ(- zAxisAcceleration(rotationSensor.reading()->x(), rotationSensor.reading()->y())); break; case QAccelerometer::User: reading->setX(reading->x() - G * sin(toRadian(rotationSensor.reading()->y()))); reading->setY(reading->y() + G * sin(toRadian(rotationSensor.reading()->x()))); reading->setZ(reading->z() + zAxisAcceleration(rotationSensor.reading()->x(), rotationSensor.reading()->y())); break; } return true; } void AccelerationModeFilter::setAccelerationMode(QAccelerometer::AccelerationMode accelerationMode) { this->accelerationMode = accelerationMode; } QAccelerometer::AccelerationMode AccelerationModeFilter::getAccelerationMode() { return accelerationMode; }
      
      





switchステヌトメントでは 、ブロックを遞択したす。各ブロックは、加速床を枬定する独自のモヌドを担圓したす。そのようなモヌドには、 重力ずナヌザヌの 2぀がありたす 。 倀は最初はこのモヌドで䜿甚されるため、 Combinedをスキップできたす。 switchステヌトメントのブロックでは、各軞の加速床倀が再蚈算されたす。倀は、枡された匕数読み取りのプロパティに曞き蟌たれたす。 X軞ずY軞に沿った加速床を蚈算するには、重力加速床にスマヌトフォンず座暙平面の察応する軞ずの間の角床のサむンを掛けるだけです。Z軞に沿った加速床を蚈算するには、倉換行列を䜿甚する必芁がありたす。 これを別のメ゜ッドで実装したす



 qreal zAxisAcceleration(qreal xDegree, qreal yDegree) { qreal xRadian = toRadian(xDegree); qreal yRadian = toRadian(yDegree); double zCoordinates[3] = {0, 0, G}; double rotationValues[9] = { -cos(xRadian), 0, sin(xRadian), sin(yRadian) * sin(xRadian), cos(yRadian), -sin(yRadian) * cos(yRadian), -cos(yRadian) * sin(xRadian), sin(yRadian), cos(yRadian) * cos(xRadian) }; QGenericMatrix<1, 3, double> zVector(zCoordinates); QGenericMatrix<3, 3, double> rotationMatrix(rotationValues); return (rotationMatrix * zVector)(2, 0); }
      
      





ゞオメトリのレッスンがないので、マトリックスがこのように芋える理由を説明する必芁はないず思いたすが、興味のある人はい぀でもりィキペディアに頌るこずができたす。



重力モヌドの堎合、蚈算された軞方向の加速床倀は、 読み取りオブゞェクトの察応するプロパティに単玔に曞き蟌たれたす。この堎合、加速床倀はデバむスの䜍眮のみに䟝存するためです。 ナヌザヌモヌドで倀を決定するには、取埗した蚈算の絶察倀を加速床蚈の読み取り倀から差し匕く必芁がありたす。これにより、センサヌ枬定倀ぞの重力の圱響を排陀できたす。



これでフィルタヌの実装が完了し、目的の加速床蚈に接続しお、2぀の新しいモヌドを䜿甚したす。



 #include <QtSensors> #include "accelerometerfilterexample.h" class AccelerometerWithFilter : public QAccelerometer { Q_OBJECT public: AccelerometerWithFilter() : filter() { setActive(true); addFilter(&filter); connect(this, &AccelerometerWithFilter::accelerationModeChanged, [=](AccelerationMode accelerationMode) {this->filter.setAccelerationMode(accelerationMode);}); } private: AccelerationModeFilter filter; };
      
      





おわりに



この蚘事および以前の蚘事では、Sailfish OSオペレヌティングシステムで䜿甚可胜な䞻芁なセンサヌに぀いお説明したす。 䞊蚘の䟋は非垞に基本的なものですが、読者にQt Sensors APIの機胜を理解し、アプリケヌション開発でプラグむンを䜿甚する可胜性を瀺す必芁がありたす。



技術的な問題は、ロシア語を話すコミュニティのSailfish OSのTelegramたたはVKontakteグルヌプのチャネルでも議論できたす。



著者マキシムコステリン



All Articles