diff --git a/alpha-lab/imu-transformations/imu_heading_visualization.ipynb b/alpha-lab/imu-transformations/imu_heading_visualization.ipynb index d8eb6cf9..e3505cc8 100644 --- a/alpha-lab/imu-transformations/imu_heading_visualization.ipynb +++ b/alpha-lab/imu-transformations/imu_heading_visualization.ipynb @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -26,7 +26,10 @@ "def transform_imu_to_world(imu_coordinates, imu_quaternions):\n", " # This array contains a timeseries of transformation matrices,\n", " # as calculated from the IMU's timeseries of quaternions values.\n", - " imu_to_world_matrices = R.from_quat(imu_quaternions).as_matrix()\n", + " imu_to_world_matrices = R.from_quat(\n", + " imu_quaternions,\n", + " scalar_first=True,\n", + " ).as_matrix()\n", "\n", " if np.ndim(imu_coordinates) == 1:\n", " return imu_to_world_matrices @ imu_coordinates\n", @@ -123,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -157,10 +160,10 @@ "# and the video render.\n", "quaternions_resampled = np.array(\n", " [\n", + " np.interp(relative_demo_video_ts, imu[\"relative ts [s]\"], imu[\"quaternion w\"]),\n", " np.interp(relative_demo_video_ts, imu[\"relative ts [s]\"], imu[\"quaternion x\"]),\n", " np.interp(relative_demo_video_ts, imu[\"relative ts [s]\"], imu[\"quaternion y\"]),\n", " np.interp(relative_demo_video_ts, imu[\"relative ts [s]\"], imu[\"quaternion z\"]),\n", - " np.interp(relative_demo_video_ts, imu[\"relative ts [s]\"], imu[\"quaternion w\"]),\n", " ]\n", ").T\n", "\n", diff --git a/alpha-lab/imu-transformations/index.md b/alpha-lab/imu-transformations/index.md index 69eb5493..1d29a7e9 100644 --- a/alpha-lab/imu-transformations/index.md +++ b/alpha-lab/imu-transformations/index.md @@ -42,8 +42,11 @@ from scipy.spatial.transform import Rotation as R def transform_imu_to_world(imu_coordinates, imu_quaternions): # This array contains a timeseries of transformation matrices, # as calculated from the IMU's timeseries of quaternions values. - imu_to_world_matrices = R.from_quat(imu_quaternions).as_matrix() - + imu_to_world_matrices = R.from_quat( + imu_quaternions, + scalar_first=True, + ).as_matrix() + if np.ndim(imu_coordinates) == 1: return imu_to_world_matrices @ imu_coordinates else: @@ -210,13 +213,13 @@ Using the transformations introduced above, we can transform various data into c Converting data into spherical world coordinates makes this obvious. When wearing Neon, an elevation and azimuth of 0 degrees corresponds to a neutral orientation: i.e., aimed at magnetic North and parallel to the horizon. A positive elevation corresponds to looking upwards, and a negative elevation corresponds to looking downwards. -The [Euler angles from the IMU](https://docs.pupil-labs.com/neon/data-collection/data-streams/#euler-angles) are already in a compatible format. For gaze data in world coordinates, the `cartesian_to_spherical_world` function below will do the necessary transformation. +The [Euler angles from the IMU](https://docs.pupil-labs.com/neon/data-collection/data-streams/#euler-angles) are already in a compatible format. For gaze data in world coordinates, the `cartesian_to_spherical_world` function below will do the necessary transformation. ```python def cartesian_to_spherical_world(world_points_3d): """ Convert points in 3D Cartesian world coordinates to spherical coordinates. - + For elevation: - Neutral orientation = 0 (i.e., parallel with horizon) - Upwards is positive