예제 #1
0
PSMove_3AxisVector
psmove_orientation_get_gyroscope_vector(PSMoveOrientation *orientation_state, enum PSMove_Frame frame)
{
	psmove_return_val_if_fail(orientation_state != NULL, *k_psmove_vector_zero);

	float omega_x, omega_y, omega_z;
	psmove_get_gyroscope_frame(orientation_state->move, frame, &omega_x, &omega_y, &omega_z);

	// Apply the "identity pose" transform
	PSMove_3AxisVector omega = psmove_3axisvector_xyz(omega_x, omega_y, omega_z);
	omega= psmove_3axisvector_apply_transform(&omega, &orientation_state->sensor_transform);

	return omega;
}
예제 #2
0
        void run()
        {
            PSMove *move;

            /* 6 values = ax, ay, az, gx, gy, gz (accel + gyro) */
            float gx, gy, gz;

            int i = 0;
            qreal rate = 1.;

            assert((move = psmove_connect()) != NULL);
            assert(psmove_connection_type(move) == Conn_Bluetooth);

            assert(psmove_has_calibration(move));

            while (true) {
                if (psmove_poll(move)) {
                    psmove_get_gyroscope_frame(move, Frame_SecondHalf, &gx, &gy, &gz);

                    /**
                     * Playback rate is calculated based on the RPM of the
                     * controller on the Z axis and the normal
                     * playback rate of the turntable (see above).
                     **/
                    rate = RAD_PER_S_TO_RPM(gz) / TURNTABLE_RPM;

                    /* Rate-limiting the updates of the playback rate */
                    if (i % READ_FRAME_UPDATE_RATE == 0) {
                        /**
                         * On Linux, the rate must not be negative. It might be
                         * possible that on Mac OS X or Windows, the rate can
                         * also be negative (depends on the backend).
                         **/
                        if (rate > 0 && rate != player->playbackRate()) {
                            qint64 pos = player->position();
                            player->setPlaybackRate(rate);
                            player->setPosition(pos);
                        }
                    }

                    i++;
                }
            }

            psmove_disconnect(move);
        }
예제 #3
0
int
main(int argc, char* argv[])
{
    PSMove *move;

	if (!psmove_init(PSMOVE_CURRENT_VERSION)) {
		fprintf(stderr, "PS Move API init failed (wrong version?)\n");
		exit(1);
	}

    move = psmove_connect();

    if (move == NULL) {
        fprintf(stderr, "Could not connect to controller.\n");
        return EXIT_FAILURE;
    }

    assert(psmove_has_calibration(move));

    if (psmove_connection_type(move) == Conn_Bluetooth) {
        float ax, ay, az, gx, gy, gz;

        while (1) {
            int res = psmove_poll(move);
            if (res) {
                psmove_get_accelerometer_frame(move, Frame_SecondHalf,
                        &ax, &ay, &az);
                psmove_get_gyroscope_frame(move, Frame_SecondHalf,
                        &gx, &gy, &gz);

                printf("A: %5.2f %5.2f %5.2f ", ax, ay, az);
                printf("G: %6.2f %6.2f %6.2f ", gx, gy, gz);
                printf("\n");
            }
        }
    }

    psmove_disconnect(move);
	psmove_shutdown();

    return EXIT_SUCCESS;
}
예제 #4
0
void
PSMoveAPI::update()
{
    for (auto &c: controllers) {
        if (c->connected && !c->sent_connect) {
            if (receiver->connect != nullptr) {
                // Send initial connect event
                receiver->connect(&c->controller, user_data);
            }
            c->sent_connect = true;
        }

        if (!c->connected && !c->sent_disconnect) {
            if (receiver->disconnect != nullptr) {
                // Send disconnect event
                receiver->disconnect(&c->controller, user_data);
            }
            c->sent_disconnect = true;
        }

        if (!c->connected) {
            // Done with this controller (TODO: Can we check reconnect?)
            continue;
        }

        auto read_move = c->read_move();
        if (read_move == nullptr) {
            // We don't have a handle that supports reading (USB-only connection);
            // we call update exactly once (no new data will be reported), so that
            // the update method can change the LED and rumble values
            if (receiver->update != nullptr) {
                receiver->update(&c->controller, user_data);
            }
        } else {
            while (psmove_poll(read_move)) {
                if (receiver->update != nullptr) {
                    int previous = c->controller.buttons;
                    c->controller.buttons = psmove_get_buttons(read_move);
                    c->controller.pressed = c->controller.buttons & ~previous;
                    c->controller.released = previous & ~c->controller.buttons;
                    c->controller.trigger = float(psmove_get_trigger(read_move)) / 255.f;

                    psmove_get_accelerometer_frame(read_move, Frame_SecondHalf,
                            &c->controller.accelerometer.x,
                            &c->controller.accelerometer.y,
                            &c->controller.accelerometer.z);
                    psmove_get_gyroscope_frame(read_move, Frame_SecondHalf,
                            &c->controller.gyroscope.x,
                            &c->controller.gyroscope.y,
                            &c->controller.gyroscope.z);
                    psmove_get_magnetometer_vector(read_move,
                            &c->controller.magnetometer.x,
                            &c->controller.magnetometer.y,
                            &c->controller.magnetometer.z);
                    c->controller.battery = psmove_get_battery(read_move);

                    receiver->update(&c->controller, user_data);
                }
            }
        }

        auto write_move = c->write_move();
        if (write_move != nullptr) {
            psmove_set_leds(write_move,
                    uint32_t(255 * c->controller.color.r),
                    uint32_t(255 * c->controller.color.g),
                    uint32_t(255 * c->controller.color.b));
            psmove_set_rumble(write_move, uint32_t(255 * c->controller.rumble));
            if (psmove_update_leds(write_move) == Update_Failed) {
                if (read_move != nullptr && write_move != read_move) {
                    // Disconnected from USB, but we read from Bluetooth, so we
                    // can just give up the USB connection and use Bluetooth
                    psmove_disconnect(c->move_usb), c->move_usb = nullptr;
                    // Now that USB is gone, clear the controller's USB flag
                    c->controller.usb = 0;
                } else {
                    c->connected = false;
                }
            }
        }
    }
}
예제 #5
0
void
psmove_orientation_update(PSMoveOrientation *orientation)
{
    psmove_return_if_fail(orientation != NULL);

    int frame;

    long now = psmove_util_get_ticks();
    if (now - orientation->sample_freq_measure_start >= 1000) {
        float measured = ((float)orientation->sample_freq_measure_count) /
            ((float)(now-orientation->sample_freq_measure_start))*1000.;
        psmove_DEBUG("Measured sample_freq: %f\n", measured);

        orientation->sample_freq = measured;
        orientation->sample_freq_measure_start = now;
        orientation->sample_freq_measure_count = 0;
    }

    /* We get 2 measurements per call to psmove_poll() */
    orientation->sample_freq_measure_count += 2;

    psmove_get_magnetometer_vector(orientation->move,
            &orientation->output[6],
            &orientation->output[7],
            &orientation->output[8]);

    float q0 = orientation->quaternion[0];
    float q1 = orientation->quaternion[1];
    float q2 = orientation->quaternion[2];
    float q3 = orientation->quaternion[3];

    for (frame=0; frame<2; frame++) {
        psmove_get_accelerometer_frame(orientation->move, frame,
                &orientation->output[0],
                &orientation->output[1],
                &orientation->output[2]);

        psmove_get_gyroscope_frame(orientation->move, frame,
                &orientation->output[3],
                &orientation->output[4],
                &orientation->output[5]);

#if defined(PSMOVE_WITH_MADGWICK_AHRS)
        MadgwickAHRSupdate(orientation->quaternion,
			   orientation->sample_freq,
			   0.5f,

                /* Gyroscope */
                orientation->output[3],
                orientation->output[5],
                -orientation->output[4],

                /* Accelerometer */
                orientation->output[0],
                orientation->output[2],
                -orientation->output[1],

                /* Magnetometer */
                orientation->output[6],
                orientation->output[8],
                orientation->output[7]
        );
#else
        psmove_DEBUG("Built without Madgwick AHRS - no orientation tracking");
        return;
#endif

        if (isnan(orientation->quaternion[0]) ||
            isnan(orientation->quaternion[1]) ||
            isnan(orientation->quaternion[2]) ||
            isnan(orientation->quaternion[3])) {
            psmove_DEBUG("Orientation is NaN!");
            orientation->quaternion[0] = q0;
            orientation->quaternion[1] = q1;
            orientation->quaternion[2] = q2;
            orientation->quaternion[3] = q3;
        }
    }
}