diff --git a/navipy/database/__init__.py b/navipy/database/__init__.py index fc671ea4cc4f7d1be1f839fc0232df597a90e7e3..91d1d7783ffddaa6e6bf4b5b3b7c2a5f9d6fbab7 100644 --- a/navipy/database/__init__.py +++ b/navipy/database/__init__.py @@ -9,7 +9,7 @@ import sqlite3 import io from navipy.scene import is_numeric_array, check_scene import navipy.maths.constants as mconst -from navipy.tools.trajectory import Trajectory +from navipy.trajectories import Trajectory from navipy.scene import __spherical_indeces__ import logging diff --git a/navipy/trajectories/__init__.py b/navipy/trajectories/__init__.py index 17ce2196e96d1ce8cf0abc53d280957bd8e16b8e..217636e823151be50f0b66169bcf1fb58e3c0593 100644 --- a/navipy/trajectories/__init__.py +++ b/navipy/trajectories/__init__.py @@ -67,11 +67,15 @@ class Trajectory(pd.DataFrame): @rotation_mode.setter def rotation_mode(self, rotation_mode): + """Convert current rotation_mode to a different one + + :param rotation_mode: the new rotation mode to be assigned + """ oldrotmod = self.rotation_mode neworient = pd.DataFrame(index=self.index, columns=self.__build_columns(rotation_mode), dtype=float) - neworient.drop(inpalce=True, labels='location', level=0, axis=1) + neworient.drop(inplace=True, labels='location', level=0, axis=1) for index_i, row in self.iterrows(): if rotation_mode == 'quaternion': orient = htq.from_euler(row.angle_0, @@ -79,15 +83,15 @@ class Trajectory(pd.DataFrame): row.angle_2, axes=oldrotmod) else: - m = hte.matrix(ai=row.loc[(self.rotation_mode, 'angle_0')], - aj=row.loc[(self.rotation_mode, 'angle_1')], - ak=row.loc[(self.rotation_mode, 'angle_2')], + m = hte.matrix(ai=row.loc[(self.rotation_mode, 'alpha_0')], + aj=row.loc[(self.rotation_mode, 'alpha_1')], + ak=row.loc[(self.rotation_mode, 'alpha_2')], axes=oldrotmod) orient = hte.from_matrix(m, axes=rotation_mode) - neworient.loc[index_i, rotation_mode] = orient + neworient.loc[index_i, rotation_mode] = orient self.drop(inplace=True, labels=oldrotmod, level=0, axis=1) for col in neworient.columns: - self[(rotation_mode, col)] = neworient.loc[:, col] + self[col] = neworient.loc[:, col] self.__rotconv = rotation_mode def facing_direction(self): @@ -433,15 +437,29 @@ class Trajectory(pd.DataFrame): def world2body(self, markers): """ Transform markers in world coordinate to body coordinate """ + if not isinstance(markers, pd.Series): + msg = 'markers should be of type pd.Series and not' + msg += ' {}'.format(type(markers)) + raise TypeError(msg) + if not isinstance(markers.index, pd.MultiIndex): + msg = 'markers should have a multiIndex index \n' + msg += ' (i,"x"), (i,"y"),(i,"z")\n' + msg += 'here i is the index of the marker' + raise TypeError(msg) transformed_markers = pd.DataFrame(index=self.index, columns=markers.index, dtype=float) + # Looping through each time point along the trajectory + # to get the homogeneous transformation from the position orientation + # and then apply the transformed to the marker position for index_i, row in self.iterrows(): angles = row.loc[self.rotation_mode].values translate = row.loc['location'].values trans_mat = htf.compose_matrix(angles=angles, translate=translate, axes=self.rotation_mode) + # More than one marker may be transformed + # The marker are assume to be a multiIndex dataframe for marki in markers.index.levels[0]: markpos = [markers.loc[marki, 'x'], markers.loc[marki, 'y'], diff --git a/navipy/trajectories/test_trajectory.py b/navipy/trajectories/test_trajectory.py index 57ffa76ab01229754f2e7023beb94163c724ff73..d1fd5923504c4d08c88bb2fa17cebe7c27074726 100644 --- a/navipy/trajectories/test_trajectory.py +++ b/navipy/trajectories/test_trajectory.py @@ -19,25 +19,30 @@ class TestTrajectoryTransform(unittest.TestCase): markers.loc[(2, 'x')] = np.cos(np.pi / 3) markers.index.name = None # Create a random trajectory - trajectory = Trajectory(data=np.nan, - index=np.arange(10), - rotation_mode='sxyz', - sampling_rate=100) - traj_test = Trajectory(data=np.nan, - index=np.arange(10), - rotation_mode='sxyz', - sampling_rate=100) - trajectory.loc[:, 'position'] = \ - 100 * (np.random.rand(trajectory.shape[0], 3) - 0.5) - trajectory.loc[:, trajectory.rotation_mode] = \ - 2 * np.pi * (np.random.rand(trajectory.shape[0], 3) - 0.5) - col = (trajectory.rotation_mode, 'angle_1') + trajectory = Trajectory(indeces=np.arange(10), + rotconv='sxyz') + trajectory.x = 100 * (np.random.rand(trajectory.shape[0]) - 0.5) + trajectory.y = 100 * (np.random.rand(trajectory.shape[0]) - 0.5) + trajectory.z = 100 * (np.random.rand(trajectory.shape[0]) - 0.5) + trajectory.alpha_0 = 2 * np.pi * \ + (np.random.rand(trajectory.shape[0]) - 0.5) + trajectory.alpha_1 = 2 * np.pi * \ + (np.random.rand(trajectory.shape[0]) - 0.5) + trajectory.alpha_2 = 2 * np.pi * \ + (np.random.rand(trajectory.shape[0]) - 0.5) + # Create test trajectory + traj_test = Trajectory(indeces=np.arange(10), + rotconv='sxyz') + # Devide by two the second anle, because of gimbal lock + col = (trajectory.rotation_mode, 'alpha_1') trajectory.loc[:, col] = trajectory.loc[:, col] / 2 + print(trajectory) # forward for euler_axes in list(htconst._AXES2TUPLE.keys()): trajectory.rotation_mode = euler_axes traj_test.rotation_mode = euler_axes transformed_markers = trajectory.world2body(markers) + print(transformed_markers) # reverse for triangle_mode in ['x-axis=median-from-0', 'y-axis=1-2']: