k icon indicating copy to clipboard operation
k copied to clipboard

Unable to converge on 2 dof setup

Open tmitchel2 opened this issue 4 years ago • 0 comments

Hi,

Im investigating your library with the aim of building a kinematic model for a 5 axis cnc machine. Im starting off very basic with 1 then 2, etc dof. My 1 dof test seems to work but my 2 dof test does not converge.

Could you shed some light on what I'm doing wrong?

I've included a bare bones reproduction of the code...Apologies as this is more of a question than an issue.

fn test_kinematics() {
    // Works...
    test_kinematics_1_dof();

    // Errors...
    //    thread 'main' panicked at 'called `Result::unwrap()` on an `Err`
    //    value: NotConvergedError { num_tried: 10, position_diff:
    //    Matrix { data: [0.0009765625, 0.0009765625, 0.0] },
    //    rotation_diff: Matrix { data: [0.0, 0.0, 0.0] } }'
    test_kinematics_2_dof();
}

fn test_kinematics_1_dof() {
    let machine_frame = k::Node::new(
        k::NodeBuilder::new()
            .name("machine_frame")
            .translation(na::Translation3::new(0.0, 0.0, 0.0))
            .joint_type(k::JointType::Fixed)
            .finalize(),
    );

    let x_axis_linear = k::Node::new(
        k::NodeBuilder::new()
            .name("x_axis_linear")
            .translation(na::Translation3::new(0.0, 0.0, 0.0))
            .joint_type(k::JointType::Linear {
                axis: na::Vector3::x_axis(),
            })
            .finalize(),
    );

    x_axis_linear.set_parent(&machine_frame);
    let chain = k::Chain::from_root(machine_frame);

    // Initial position
    let origin_positions_vec = vec![0.0];
    chain.set_joint_positions(&origin_positions_vec).unwrap();
    println!("initial positions = {:?}", chain.joint_positions());
    // Forward kinematics
    let target_positions_vec = vec![1.0];
    let workpiece = chain.find("x_axis_linear").unwrap();
    chain.update_transforms();
    let mut target = x_axis_linear.world_transform().unwrap();
    println!("initial target pos = {:?}", target.translation);
    println!("move x: {:?}", target_positions_vec[0]);
    target.translation.vector.x += target_positions_vec[0];

    // Inverse kinematics
    let solver = k::JacobianIKSolver::default();
    let arm = k::SerialChain::from_end(workpiece);
    let mut constraints = k::Constraints::default();
    constraints.rotation_x = false;
    constraints.rotation_y = false;
    constraints.rotation_z = false;
    // constraints.position_x = false;
    constraints.position_y = false;
    constraints.position_z = false;
    solver
        .solve_with_constraints(&arm, &target, &constraints)
        .unwrap();
    println!("solved positions = {:?}", chain.joint_positions());
    chain.update_transforms();
    let solved_pose = workpiece.world_transform().unwrap();
    println!("solved target positions = {:?}", solved_pose.translation);
}

fn test_kinematics_2_dof() {
    let machine_frame = k::Node::new(
        k::NodeBuilder::new()
            .name("machine_frame")
            .translation(na::Translation3::new(0.0, 0.0, 0.0))
            .joint_type(k::JointType::Fixed)
            .finalize(),
    );

    let x_axis_linear = k::Node::new(
        k::NodeBuilder::new()
            .name("x_axis_linear")
            .translation(na::Translation3::new(0.0, 0.0, 0.0))
            .joint_type(k::JointType::Linear {
                axis: na::Vector3::x_axis(),
            })
            .finalize(),
    );

    let y_axis_linear = k::Node::new(
        k::NodeBuilder::new()
            .name("y_axis_linear")
            .translation(na::Translation3::new(0.0, 0.0, 0.0))
            .joint_type(k::JointType::Linear {
                axis: na::Vector3::y_axis(),
            })
            .finalize(),
    );

    x_axis_linear.set_parent(&machine_frame);
    y_axis_linear.set_parent(&x_axis_linear);
    let chain = k::Chain::from_root(machine_frame);

    // Initial position
    let origin_positions_vec = vec![0.0, 0.0];
    chain.set_joint_positions(&origin_positions_vec).unwrap();
    println!("initial positions = {:?}", chain.joint_positions());
    // Forward kinematics
    let target_positions_vec = vec![1.0, 1.0];
    let workpiece = chain.find("y_axis_linear").unwrap();
    chain.update_transforms();
    let mut target = y_axis_linear.world_transform().unwrap();
    println!("initial target pos = {:?}", target.translation);
    println!("move x: {:?}", target_positions_vec[0]);
    println!("move y: {:?}", target_positions_vec[1]);
    target.translation.vector.x += target_positions_vec[0];
    target.translation.vector.y += target_positions_vec[1];

    // Inverse kinematics
    let solver = k::JacobianIKSolver::default();
    let arm = k::SerialChain::from_end(workpiece);
    let mut constraints = k::Constraints::default();
    constraints.rotation_x = false;
    constraints.rotation_y = false;
    constraints.rotation_z = false;
    // constraints.position_x = false;
    // constraints.position_y = false;
    constraints.position_z = false;
    solver
        .solve_with_constraints(&arm, &target, &constraints)
        .unwrap();
    println!("solved angles = {:?}", chain.joint_positions());
    chain.update_transforms();
    let solved_pose = workpiece.world_transform().unwrap();
    println!("solved target pos = {:?}", solved_pose.translation);
}

tmitchel2 avatar May 26 '20 18:05 tmitchel2