1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     hid_AccelerometerReader.h
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  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: 26706 $
14  *---------------------------------------------------------------------------*/
15 
16 /*! @file
17     @brief      AccelerometerReader クラスを定義します。
18 
19 */
20 #ifndef NN_HID_CTR_HID_ACCELEROMETERREADER_H_
21 #define NN_HID_CTR_HID_ACCELEROMETERREADER_H_
22 
23 #include <nn/Handle.h>
24 #include <nn/Result.h>
25 #include <nn/types.h>
26 #include <nn/hid/CTR/hid_Result.h>
27 #include <nn/hid/CTR/hid_Api.h>
28 #include <nn/hid/CTR/hid_Accelerometer.h>
29 #include <nn/hid/CTR/hid_DeviceStatus.h>
30 #include <nn/util/util_SizedEnum.h>
31 #include <nn/util/util_NonCopyable.h>
32 #include <nn/math.h>
33 
34 namespace nn {
35 namespace hid {
36 namespace CTR {
37 /*!
38   @brief 加速度センサの取る最大の絶対値です。
39 
40   注意 ) 検討中のパラメータのため、将来変更します。
41 
42 */
43 const s16   MAX_OF_ACCELEROMETER_VALUE                      = 930;
44 
45 /*!
46   @brief 加速度センサの 1G あたりの 値です。
47 
48   注意 ) 検討中のパラメータのため、将来変更します。
49 
50 */
51 const s16   ACCELEROMETER_VALUE_PER_1G                      = 512;
52 const f32   ACCELERATION_SCALE_PER_1G                       = 1.f / ACCELEROMETER_VALUE_PER_1G;
53 
54 /*!
55   @brief 加速度センサの遊びの最大値です。
56 
57   注意 ) 検討中のパラメータのため、将来変更します。
58 
59 */
60 const s16   MAX_OF_ACCELEROMETER_PLAY                       = MAX_OF_ACCELEROMETER_VALUE * 2;
61 
62 const s16   ACCELEROMETER_SENSITIVITY_SCALE_SHIFT           = 7;
63 
64 /*!
65   @brief 加速度センサの検出感度の最大値です。
66 
67   注意 ) 検討中のパラメータのため、将来変更します。
68 
69 */
70 const s16   MAX_OF_ACCELEROMETER_SENSITIVITY                = 128; // 1 << ACCELEROMETER_SENSITIVITY_SCALE_SHIFT
71 
72 
73 /*!
74     @brief 加速度センサのサンプリングデータを読み込むクラスです。
75 
76         注意) 加速度センサのサンプリングは平均 10 msec 周期で行われます。
77 
78         加速度センサのサンプリングは、本クラスのインスタンスを生成した段階から行われるため、
79         サンプリングデータを読み込めるのは、インスタンス生成後 10 msec 経過した後になります。
80 
81         nn::hid::AccelerometerReader::EnableOffset( ) や nn::hid::AccelerometerReader::EnableAxisRotation( )を使用することで、加工した出力値を得ることができます。
82         加工によって、センサが傾いて配置されているような出力値を得たり、水平であるとみなしたい基準の状態を調整することができます。
83         詳細は各関数のリファレンスを参照してください。
84 
85         加速度センサの軸は以下のようになっています。<BR>
86         X+:十字ボタンの左方向<BR>
87         Y+:タッチパネルの実装面方向<BR>
88         Z+:十字ボタンの上方向<BR>
89 */
90 class AccelerometerReader : private nn::util::NonCopyable<AccelerometerReader>
91 {
92 public:
93     /*!
94     @brief          コンストラクタです。
95 
96                     インスタンスを生成する前に @ref nn::hid::CTR::Initialize( ) で初期化してください。
97 
98     */
99     AccelerometerReader(Accelerometer& accelerometer = GetAccelerometer( ));
100 
101     /*!
102     @brief          デストラクタです。
103 
104     */
105     ~AccelerometerReader( );
106     /*!
107       @brief        加速度センサのサンプリングデータを新しいものから順に読み込みます。以前に読み込んだデータは読み込まれません。
108 
109       @param[out]   pBufs       新しいものから順にサンプリングデータが読み込まれます。
110       @param[out]   pReadLen    読み込んだサンプリングデータの数です。
111       @param[in]    bufLen      pBufs に読み込めるサンプリングデータの数を指定します。
112       @return       なし。
113 
114     */
115     void Read(AccelerometerStatus* pBufs, s32* pReadLen, s32 bufLen);
116 
117     /*!
118       @brief        最新の加速度センサのサンプリングデータを読み込みます。 nn::hid::CTR::AccelerometerReader::Read( ) とちがい同じサンプリングデータを読み込むことが出来ます。
119 
120       内部では一つ前の ReadLatest( ) のサンプリングデータとの差を加速度の変位として検出感度を計算します。
121 
122       @param[out]   pBuf        サンプリングデータが読み込まれます。
123       @return       サンプリングデータの読み込み結果を返します。<BR>
124                       true ・・・ 読み込めました。<BR>
125                       false ・・・ 読み込めませんでした。(AccelerometerReaderのインスタンス生成後あるいはスリープ復帰後の最初のサンプリングが行われ次第、読み込めます。)
126 
127     */
128     bool ReadLatest(AccelerometerStatus* pBuf);
129 
130     /*!
131         @brief      サンプリング間の加速度変位の遊びと、検出感度の設定値を取得します。
132         @param[out] pPlay           現在設定されている遊びを読み込みます。
133         @param[out] pSensitivity    現在設定されている検出感度を読み込みます。
134         @return     なし。
135 
136     */
137     void GetSensitivity(s16* pPlay, s16* pSensitivity) const;
138 
139     /*!
140         @brief      サンプリング間の加速度変位の遊びと、検出感度の設定を行います。
141 
142                     デフォルトは、 play、sensitivity がそれぞれ  0、@ref nn::hid::CTR::MAX_OF_ACCELEROMETER_SENSITIVITY です。
143 
144         @param[in]  play            遊びです。 0 以上  @ref nn::hid::CTR::MAX_OF_ACCELEROMETER_PLAY 以下の数値を指定してください。
145         @param[in]  sensitivity     検出感度を表します。 0 ~ @ref nn::hid::CTR::MAX_OF_ACCELEROMETER_SENSITIVITY の範囲で指定します。 0 だと全く反応しなくなり、 @ref nn::hid::CTR::MAX_OF_ACCELEROMETER_SENSITIVITY ではデバイスから取得した値そのままに反応します。
146         @return     なし。
147 
148     */
149     void SetSensitivity(s16 play, s16 sensitivity);
150 
151     /*!
152       @brief        加速度センサのサンプリングデータを、加速度 (単位は G ) へ変換します。
153 
154       @param[out]   pAcceleration       加速度に変換されたデータが格納されます。
155       @param[in]    bufLen              pAcceleration に格納できる加速度データの数を指定します。
156       @param[in]    pSamplingData       変換前の加速度センサのサンプリングデータ
157       @return       なし。
158 
159     */
160     void ConvertToAcceleration(AccelerationFloat* pAcceleration, s32 bufLen, const AccelerometerStatus* pSamplingData);
161 
162     /*!
163       @brief        加速度センサの軸回転を有効にします。
164 
165                     軸回転が有効なとき、@ref SetRotationAxis( ) で設定された回転行列使用し、サンプリングデータに回転変換処理を行った値が出力されるようになります。
166 
167                     この処理によって、CTR内にセンサが傾いて配置されている様に扱うことができます。
168 
169                     オフセットと軸回転が両方とも有効の場合には、オフセット処理、回転処理の順に変換処理を行います。
170      */
171     void EnableAxisRotation();
172 
173 
174     /*!
175       @brief        加速度センサの軸回転を無効にします。
176      */
177     void DisableAxisRotation();
178 
179 
180     /*!
181       @brief        加速度センサの軸回転が有効か無効か調べます。
182 
183       @return       有効であればtrue,無効であればfalse
184     */
185     bool IsEnableAxisRotation();
186 
187 
188     /*!
189       @brief        加速度センサのサンプリングデータを軸回転するための回転行列を指定します。
190       @param[in]    mtx                 変換する回転行列
191      */
192     void SetAxisRotationMatrix(nn::math::MTX34 mtx);
193 
194     /*!
195       @brief        加速度センサのサンプリングデータを軸回転するために指定している回転行列を取得します。
196 
197       @return       設定されている回転行列
198      */
199     nn::math::MTX34 GetAxisRotationMatrix();
200 
201 
202     /*!
203       @brief        加速度センサのサンプリングデータを変換するための回転行列を初期化します。
204 
205                     この関数を呼び出すと、回転行列は @ref nn::math::MTX34 の単位行列に初期化されます。
206 
207                     これは軸回転が無効な場合と同等です。
208      */
209     void ResetAxisRotationMatrix();
210 
211     /*!
212       @brief        加速度センサのオフセットを有効にします。
213 
214                     オフセットが有効なとき、@ref SetOffset( ) や @ref SetOffsetFromBaseStatus( ) で設定されたオフセット値をサンプリングデータから引いて出力します。
215 
216                     オフセットと軸回転が両方とも有効の場合には、オフセット処理、回転処理の順に変換処理を行います。
217 
218                     初期値は有効になっています。
219      */
220 
221     void EnableOffset();
222 
223     /*!
224       @brief        加速度センサのオフセットを無効にします。
225 
226                     初期値は有効になっています。
227      */
228     void DisableOffset();
229 
230     /*!
231       @brief        加速度センサのオフセットが有効か無効か調べます。
232 
233       @return       有効であればtrue,無効であればfalse
234      */
235     bool IsEnableOffset();
236 
237 
238     /*!
239       @brief        加速度センサのオフセット値を設定します。
240 
241                     オフセットが有効なとき、ここで指定した加速度センサの値の時に水平となるようオフセットが引かれてサンプリングデータが出力されるようになります。
242 
243       @param[in]    baseAccelerometerStatus       水平状態とみなす加速度センサの値
244      */
245 
246     void SetOffsetFromBaseStatus(AccelerometerStatus baseAccelerometerStatus);
247 
248     /*!
249       @brief        加速度センサのオフセット値を指定します。
250 
251                     オフセットが有効なとき、指定した値がサンプリングデータから引かれて出力されるようになります。
252 
253                     初期値は全て 0 になっています。
254 
255       @param[in]    x      オフセット値のx成分
256       @param[in]    y      オフセット値のy成分
257       @param[in]    z      オフセット値のz成分
258      */
259     void SetOffset(s16 x, s16 y,s16 z);
260 
261     /*!
262       @brief        加速度センサのオフセット値を取得します。
263 
264       @param[out]   pX     オフセット値のx成分
265       @param[out]   pY     オフセット値のy成分
266       @param[out]   pZ     オフセット値のz成分
267      */
268     void GetOffset(s16* pX, s16* pY, s16*pZ);
269 
270     /*!
271       @brief        加速度センサのオフセット値を初期値に戻します。
272 
273                     この関数を呼びだすと、加速度センサのオフセット値は(0,0,0)となります。これはオフセットが無効な場合と同等です。
274      */
275     void ResetOffset();
276 
277 
278 
279 private:
280     void Transform(AccelerometerStatus* pAccStatus);
281 
282 protected:
283     Accelerometer&                              m_Accelerometer;
284     s16                                         m_Play;
285     s16                                         m_Sensitivity;
286 
287     AccelerometerStatus                         m_LatestCalculatedStatus;
288     AccelerometerStatus                         m_OffsetAccStatus;
289     NN_PADDING4;
290 
291     nn::math::MTX34                             m_RotateMtx;
292     bool                                        m_EnableOffset;
293     bool                                        m_EnableRotate;
294     NN_PADDING2;
295     s32                                         m_IndexOfRead;
296     s64                                         m_TickOfRead;
297 };
298 
299 
300 
301 // inline 実装
SetSensitivity(s16 play,s16 sensitivity)302 inline void AccelerometerReader::SetSensitivity(s16 play, s16 sensitivity)
303 {
304     NN_TASSERT_(0 <= play && MAX_OF_ACCELEROMETER_PLAY >= play && 0 <= sensitivity && MAX_OF_ACCELEROMETER_SENSITIVITY >= sensitivity);
305     m_Play = play;
306     m_Sensitivity = sensitivity;
307 }
308 
GetSensitivity(s16 * pPlay,s16 * pSensitivity)309 inline void AccelerometerReader::GetSensitivity(s16* pPlay, s16* pSensitivity) const
310 {
311     *pPlay = m_Play;
312     *pSensitivity = m_Sensitivity;
313 }
314 
315 } // namespace CTR {
316 } // namespace hid {
317 } // namespace nn {
318 
319 #endif  // #ifndef NN_HID_CTR_HID_ACCELEROMETERREADER_H_
320