Using BPS sensors

Not all sensor types are available on all devices. You can determine what sensors are available on a device by using the sensor_is_supported() function. You should verify that the sensor is supported on the device that your app is running on before trying to use the sensor. The following table shows the supported sensors with their corresponding sensor_type_t types.

Sensor Sensor Type (BPS)
Accelerometer SENSOR_TYPE_ACCELEROMETER
Azimuth SENSOR_TYPE_AZIMUTH_PITCH_ROLL
Gravity SENSOR_TYPE_GRAVITY
Gyroscope SENSOR_TYPE_GYROSCOPE
Holster sensor The holster sensor can be accessed in BPS using the functions defined by holster.h
Light sensor SENSOR_TYPE_LIGHT
Linear acceleration SENSOR_TYPE_LINEAR_ACCEL
Magnetometer SENSOR_TYPE_MAGNETOMETER
Orientation sensor SENSOR_TYPE_ORIENTATION
Azimuth, pitch, and roll SENSOR_TYPE_AZIMUTH_PITCH_ROLL
Proximity sensor SENSOR_TYPE_PROXIMITY
Rotation sensor SENSOR_TYPE_ROTATION_MATRIX

Prerequisites

To use BPS sensor APIs in your app, include the following files:

#include <bps/bps.h>
#include <bps/sensor.h>

The World Magnetic Model library's header file, wmm/wmm.h, contains magnetic field definitions and a function that you can use to retrieve the geomagnetic field of the device. You can use the geomagnetic field of the device to adjust sensor values that are affected by the Earth's magnetic field. For more information, see World Magnetic Model Library.

You must also add BlackBerry Platform Services (libbps) to your project.

Workflow

Your app must perform the following general steps to use BPS to access any of the sensor types defined by sensor_type_t:

  1. Initialize BPS by calling bps_initialize().
  2. Check for sensor existence by calling sensor_is_supported() with the appropriate sensor_type_t.
  3. Optionally, configure the sensor by calling sensor_set_rate() and sensor_set_skip_duplicates(), depending on your app's needs.
  4. Start receiving sensor events by calling sensor_request_events().
  5. In your app's main loop, perform the following:
    1. Get the next BPS event by calling bps_get_event().
    2. Determine whether the BPS event is a sensor reading event. If it is a sensor reading event, determine which type of sensor reading has occurred.
    3. Get the sensor data from the event by calling the appropriate sensor_event_get_*() function.
    4. Apply the sensor data to your app.
    5. Continue getting and processing BPS events until app exit occurs.
  6. Free the resources used by BPS by calling bps_shutdown().

Remapping sensor data based on device orientation

If you are developing an app using the BPS Sensor APIs and your app's UI depends on sensor readings, you might need to remap the data to match the device's orientation. Your app should check for NAVIGATOR_ORIENTATION events, which are generated when the device rotation is detected. When your app gets this event, you can get the device orientation angle by calling navigator_event_get_orientation_angle(). You should check for NAVIGATOR_ORIENTATION events instead of SENSOR_ORIENTATION_READING events because the navigator controls whether the screen rotates. You might want to remap the sensor data when the screen coordinates change.

The following code sample illustrates how to get the device orientation angle after your app gets a NAVIGATOR_ORIENTATION event:

Not applicable

Not applicable

/* Get the domain of the BPS event */
if ((bps_event_get_domain(event) == navigator_get_domain())) {
    switch (bps_event_get_code(event)) {
    case NAVIGATOR_ORIENTATION:
        int angle;
        /* Get the current device orientation  */
        /* angle with respect to gravity       */
         angle = navigator_event_get_orientation_angle(event);
        break;
    }
}

Now, you can remap the sensor coordinates to the device orientation angle either manually or by calling sensor_remap_coordinates().

This following code sample illustrates how you can manually remap sensor data that is returned by sensor_event_get_apr() and sensor_event_get_xyz() to match the device orientation angle:

sensor_event_get_xyz(event, &x, &y, &z);

if (angle == 90) {
    x_remapped = -y;
    y_remapped = x;
} else if (angle == 180) {
    x_remapped = -x;
    y_remapped = -y;
} else if (angle == 270) {
    x_remapped = y;
    y_remapped = -x;
}

This following code sample illustrates how you can manually remap sensor data that is returned by sensor_event_get_rotation_matrix():

/* Get rotation matrix sensor data from an event */
sensor_event_get_rotation_matrix(event, &rotation_matrix);

if (angle == 0) { 
    /* Don't rotate, because device orientation is  */
    /* the same as the sensor coordinate system */
} else {

    /* The standard rotation matrix */
    float R[] = {
        cos(angle*M_PI/180), -sin(angle*M_PI/180),
        sin(angle*M_PI/180), cos(angle*M_PI/180)
    };
    
    /* i is the row of the matrix */
    /* j is the column of the matrix */
    /* k is an index into the rotation matrix R[] */
    int i, j, k;
    sensor_rotation_matrix_t remapped_data;    
    
    for(i = 0; i < 3; i++){
        for(j = 0; j < 2; j++){ 
            /* Last column of matrix (column 2) stays unchanged */
            remapped_data.matrix[i*3+j] = 0;
            for(k = 0; k < 2; k++){ 
                /* Rotation matrix is zero in bottom row (row 2) */
                remapped_data.matrix[i*3+j] += 
                rotation_matrix.matrix[i*3+k] * R[k*2+j];
            }
        }
        /* The third column remains untouched after the remapping */
        remapped_data.matrix[i*3+2] = rotation_matrix.matrix[i*3+2];
    }

The following code sample illustrates how you can use sensor_remap_coordinates() in your app:

/* Receive a BPS event */
if ((bps_event_get_domain(event) == navigator_get_domain())) {
    switch (bps_event_get_code(event)) {
    case NAVIGATOR_ORIENTATION:
        int angle;
        /* Get the current device orientation angle */
        angle = navigator_event_get_orientation_angle(event);

        /* Remap the sensor data to match the device orientation */
        /* This remaps data that is returned by:       */
        /*     - sensor_event_get_apr()                */
        /*     - sensor_event_get_rotation_matrix()    */
        /*     - sensor_event_get_rotation_xyz()       */

        sensor_remap_coordinates(angle);        
        break;
    }
}

Last modified: 2015-05-07



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus