Tutorials
All tutorials are jupyter notebooks, downloadable from https://github.com/MarcToussaint/rai-tutorials. For installation instructions, see Getting Started.
The first 3 are intro tutorials that introduce essentials for understanding the code:
Configurations: The core data structure used to represent scenes and robots, compute features, and feed into optimization problems, simulations, and real robot control.
KOMO: A framework to formulate optimization problems, esp. for motion design (IK, path optimization, and manipulation planning).
BotOp: The Robot Operation interface used to control a real or simulated robot, as well as to access sensors.
The remaining tutorials cover various topics in more depth:
- BotOp-2: Real robot operation checklist & first steps
- Config-2: Computing differentiable features & collision evaluation
- Config-3: Importing, editing & manipulating them
- KOMO-2: Reporting & explaining convergence
- KOMO-3: Manipulation Modelling & Execution
- LGP-1: First Mini Interface
- Extension - Simulation: Low-level stepping interface & gym environments
- Extension - Rendering: Basic opengl, offscreen (headless), and interface to physics-based rendering
- Extension - RRT: basic finding example
- Extension - NLP interface: Low-level NLP formulation and solving
- Extension - Gym Environment Interface: minimal example
More stuff:
from robotic import BSpline
import numpy as np
import matplotlib.pyplot as plt
## B splines themselves, based on uniform knots
S = BSpline()
S.setKnots(2, np.linspace(0.,1.,10))
B = S.getBmatrix(np.linspace(0.,1.,100), False, False)
plt.plot(B)
plt.show()
## setting random control points, and fine-evaluating the resulting spline
X = np.random.randn(10,3)
S.setCtrlPoints(X)
Teval = np.linspace(-.1,1.1,100)
x = S.eval(Teval)
v = S.eval(Teval, 1)
a = S.eval(Teval, 2)
T_X = np.linspace(0.,1.,10)
plt.plot(Teval, np.hstack((x,v/10.,a/100.)))
plt.plot(T_X, X, 'p')
plt.show()
## computing optimal control points that fit the random data X from above
B = S.getBmatrix(T_X, False, True) #start not constrained to zero vel, end is
Z = np.linalg.pinv(B) @ X
S.setCtrlPoints(Z, False, True)
Y = S.eval(Teval)
plt.plot(Teval, Y)
plt.plot(T_X, X, 'p')
plt.show()
# READ THIS: https://www.user.tu-berlin.de/mtoussai/notes/quaternions.pdf
from robotic import Quaternion
import math
import numpy as np
q = Quaternion()
print('\n=== using set(...).normalize()):', q.set([1,1,0,0]).normalize())
print(' direct access:', q.w, q.x, q.y, q.z)
print(' as numpy array:', q.asArr())
## converting a quaternion to another representations
print('\n=== converting a quaternion')
print(' original: 90 degree rotation about x:', q)
print(' total rotation angle/pi:', q.getRad()/math.pi)
print(' roll-pitch-yaw/pi:', q.getRollPitchYaw()/math.pi)
print(' log (which is also the "rotation vector"):', q.getLog(), ' length/pi:', np.linalg.norm(q.getLog())/math.pi)
print(' matrix:', q.getMatrix())
## setting a quaternion in various ways:
q = Quaternion()
print('\n=== setting a quaternion')
print(' non-initialized!:', q)
print(' initialize "zero" (which here means identity!)', q.setZero())
print(' the minimal rotation to rotate vector a=(1,0,0) into vector b=(0,1,0)', q.setDiff([1,0,0], [0,1,0]))
print(' 90 degrees about the [0,1,0] axis:', q.setRad(math.pi/2, [0,1,0]))
print(' random:', q.setRandom())
print(' exp(log(q)):', q.setExp(q.getLog()))
print(' quat(matrix(q)):', q.setMatrix(q.getMatrix()))
print(' quat(rollPitchWay(q)):', q.setRollPitchYaw(q.getRollPitchYaw()))
## geodesic interpolation
print('\n=== interpolation')
q0 = Quaternion().set([1,1,0,0]).normalize()
q1 = Quaternion().set([1,0,0,1]).normalize()
for t in np.arange(0, 1.1, 0.1):
q_t = Quaternion().setInterpolateProper(t, q0, q1)
q_t2 = q0 * Quaternion().setExp(t * ((-q0)*q1).getLog()) #same, but harder to remember
print(f' t:{t:.2}, q(t): {q_t}, via exp(log): {q_t2}')
## inverse
print('\n=== multiplication & inverse')
q.setRandom()
print('q: ', q)
print('q*(-q):', q*(-q))
print('(-q)*q:', (-q)*q)