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