pub struct Chain<T: Real> { /* fields omitted */ }
Kinematic Chain using Node
#[macro_use]
use k::*;
use k::prelude::*;
let l0 = JointBuilder::new()
.name("joint_pitch0")
.translation(Translation3::new(0.0, 0.0, 0.1))
.joint_type(JointType::Rotational{axis: Vector3::y_axis()})
.into_node();
let l1 = JointBuilder::new()
.name("joint_pitch1")
.translation(Translation3::new(0.0, 0.0, 0.5))
.joint_type(JointType::Rotational{axis: Vector3::y_axis()})
.into_node();
let l2 = JointBuilder::new()
.name("hand")
.translation(Translation3::new(0.0, 0.0, 0.5))
.joint_type(JointType::Fixed)
.into_node();
connect![l0 => l1 => l2];
let mut tree = Chain::from_root(l0);
assert_eq!(tree.dof(), 2);
let positions = tree.joint_positions();
assert_eq!(positions.len(), 2);
assert_eq!(positions[0], 0.0);
assert_eq!(positions[1], 0.0);
let transforms = tree.update_transforms();
assert_eq!(transforms.len(), 3);
assert_eq!(transforms[0].translation.vector.z, 0.1);
assert_eq!(transforms[1].translation.vector.z, 0.6);
assert_eq!(transforms[2].translation.vector.z, 1.1);
for t in transforms {
println!("before: {}", t);
}
tree.set_joint_positions(&vec![1.0, 2.0]).unwrap();
let positions = tree.joint_positions();
assert_eq!(positions[0], 1.0);
assert_eq!(positions[1], 2.0);
let transforms = tree.update_transforms();
assert_eq!(transforms.len(), 3);
for t in transforms {
println!("after: {}", t);
}
Create Chain from root joint
use k;
let l0 = k::JointBuilder::new().into_node();
let l1 = k::JointBuilder::new().into_node();
l1.set_parent(&l0);
let tree = k::Chain::<f32>::from_root(l0);
Create Chain
from end joint. It has any branches.
Do not discard root joint before create Chain.
If you want to get Chain, unwrap()
this, it is safe.
use k::*;
fn create_tree_from_end() -> Chain<f64> {
let l0 = Node::new(Joint::new("fixed0", JointType::Fixed));
let l1 = Node::new(Joint::new("fixed1", JointType::Fixed));
l1.set_parent(&l0);
Chain::from_end(&l1)
}
let tree = create_tree_from_end();
Iterate for all joint nodes
The order is from parent to children. You can assume that parent is already iterated.
use k::*;
let l0 = Node::new(Joint::new("fixed0", JointType::Fixed));
let l1 = Node::new(Joint::new("fixed1", JointType::Fixed));
l1.set_parent(&l0);
let tree = Chain::<f64>::from_root(l0);
let names = tree.iter().map(|node| node.joint().name.to_owned()).collect::<Vec<_>>();
assert_eq!(names.len(), 2);
assert_eq!(names[0], "fixed0");
assert_eq!(names[1], "fixed1");
Iterate for movable joints
Fixed joints are ignored. If you want to manipulate on Fixed,
use iter()
instead of iter_joints()
Calculate the degree of freedom
use k::*;
let l0 = JointBuilder::new()
.joint_type(JointType::Fixed)
.finalize()
.into();
let l1 : Node<f64> = JointBuilder::new()
.joint_type(JointType::Rotational{axis: Vector3::y_axis()})
.finalize()
.into();
l1.set_parent(&l0);
let tree = Chain::from_root(l0);
assert_eq!(tree.dof(), 1);
Find the joint by name
use k::*;
let l0 = Node::new(JointBuilder::new()
.name("fixed")
.finalize());
let l1 = Node::new(JointBuilder::new()
.name("pitch1")
.translation(Translation3::new(0.0, 0.1, 0.0))
.joint_type(JointType::Rotational{axis: Vector3::y_axis()})
.finalize());
l1.set_parent(&l0);
let tree = Chain::from_root(l0);
let j = tree.find("pitch1").unwrap();
j.set_joint_position(0.5).unwrap();
assert_eq!(j.joint_position().unwrap(), 0.5);
Get the positions of the joints
FixedJoint
is ignored. the length is the same with dof()
Set the positions of the joints
FixedJoints
are ignored. the input number must be equal with dof()
Fast, but without check, dangerous set_joint_positions
Update world_transform() of the joints
Update world_velocity() of the joints
Update transforms of the links
Formats the value using the given formatter. Read more
Formats the value using the given formatter. Read more
Converts the given value to a String
. Read more
🔬 This is a nightly-only experimental API. (try_from
)
The type returned in the event of a conversion error.
🔬 This is a nightly-only experimental API. (try_from
)
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
🔬 This is a nightly-only experimental API. (try_from
)
The type returned in the event of a conversion error.
🔬 This is a nightly-only experimental API. (try_from
)
🔬 This is a nightly-only experimental API. (get_type_id
)
this method will likely be replaced by an associated static
impl<SS, SP> SupersetOf for SP where SS: SubsetOf<SP>, | |
The inverse inclusion map: attempts to construct self
from the equivalent element of its superset. Read more
Checks if self
is actually part of its subset T
(and can be converted to it).
Use with care! Same as self.to_subset
but without any property checks. Always succeeds.
The inclusion map: converts self
to the equivalent element of its superset.