forked from danieldugas/pymap2d
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pose2d.py
113 lines (98 loc) · 3.26 KB
/
pose2d.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import numpy as np
def Pose2D(tf_msg):
import tf
return np.array([tf_msg[0][0], tf_msg[0][1],
tf.transformations.euler_from_quaternion(tf_msg[1])[2]])
def posemsg_to_pose2d(posemsg):
import tf
quaternion = (
posemsg.orientation.x,
posemsg.orientation.y,
posemsg.orientation.z,
posemsg.orientation.w,
)
xytheta = np.array([0., 0., 0.])
xytheta[0] = posemsg.position.x
xytheta[1] = posemsg.position.y
xytheta[2] = tf.transformations.euler_from_quaternion(quaternion)[2]
return xytheta
def apply_tf(x, pose2d):
""" Applies transform to x
x is a list of x y points in frame B
pose2d is the transform AT_B, (frame B in frame A)
result is x in frame A
Parameters
----------
pose2d : np.array
Array of shape (3,), x, y, theta components of the tf of frame B in frame A
x: np.array
Array of shape (N, 2), x, y coordinates of N points in frame B
Returns
-------
result: np.array
Array of shape (N, 2), x, y coordinates of N points in frame A
Note
----
pose2d is under the form [x, y, theta], where
x and y are coordinates of frame B in frame A,
and theta is the orientation of frame B in frame A.
Example
-------
>>> BX = np.array([[0, 0], [1, 0]])
>>> AT_B = np.array([2, 1, np.pi/2])
>>> apply_tf(BX, AT_B)
array([[ 2., 1.],
[ 2., 2.]])
"""
return rotate(x, pose2d[2]) + np.array(pose2d[:2])
def apply_tf_to_pose(pose, pose2d):
# same as apply_tf but assumes pose is x y theta instead of x y
xy = rotate(np.array([pose[:2]]), pose2d[2])[0] + np.array(pose2d[:2])
th = pose[2] + pose2d[2]
return np.array([xy[0], xy[1], th])
def apply_tf_to_poses(poses, pose2d):
"""
Parameters
----------
poses: np.array
Array of shape (N, 3), x, y, theta components of tfs of frame C in frame B)
pose2d : np.array
Array of shape (3,), x, y, theta components of the tf of frame B in frame A
Returns
-------
result: np.array
Array of shape (N, 3), x, y theta components of the tf of frame C in frame A
"""
result = np.zeros_like(poses)
xy = rotate(poses[:, :2], pose2d[2]) + pose2d[:2][None, :]
th = poses[:, 2] + pose2d[2]
result[:, :2] = xy
result[:, 2] = th
return result
def apply_tf_to_vel(vel, pose2d):
# same as apply_tf but assumes vel is xdot ydot thetadot instead of x y
# for xdot ydot frame transformation applies,
# but thetadot is invariant due to frames being fixed.
xy = rotate(vel[...,:2], pose2d[2])
th = vel[...,2]
xyth = np.zeros_like(vel)
xyth[...,:2] = xy
xyth[...,2] = th
return xyth
def old_apply_tf_to_vel(vel, pose2d):
xy = rotate(np.array([vel[...,:2]]), pose2d[2])[0]
th = vel[...,2]
return np.array([xy[0], xy[1], th])
def rotate(x, th):
rotmat = np.array([
[np.cos(th), -np.sin(th)],
[np.sin(th), np.cos(th)],
])
return np.matmul(rotmat, x.T).T
def inverse_pose2d(pose2d):
inv_th = -pose2d[2] # theta
inv_xy = rotate(np.array([-pose2d[:2]]), inv_th)[0]
return np.array([inv_xy[0], inv_xy[1], inv_th])
if __name__ == "__main__":
import doctest
doctest.testmod()