1 /*---------------------------------------------------------------------------* 2 Project: horizon 3 File: hid_GyroscopeReader.h 4 5 Copyright 2010 Nintendo. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: $ 14 *---------------------------------------------------------------------------*/ 15 16 /*! @file 17 @brief GyroscopeReaderクラスを定義します 18 19 */ 20 21 #ifndef NN_HID_CTR_GYROSCOPEREADER_H_ 22 #define NN_HID_CTR_GYROSCOPEREADER_H_ 23 24 #include <nn/Handle.h> 25 #include <nn/Result.h> 26 #include <nn/types.h> 27 #include <nn/hid/CTR/hid_Result.h> 28 #include <nn/hid/CTR/hid_Api.h> 29 #include <nn/hid/CTR/hid_Gyroscope.h> 30 #include <nn/hid/CTR/hid_AccelerometerReader.h> 31 #include <nn/hid/CTR/hid_DeviceStatus.h> 32 #include <nn/util/util_SizedEnum.h> 33 #include <nn/util/util_NonCopyable.h> 34 35 namespace nn 36 { 37 namespace hid 38 { 39 namespace CTR 40 { 41 42 /*! 43 @brief ゼロ点のドリフト修正の強度を設定する列挙体です 44 */ 45 enum ZeroDriftMode 46 { 47 GYROSCOPE_ZERODRIFT_LOOSE, //!< センサの値がある程度変動していても、安定しているとみなして修正が行われるモードです。 48 GYROSCOPE_ZERODRIFT_STANDARD,//!< GYROSCOPE_ZERODRIFT_LOOSE と GYROSCOPE_ZERODRIFT_TIGHT の中間にあたるモードです。 49 GYROSCOPE_ZERODRIFT_TIGHT,//!< センサの値が定められた閾値以内の変動でないと、安定しているとみなさない厳密な修正が行われるモードです。 50 GYROSCOPE_ZERODRIFT_NUM 51 }; 52 53 54 /*! 55 @brief ジャイロセンサのサンプリングデータを読み込むクラスです。 56 */ 57 class GyroscopeReader: private nn::util::NonCopyable<GyroscopeReader> 58 { 59 public: 60 61 62 /*! 63 @name コンストラクタ/デストラクタ 64 @{ 65 */ 66 67 /*! 68 @brief コンストラクタです。 69 70 インスタンスを生成する前に @ref nn::hid::CTR::Initialize( ) で初期化してください。<BR> 71 サンプリングを開始するために必要な設定を行います。<BR> 72 最初のインスタンスを生成してからサンプリングが開始されるまでにウェイト時間が必要な点にご注意ください。 73 @param[in] pAccelerometrReader @ref AccelerometerReaderへの参照を指定すると、参照する @ref AccelerometerReader の出力値を利用した補正を行います。 74 デフォルトではNULLが渡され、この場合内部に保持するデフォルトの @ref AccelerometerReader によって補正を行います。 75 76 */ 77 GyroscopeReader(AccelerometerReader* pAccelerometerReader = NULL, Gyroscope& gyroscope = GetGyroscope()); 78 79 /*! 80 @brief デストラクタです。 81 */ 82 83 ~GyroscopeReader(); 84 85 /*! 86 @} 87 */ 88 89 /*! 90 @name サンプリングデータの読み込み 91 @{ 92 */ 93 94 /*! 95 @brief ジャイロセンサのサンプリングデータを新しいものから順に読み込みます。以前に読み込んだデータは読み込まれません。 96 97 @param[out] pBufs 新しいものから順にサンプリングデータが読み込まれます。 98 @param[out] pReadLen 読み込んだサンプリングデータの数です。 99 @param[in] bufLen pBufs に読み込めるサンプリングデータの数を指定します。 100 @return なし。 101 102 */ 103 void Read(GyroscopeStatus* pBufs, s32* pReadLen, s32 bufLen); 104 105 /*! 106 @brief 最新のジャイロセンサのサンプリングデータを読み込みます。 nn::hid::CTR::GyroscopeReader::Read( ) とちがい同じサンプリングデータを読み込むことが出来ます。 107 108 @param[out] pBuf サンプリングデータが読み込まれます。 109 @return サンプリングデータの読み込み結果を返します。<BR> 110 true ・・・ 読み込めました。<BR> 111 false ・・・ 読み込めませんでした。(GyroscopeReaderのインスタンス生成後あるいはスリープ復帰後の最初のサンプリングが行われ次第、読み込めます。) 112 113 */ 114 bool ReadLatest(GyroscopeStatus* pBuf); 115 116 /*! 117 @} 118 */ 119 120 /*! 121 @name リセット 122 @{ 123 */ 124 125 /*! 126 @brief 内部状態を初期化します。 127 128 このとき、各種補正処理の設定も以下のようになります。 129 130 加速度の補正 有効になります。<BR> 131 ゼロ点のドリフト補正 GYROSCOPE_ZERODRIFT_STANDARD に設定され、有効になります。<BR> 132 ゼロ点の遊び 無効になります。<BR> 133 軸回転 回転行列に単位行列が設定され、さらに無効になります。<BR> 134 角速度の倍率 すべて1.0 に設定されます<BR> 135 136 @return なし。 137 */ 138 139 void Reset(); 140 141 /*! 142 @} 143 */ 144 145 /*! 146 @name 出力値の設定 147 @{ 148 */ 149 150 151 /*! 152 @brief @ref Read ・ @ref ReadLatest 関数で得られる GyroscopeStatus 構造体の angle を任意の値にリセットします。 153 @param[in] ax ピッチ方向の角度。角度は 1.0 を 360度とした値です。 154 @param[in] ay ヨー方向の角度。角度は 1.0 を 360度とした値です。 155 @param[in] az ロール方向の角度。角度は 1.0 を 360度とした値です。 156 @return なし。 157 */ 158 void SetAngle(f32 ax, f32 ay, f32 az); 159 160 /*! 161 @brief @ref Read ・ @ref ReadLatest 関数で得られる GyroscopeStatus 構造体の direction を任意の値にリセットします。 162 @param[in] direction 設定する任意の3次元姿勢。 163 @return なし。 164 */ 165 void SetDirection(const Direction& direction); 166 167 /*! 168 @brief 角速度を計算する際に掛ける倍率を各方向ごとに設定します。 169 @param[in] pitch pitch方向の角速度を計算する際に掛ける倍率。 170 @param[in] yaw yaw方向の角速度を計算する際に掛ける倍率。 171 @param[in] roll roll方向の角速度を計算する際に掛ける倍率。 172 @return なし。 173 */ 174 void SetAngleMagnification(f32 pitch, f32 yaw, f32 roll); 175 176 /*! 177 @brief @ref Read ・ @ref ReadLatest 関数で得られる GyroscopeStatus 構造体の direction を内部で計算する際に使用する角速度の値にかける倍率を設定します。 178 179 たとえば、magification を 2.0f に設定した場合、90度回転させると GyroscopeStatus 構造体の direction は180度回転した姿勢として計算されます。 180 181 @param[in] magnification 三次元姿勢を計算する際に使用する角速度にかける倍率。 182 @return なし。 183 */ 184 void SetDirectionMagnification(f32 magnification); 185 186 /*! 187 @} 188 */ 189 190 /*! 191 @name ゼロ点の遊び 192 @{ 193 */ 194 195 /*! 196 @brief ゼロ点の遊びを有効にします。 197 @return なし。 198 */ 199 void EnableZeroPlay(); 200 201 /*! 202 @brief ゼロ点の遊びを無効にします。 203 @return なし。 204 */ 205 void DisableZeroPlay(); 206 207 /*! 208 @brief ゼロ点の遊びが有効になっているか調べます。 209 @return 有効な場合にtrue,無効な場合にfalseが帰ります。 210 */ 211 bool IsEnableZeroPlay() const; 212 213 /*! 214 @brief ゼロ点の遊びによる補正処理の働き具合を返します。 215 216 ゼロ点の遊びが無効の場合は0を返します。 217 218 @return 無効の場合は常に0が返ります。有効の場合は0以上の値が返ります。この値は補正処理の働き具合を示します。 219 220 現在の角速度が設定した遊びの値に近いほど0に近づき、遊びの範囲を越える速度になると0になります。 221 */ 222 f32 GetZeroPlayEffect() const; 223 224 225 /*! 226 @brief 静止時(ゼロ点)の遊びを設定します。 227 228 遊びを設けると小さな動きに反応しなくなります。 229 230 設定した遊びはすべての方向に対して適用されます。 231 232 @param[in] radius ゼロ点の遊び具合。1.0f を 360 dps とした値を設定します。 233 @return なし。 234 */ 235 void SetZeroPlayParam(f32 radius); 236 237 /*! 238 @brief ゼロ点の遊びを取得します。 239 240 遊びは 1.0f を 360 dps とした値になります。 241 242 @param[out] radius 現在のゼロ点の遊び具合をコピーするバッファ。 243 @return なし。 244 */ 245 void GetZeroPlayParam(f32& radius) const; 246 247 /*! 248 @brief ゼロ点の遊びを初期化します。 249 250 初期値は 0.005f となります。 251 252 @return なし。 253 */ 254 void ResetZeroPlayParam(); 255 256 /*! 257 @} 258 */ 259 260 261 /*! 262 @name ゼロ点ドリフトの補正 263 @{ 264 */ 265 266 /*! 267 @brief ゼロ点ドリフトの補正を有効にします。 268 @return なし。 269 */ 270 void EnableZeroDrift(); 271 272 /*! 273 @brief ゼロ点ドリフトの補正を無効にします。 274 @return なし。 275 */ 276 void DisableZeroDrift(); 277 278 /*! 279 @brief ゼロ点ドリフトの補正が有効になっているか調べます。 280 281 ゼロ点ドリフトの補正は初期状態では有効となっています。 282 283 @return 有効な場合にtrue,無効な場合にfalseを返します。 284 */ 285 bool IsEnableZeroDrift() const; 286 287 /*! 288 @brief ゼロ点ドリフトの補正の効き具合を取得します。 289 290 この値は補正処理の働き具合を示し、1に近づくほどそのときの角速度で安定していることを意味します。 291 292 @return 無効の場合は負の値が返ります。有効の場合はゼロ以上の値が返ります。この値は補正処理の働き具合を示します。 293 294 1に近づくほどそのときの角速度で安定していることを意味します。 295 296 また、ゼロが返される期間は補正処理は行われません。 297 */ 298 f32 GetZeroDriftEffect() const; 299 300 /*! 301 @brief ゼロ点ドリフトの補正モードを初期化します。 302 303 初期値は GYROSCOPE_ZERODRIFT_STANDARD に設定されます。 304 305 @return なし。 306 */ 307 void ResetZeroDriftMode(); 308 309 /*! 310 @brief ゼロ点ドリフトの補正モードを設定します。 311 312 設定した内容はすべての方向に対して適用されます。 313 314 GYROSCOPE_ZERODRIFT_LOOSE の場合、センサーの値がある程度変動していても安定しているとみなし 315 ゼロ点の値を修正しようとしますので、等速度運動時にも修正される場合があります。 316 317 そのような場合はより条件が厳しいモードに設定することで改善される場合があります。 318 319 デフォルトは GYROSCOPE_ZERODRIFT_STANDARD に設定されています。 320 321 @param[in] mode ゼロ点ドリフトの補正モード 322 @return なし。 323 */ 324 void SetZeroDriftMode(const ZeroDriftMode& mode); 325 326 /*! 327 @brief ゼロ点ドリフトの補正モードを取得します。 328 @param[out] mode 現在のゼロ点ドリフトの補正モードをコピーするバッファ。 329 @return なし。 330 */ 331 void GetZeroDriftMode(ZeroDriftMode& mode) const; 332 333 /*! 334 @} 335 */ 336 337 338 /*! 339 @name 加速度補正 340 @{ 341 */ 342 343 /*! 344 @brief 加速度補正を有効にします。 345 346 加速度補正はCTRの静止時に加速度センサの値を用いてジャイロセンサの姿勢計算を補正する機能です。 347 348 加速度補正が有効であるとき、ジャイロセンサと補正に使用する加速度センサの軸回転に関する設定が共通である必要があります。 349 350 詳細は nn::hid::GyroscopeReader::EnableAxisRotation( ) を参照してください。 351 352 @return なし。 353 */ 354 void EnableAccRevise(); 355 356 /*! 357 @brief 加速度補正を無効にします。 358 @return なし。 359 */ 360 void DisableAccRevise(); 361 362 /*! 363 @brief 加速度補正が有効になっているか調べます。 364 365 加速度補正は初期状態では有効となっています。 366 367 @return 有効な場合にtrue,無効な場合にfalseを返します。 368 */ 369 bool IsEnableAccRevise() const; 370 371 /*! 372 @brief 加速度補正処理の働き具合が返されます。 373 @return 加速度補正処理が無効の場合は常に0を返します。有効の場合は0以上の値が返ります。 374 375 この値は補正処理の働き具合を示し、1に近いほど @ref Read ・ @ref ReadLatest 関数で得られる GyroscopeStatus 構造体の direction の方向を加速度の方向に近づけるように補正がかかっています。 376 */ 377 f32 GetAccReviseEffect() const; 378 379 380 /*! 381 @brief 加速度補正の重みと有効範囲を設定します。 382 383 設定した内容はすべての方向に対して適用されます。 384 385 @param[in] revisePower 加速度補正の重み。0 から 1 の間の値を設定してください。値が大きいほど急激に補正がかかります。 386 @param[in] reviseRange 加速度補正の有効範囲。重力加速度を中心にこの範囲内の加速度センサの値を補正計算に使用します。 387 388 1.0f は重力加速度の大きさを意味します。 389 390 つまり、0.4f を指定した場合は 0.6f から 1.4f の範囲に収まる加速度センサの値を補正計算に使用します。 391 @return なし。 392 */ 393 void SetAccReviseParam(f32 revisePower, f32 reviseRange); 394 395 /*! 396 @brief 加速度補正の重みと有効範囲を取得します。 397 @param[out] revisePower 現在の加速度補正具合をコピーするバッファ。 398 @param[out] reviseRange 現在の加速度補正の有効半径をコピーするバッファ。 399 @return なし。 400 */ 401 void GetAccReviseParam(f32& revisePower, f32& reviseRange) const; 402 403 /*! 404 @brief 加速度補正の重みと有効範囲を初期化します。 405 406 初期値は加速度補正処理の重み(revisePower)が 0.030f、加速度補正の有効半径(reviseRange)が 0.400f となります。 407 408 @return なし。 409 */ 410 void ResetAccReviseParam(); 411 412 /*! 413 @} 414 */ 415 416 /*! 417 @name 軸回転 418 @{ 419 */ 420 421 /*! 422 @brief 軸回転を有効にします。 423 424 軸回転が有効なとき、nn::hid::CTR::GyroscopeReader::SetAxisRotationMatrix( ) で設定された回転行列使用し、サンプリングデータに回転変換処理を行った値が出力されるようになります。 425 426 この処理によって、CTR内にセンサが傾いて配置されているかのように扱うことができます。 427 428 軸回転を行い、かつ加速度補正も行う場合には、加速度センサの設定に注意する必要があります。<BR> 429 この場合には、参照している @ref AccelerometerReader の軸回転とジャイロセンサの軸回転の設定が共通でなければいけません。<BR> 430 デフォルトの @ref AccelerometerReader を使用している場合には nn::hid::CTR::GyroscopeReader::EnableAxisRotation( ), nn::hid::CTR::GyroscopeReader::DisableAxisRotation( ), 431 nn::hid::CTR::GyroscopeReader::SetAxisRotationMatrix( ), nn::hid::CTR::GyroscopeReader::ResetAxisRotationMatrix( ) の各関数コール時にSDK側でデフォルトの 432 @ref nn::hid::CTR::AccelerometerReaderの対応する関数をコールして設定を共通化しますが、コンストラクタで独自の@ref nn::hid::CTR::AccelerometerReaderインスタンスを 433 指定した場合には、これらの設定をアプリ側で揃える必要があります。<BR> 434 軸回転の設定が共通でない場合、加速度補正が不適切に働く可能性がありますのでご注意ください。<BR> 435 436 本設定は初期値では無効になっています。 437 */ 438 void EnableAxisRotation(); 439 440 /*! 441 @brief 軸回転を無効にします。 442 443 本設定は初期値では無効になっています。 444 */ 445 void DisableAxisRotation(); 446 447 /*! 448 @brief 軸回転が有効か無効か調べます。 449 @return 軸回転が有効であればtrue,無効であればfalseを返します。 450 */ 451 bool IsEnableAxisRotation(); 452 453 /*! 454 @brief 軸回転で使用する回転行列を設定します。 455 */ 456 void SetAxisRotationMatrix(nn::math::MTX34 mtx); 457 458 /*! 459 @brief 軸回転で使用する回転行列を取得します。 460 461 @return 設定されている回転行列 462 */ 463 nn::math::MTX34 GetAxisRotationMatrix(); 464 465 /*! 466 @brief 軸回転で使用する回転行列を初期化します。 467 この時回転行列は nn::math::MTX34 の単位行列に設定され、これは軸回転が無効な場合と同等です。 468 */ 469 void ResetAxisRotationMatrix(); 470 471 /*! 472 @} 473 */ 474 475 private : 476 477 void ReadLocal(GyroscopeStatus* pBufs, s32* pReadLen, s32 bufLen); 478 void GetZeroDriftParam(f32& radius, s32& count, f32& power) const; 479 void SetZeroDriftParam(f32 radius, s32 count, f32 power); 480 f32 ReviseDirection_Acceleration(Direction& rev_dir, const nn::math::VEC3& acc); 481 void CalculateGyroscopeAxisStatus( 482 f32 *destSpeed, 483 s32 *nearSamplingNum, 484 f32 *zeroOffset, 485 s32 srcSpeed, 486 f32 speedScale, 487 s32* oldValueArray); 488 void CalculateDirection(); 489 void InitializeCalibrationData(); 490 491 private : 492 /* ドリフト修正カウントの最大数*/ 493 static const u32 GYROSCOPE_DRIFT_COUNT_MAX = 256; //2のn乗であること 494 495 496 private : 497 static const s32 GYROSCOPE_LOCAL_BUFFER_SIZE = 32; 498 s32 m_GyroscopeLocalBufferSize; 499 GyroscopeStatus m_GyroscopeStatusLocalBuffer[GYROSCOPE_LOCAL_BUFFER_SIZE]; 500 bool m_IsFirstRead; 501 ZeroDriftMode m_ZeroDriftMode; 502 NN_PADDING2; 503 504 AccelerometerReader m_DefaultAccelerometerReader; 505 506 GyroscopeStatus m_CurrentStatus; 507 AccelerometerReader* m_pAccelerometerReader; 508 509 nn::math::VEC3 m_SpeedOld; 510 nn::math::VEC3 m_SpeedVector; 511 nn::math::VEC3 m_SpeedScale; 512 f32 m_DirectionMagnification; // 姿勢計算時の倍率 513 514 f32 m_Period; // 計算用係数 515 f32 m_FreqDegree; // 計算用係数 516 f32 m_FreqRadian; // 計算用係数 517 518 bool m_EnableZeroPlay; // ゼロ点に遊びを設けるか 519 bool m_EnableZeroDrift; // ゼロ点自動補正するか 520 bool m_EnableAccRevise; // 加速度で姿勢補正するか 521 bool m_EnableRotate; 522 523 f32 m_ZeroPlayRadius; // ゼロ点遊び半径 (1 = 360deg/sec) 524 f32 m_ZeroDriftRadius; // ドリフトカウント許容半径 (1 = 360deg/sec) 525 s32 m_ZeroDriftCount; // ドリフト修正カウント 526 f32 m_ZeroDriftPower; // ドリフト修正パワー 527 f32 m_AccRevisePower; // 加速度補正力 528 f32 m_AccReviseRange; // 加速度補正有効半径 529 530 f32 m_ZeroPlayEffect; // 遊び円の内側具合 0:外側 ~ 1:中心 531 f32 m_ZeroDriftEffect; // ドリフト修正カウントの続き具合 (0~1) 532 f32 m_AccRevEffect; // 加速度補正がどれくらいかかっているか 533 534 nn::math::VEC3 m_CalibrationZero; // キャリブレーション値 535 f64 m_CalibrationScale[3]; // キャリブレーション値 536 537 nn::math::VEC3 m_CountZero; // ゼロ点を示すカウント値 538 s32 m_CountIdx; // 最新が格納されているバッファインデクス 539 s32 m_CountT[3][GYROSCOPE_DRIFT_COUNT_MAX]; // XYZハードウェア値 540 f32 m_DpsPitchMagnification; // pitch方向の角速度計算時の倍率 541 f32 m_DpsYawMagnification; // yaw方向の角速度計算時の倍率 542 f32 m_DpsRollMagnification; // roll方向の角速度計算時の倍率 543 NN_PADDING4; 544 545 /*from Low*/ 546 Gyroscope& m_Gyroscope; 547 s32 m_IndexOfRead; 548 s64 m_TickOfRead; 549 550 /*rotate axis*/ 551 nn::math::MTX34 m_RotateMtx; 552 553 }; 554 555 } // namespace CTR { 556 } // namespace hid { 557 } // namespace nn { 558 559 #endif // #ifndef NN_HID_CTR_GYROSCOPEREADER_H_ 560