ZED SDK のTransform型 (同次変換行列)

# 想定する読者
stereolabsのzed2, zed mini, zed x などのステレオカメラの利用者
いまどきのステレオカメラは何ができるのかを知りたい人

# 前提
ZED SDK 4.0
Ubuntu 20.04
ZED2i
Python 版のAPI

## pose を取得するコードの一部
```.py:
  sensors_data = sl.SensorsData()
  zed.get_sensors_data(sensors_data, sl.TIME_REFERENCE.IMAGE) # Retrieve only frame synchronized data
  imu_data = sensors_data.get_imu_data()
  pose = imu_data.get_pose()
```

このようにして得られたposeはpyzed.sl.Transform 型になります。

#  Transform 型

```.py:
class Transform(Matrix4f)
 |  Method resolution order:
 |      Transform
 |      Matrix4f
 |      builtins.object
 |  
```
Matrix4f を継承しています。

- 座標変換の行列は4x4の行列で表されます。
- そのなかには、3x3の回転行列と、大きさが３の並行移動のベクトルとを含んでいます。
- pose.get_rotation_matrix() が3x3の回転行列を返します。
- pose.get_translation() は、平行移動を示すTranslation型を返します。

## Transform型のget_* メソッドの実行例

```.py:
pose.get_euler_angles()=array([ 0.02268377, -0.00167874,  0.07652272])
pose.get_infos()='FEF4870\n0.997072 -0.076466 0.000003 -0.000000\n0.076447 0.996817 -0.022619 0.000000\n0.001726 0.022553 0.999744 -0.000000\n0.000000 0.000000 0.000000 1.000000\n'
pose.get_orientation()=<pyzed.sl.Orientation object at 0xffffb635c350>
pose.get_rotation_matrix()=1209C4A0
0.997072 -0.076466 0.000003
0.076447 0.996817 -0.022619
0.001726 0.022553 0.999744

pose.get_rotation_vector()=array([ 0.02260999, -0.00086241,  0.07653794])
pose.get_translation()=<pyzed.sl.Translation object at 0xffffb635c350>
```

## np.ndarray 型の変換行列を取得するには
`pose.m`

`m` というデータメンバーにアクセスします。



## 各メソッドの説明
`help(sl.Transform)` の実行結果から抜粋

```.py:
 |  get_euler_angles(self, radian=True) -> 'np.array[float]'
 |      Transform.get_euler_angles(self, radian=True) -> np.array[float]
 |  
 |  get_orientation(self) -> 'Orientation'
 |      Transform.get_orientation(self) -> Orientation
 |  
 |  get_rotation_matrix(self) -> 'Rotation'
 |      Transform.get_rotation_matrix(self) -> Rotation
 |  
 |  get_rotation_vector(self) -> 'np.array[float]'
 |      Transform.get_rotation_vector(self) -> np.array[float]
 |  
 |  get_translation(self) -> 'Translation'
 |      Transform.get_translation(self) -> Translation
 |  
 |  init_matrix(self, matrix: 'Matrix4f') -> 'None'
 |      Transform.init_matrix(self, Matrix4f matrix: Matrix4f) -> None
 |  
 |  init_orientation_translation(self, orient: 'Orientation', tr: 'Translation') -> 'None'
 |      Transform.init_orientation_translation(self, Orientation orient: Orientation, Translation tr: Translation) -> None
 |  
 |  init_rotation_translation(self, rot: 'Rotation', tr: 'Translation') -> 'None'
 |      Transform.init_rotation_translation(self, Rotation rot: Rotation, Translation tr: Translation) -> None
 |  
 |  init_transform(self, motion: 'Transform') -> 'None'
 |      Transform.init_transform(self, Transform motion: Transform) -> None
 |  
 |  set_euler_angles(self, input0: 'float', input1: 'float', input2: 'float', radian=True) -> 'None'
 |      Transform.set_euler_angles(self, double input0: float, double input1: float, double input2: float, radian=True) -> None
 |  
 |  set_orientation(self, py_orientation: 'Orientation') -> 'None'
 |      Transform.set_orientation(self, Orientation py_orientation: Orientation) -> None
 |  
 |  set_rotation_matrix(self, py_rotation: 'Rotation') -> 'None'
 |      Transform.set_rotation_matrix(self, Rotation py_rotation: Rotation) -> None
 |  
 |  set_rotation_vector(self, input0: 'float', input1: 'float', input2: 'float') -> 'None'
 |      Transform.set_rotation_vector(self, double input0: float, double input1: float, double input2: float) -> None
 |  
 |  set_translation(self, py_translation: 'Translation') -> 'None'
 |      Transform.set_translation(self, Translation py_translation: Translation) -> None
 |  

```


## Translation 型
並行移動を示す３次元ベクトル

```.py:
 |  dot_translation(tr1: 'Translation', tr2: 'Translation') -> 'float'
 |      Translation.dot_translation(tr1: Translation, Translation tr2: Translation) -> float
 |  
 |  get(self) -> 'np.array[float]'
 |      Translation.get(self) -> np.array[float]
 |  
 |  init_translation(self, tr: 'Translation') -> 'None'
 |      Translation.init_translation(self, Translation tr: Translation) -> None
 |  
 |  init_vector(self, t1: 'float', t2: 'float', t3: 'float') -> 'None'
 |      Translation.init_vector(self, double t1: float, double t2: float, double t3: float) -> None
 |  
 |  normalize(self) -> 'None'
 |      Translation.normalize(self) -> None
 |  
 |  normalize_translation(self, tr: 'Translation') -> 'Translation'
 |      Translation.normalize_translation(self, Translation tr: Translation) -> Translation
 |  
 |  size(self) -> 'int'
 |      Translation.size(self) -> int
 |  
```

## Transform 型について
同次変換行列(Homogeneous transformation matrix)のことです。
斉次変換行列とも呼ばれます。
空間の点を示すために(x, y, z, 1) という４次元のベクトルにすることで、変換処理を4x4の行列との積にしてしまう流儀です。
以下の説明は２次元での解説になりますが、概略をつかむには良さそうです。

[【初心者向け】 ロボット分野の同次変換行列(Homogeneous transformation matrix) 入門](https://qiita.com/ryosuke1212/items/0456ce07bcc933ca4534)

## 次に調べること
- ZED カメラにあるIMUを使って、鉛直方向を補正するように点群の座標の変換方法を調べること