@people_and_robots/lively_tk v0.9.36
LivelyTK v0.9.33 (beta)
NOTE: Since LivelyTK is still in beta, the design is subject to change and should not be considered final!
About
LivelyTK Package
The LivelyTK framework provides a highly configurable toolkit for commanding robots in mixed modalities while incorporating liveliness motions. It is adapted from RelaxedIK framework, and compatible with Python and Javascript/Node.
To configure a robot, the easiest method is to use the LivelyStudio interface in the lively_tk_ros repository, which is a wizard for configuring the robot.
Configuring
Configuring of LivelyTK is centered on the Solver class, which you can instantiate in the following ways:
python
from lively_tk import Solver, PositionMatchObjective, OrientationMatchObjective, SmoothnessMacroObjective, CollisionAvoidanceObjective, State, Transform, ScalarRange, BoxShape
solver = Solver(
urdf='<?xml version="1.0" ?><robot name="panda">...</robot>', # Full urdf as a string
objectives=[
PositionMatchObjective(name="EE Position",link="panda_hand",weight=50),
OrientationMatchObjective(name="EE Rotation",link="panda_hand",weight=25),
SmoothnessMacroObjective(name="General Smoothness",weight=10),
CollisionAvoidanceObjective(name="Collision Avoidance",weight=10)
...
],
root_bounds=[
ScalarRange(value=0.0,delta=0.0),ScalarRange(value=0.0,delta=0.0),ScalarRange(value=0.0,delta=0.0), # Translational
ScalarRange(value=0.0,delta=0.0),ScalarRange(value=0.0,delta=0.0),ScalarRange(value=0.0,delta=0.0) # Rotational
],
shapes=[
BoxShape(name="Table",frame="world",physical=True,x=2,y=1,z=1.2,local_transform=Transform.isometry())
],
initial_state=State(origin=Transform.identity(),joints={"panda_joint1":0.0,"panda_joint2":0.0,...}), # Optional
only_core=False, # Only use this flag if you are not using liveliness objectives and want a slight speed-up.
max_retries=1, # Number of times the solution is attempted (default 1)
max_iterations=150 # Number of iterations per try (default 150)
)javascript
import {
Solver, PositionMatchObjective, OrientationMatchObjective,
SmoothnessMacroObjective, CollisionAvoidanceObjective,
State, Transform, ScalarRange, BoxShape} from "@people_and_robots/lively_tk";
let solver = new Solver(
'<?xml version="1.0" ?><robot name="panda">...</robot>', // Full urdf as a string
[
{type:'PositionMatch',name:"EE Position",link:"panda_hand",weight:50},
{type:'OrientationMatch',name:"EE Rotation",link:"panda_hand",weight:25},
{type:'SmoothnessMacro',name:"General Smoothness",weight:10},
{type:'CollisionAvoidance',name:"Collision Avoidance",weight:10}
...
],
[
{value:0.0,delta:0.0},{value:0.0,delta:0.0},{value:0.0,delta:0.0}, // Translational
{value:0.0,delta:0.0},{value:0.0,delta:0.0},{value:0.0,delta:0.0} // Rotational
],
[
{type:'Box',name="Table",frame:"world",physical:True,x:2,y:1,z:1.2,localTransform:{translation:[0,0,0],rotation:[1,0,0,0]}}
],
{origin:{translation:[0,0,0],rotation:[1,0,0,0]},joints:{panda_joint1:0.0,panda_joint2:0.0,...}}, // Optional
false, // Only use this flag if you are not using liveliness objectives and want a slight speed-up.
1, // Number of times the solution is attempted (default 1)
150 // Number of iterations per try (default 150)
)Resetting
In both the Javascript and Python interfaces, the Solver class has a reset method that allows the user to reset the state of the solver given some new objective weights and a new robot state. In this case, the robot state only needs to supply the joints and origin field, as shown in the initialization example.
python
solver.reset(state=State(origin=Transform.identity(),joints={"panda_joint1":0.0,"panda_joint2":0.0,...}),weights=[50.0,30.0,20.0,10.0])javascript
solver.reset(
{origin:{translation:[0,0,0],rotation:[1,0,0,0]},joints:{panda_joint1:0.0,panda_joint2:0.0,...}}, // New starting state
[50.0,30.0,20.0,10.0] // New starting weights
)Solving
The Solver class has a solve method that represents the core functionality of the LivelyTK interface. At a high level, it accepts the following fields:
goals: A list of goal-type objects.weights: A list of floats, order corresponding to the order of the objectives.time: (float) The current time. If no liveliness objectives are used, this has no effect.shapes: A list of shape objects.
The solve method returns a fully-filled State object
Goals
There are a variety of different "goal" types that can be provided. Think of these as settings that you would like to achieve (e.g. a PositionMatch objective accepts a Translation goal).
Translation
The translation goal is used by the PositionMatch, PositionMirroring, and OriginPositionMatch objectives.
python
goal = Translation(x:1.0,y:0.0,z:0.5)javascript
let goal = {Translation:[1.0,0.0,0.5]}Rotation
The rotation goal is used by the OrientationMatch, OrientationMirroring, and OriginOrientationMatch objectives.
python
goal = Rotation(w:0.707,x:0.0,y:0.0,z:0.707)javascript
let goal = {Rotation:[0.707,0.0,0.0,0.707]}Scalar
The scalar goal is used by the JointMatch, JointMirroring, DistanceMatch, JointLiveliness, and RelativeMotionLiveliness objectives.
python
goal = 0.5javascript
let goal = {Scalar:0.5}Size
The size goal is used by the PositionLiveliness, OrientationLiveliness, OriginPositionLiveliness, and OriginOrientationLiveliness objectives.
python
goal = Size(x:1.0,y:0.1,z:0.5)javascript
let goal = {Size:[1.0,0.1,0.5]}Ellipse
The ellipse goal is used by the PositionBounding objective.
python
goal = Ellipse(
translation=Translation(x:1.0,y:0.0,z:0.4),
rotation=Rotation(w:0.707,x:0.0,y:0.0,z:0.707),
size=Size(x:0.1,y:0.1,z:0.2)
)javascript
let goal = {Ellipse: {
pose: {translation: [1.0,0.0,0.4], rotation: [0.707,0.0,0.0,0.707]},
size: [0.1,0.1,0.2]
}RotationRange
The rotation range goal is used by the RotationBounding objective.
python
goal = RotationRange(
rotation=Rotation(w:0.707,x:0.0,y:0.0,z:0.707),
delta=0.4
)javascript
let goal = {RotationRange: {
rotation: [0.707,0.0,0.0,0.707],
delta:0.4
}ScalarRange
The scalar range goal is used by the JointBounding objective.
python
goal = ScalarRange(value=0.0,delta=0.4)javascript
let goal = {ScalarRange: {value:0.0,delta:0.4}Shapes
There are 4 different Shape classes: Box, Sphere, Capsule, and Cylinder. The name field is entirely for your own usage, and the frame field indicates what robot link the shape is attached to (by default "world"). The physical field indicates whether the shape presents a collision, and should be factored into collision avoidance. Otherwise, the shape is simply tracked in the state if close enough.
Box
python
shape = BoxShape(
name="camera attachment",
frame='panda_hand',
physical=True,
x=0.5,y=0.5,z=0.2,
local_transform=Transform.identity())javascript
let shape = {
type:'Box',
name:'camera attachment',
frame: 'panda_hand',
physical: true,
x:0.5,y:0.5,z:0.2,
local_transform: {translation:[0.0,0.0,0.0],rotation:[1.0,0.0,0.0,0.0]}
}Sphere
python
shape = SphereShape(
name="bouncy ball",
frame='world',
physical=True,
radius=0.1,
local_transform=Transform.identity())javascript
let shape = {
type:'Sphere',
name:'bouncy ball',
frame: 'world',
physical: true,
radius:0.1,
local_transform: {translation:[0.0,0.0,0.0],rotation:[1.0,0.0,0.0,0.0]}
}Capsule
python
shape = CapsuleShape(
name="pill",
frame='world',
physical=True,
length=0.2,
radius=0.1,
local_transform=Transform.identity())javascript
let shape = {
type:'Capsule',
name:'pill',
frame: 'world',
physical: true,
length:0.2,
radius:0.1,
local_transform: {translation:[0.0,0.0,0.0],rotation:[1.0,0.0,0.0,0.0]}
}Cylinder
python
shape = CylinderShape(
name="zone",
frame='world',
physical=False,
length=0.2,
radius=0.1,
local_transform=Transform.identity())javascript
let shape = {
type:'Cylinder',
name:'zone',
frame: 'world',
physical: false,
length:0.2,
radius:0.1,
local_transform: {translation:[0.0,0.0,0.0],rotation:[1.0,0.0,0.0,0.0]}
}State
The State object is the response back after calling solve. It contains the state of the robot in terms of joint and frames, as well as some diagnostic information regarding proximity of various shapes and the center-of-mass of the robot.
Origin
The transform of the root of the robot. This is useful if the root node is movable. Exported as a Transform class (python) or object containing translation and rotation fields (javascript).
Joints
A lookup table of the joint values for each movable joint. Exported as a dictionary (python) or object (javascript).
Frames
A lookup table of the positions/orientations for each link. Exported as a dictionary (python) or object (javascript) of transform objects keyed by the link name.
Proximity
A list of all shapes that are currently tracked and that reach close enough proximity to potentially factor into collision detection. Exported as a ProximityInfo class (python) or object (javascript) with the following attributes:
shape1(string) The name of the first shape (note, if the robot is initialized with this shape, and it is attached to a robot link, the name is the link it is attached to.)shape2(string) The name of the second shape (note, if the robot is initialized with this shape, and it is attached to a robot link, the name is the link it is attached to.)distance(float/number/None/null) The distance recorded between the two shapes. May possibly beNoneornullif not tracked, and is zero if the shapes are intersecting.points(None/set of two points) The closest points on two different shapes that are used determined whether these two shapes are close though to cause a collision based on the distance between the points on these two shapes.pointswill beNoneanddistancewill be0.0if two shapes areinteresectingand colliding.pointswill return aset of two pointsanddistancewill be greater than0.0but smaller than1.0if two shapes are close enough(smaller than 1.0) to potentially cause a collision but not yet colliding. Any distance between two points bigger than1.0are not considered for collision detection.physical(bool) True if both shapes are physical, otherwise False.
- If the distance between points on two different shapes is
0.0, two shapes areintersectingwith each other. - If the distance between points on two different shapes is bigger than
0.0but smaller than1.0, two shapes arewith in marginwith each other.
Center of Mass
A translation (vector) indicating the current center of mass of the robot.
Contributing
Python Instructions
To build, download and cd to this directory. Then run:
# If you just want to install:
python3 setup.py install
# Or if you are developing:
python3 setup.py develop
# If you are developing and need to rebuild:
python3 setup.py clean && python3 setup.py developYou will need this installed to use the ROS2 LivelyIK Package.
Javascript Instructions
To build, download and cd to this directory. Then run:
# Build the javascript bundle
wasm-pack build --scope people_and_robots --target web -- --features jsbindings
# Pack
wasm-pack pack
# Publish
wasm-pack publish --access=public3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago