This example shows how to build a reduced robot model from an existing URDF model by fixing the desired joints at a specified position.
import os
from pathlib import Path
import numpy as np
import pinocchio as pin
model_path = Path(os.environ.get("EXAMPLE_ROBOT_DATA_MODEL_DIR"))
mesh_dir = model_path.parent.parent
urdf_filename = model_path / "ur_description/urdf/ur5_robot.urdf"
model, collision_model, visual_model = pin.buildModelsFromUrdf(urdf_filename, mesh_dir)
print("standard model: dim=" + str(len(model.joints)))
for jn in model.joints:
print(jn)
print("-" * 30)
jointsToLock = ["wrist_1_joint", "wrist_2_joint", "wrist_3_joint"]
jointsToLockIDs = []
for jn in jointsToLock:
if model.existJointName(jn):
jointsToLockIDs.append(model.getJointId(jn))
else:
print("Warning: joint " + str(jn) + " does not belong to the model!")
initialJointConfig = np.array(
[
0,
0,
0,
1,
1,
1,
]
)
model_reduced = pin.buildReducedModel(model, jointsToLockIDs, initialJointConfig)
model_reduced, visual_model_reduced = pin.buildReducedModel(
model, visual_model, jointsToLockIDs, initialJointConfig
)
geom_models = [visual_model, collision_model]
model_reduced, geometric_models_reduced = pin.buildReducedModel(
model,
list_of_geom_models=geom_models,
list_of_joints_to_lock=jointsToLockIDs,
reference_configuration=initialJointConfig,
)
visual_model_reduced, collision_model_reduced = (
geometric_models_reduced[0],
geometric_models_reduced[1],
)
print("joints to lock (only ids):", jointsToLockIDs)
print("reduced model: dim=" + str(len(model_reduced.joints)))
print("-" * 30)
mixed_jointsToLockIDs = [jointsToLockIDs[0], "wrist_2_joint", "wrist_3_joint"]
robot = pin.RobotWrapper.BuildFromURDF(urdf_filename, mesh_dir)
reduced_robot = robot.buildReducedRobot(
list_of_joints_to_lock=mixed_jointsToLockIDs,
reference_configuration=initialJointConfig,
)
print("mixed joints to lock (names and ids):", mixed_jointsToLockIDs)
print("RobotWrapper reduced model: dim=" + str(len(reduced_robot.model.joints)))
for jn in robot.model.joints:
print(jn)
#include "pinocchio/parsers/urdf.hpp"
#include "pinocchio/algorithm/joint-configuration.hpp"
#include "pinocchio/algorithm/model.hpp"
#include <iostream>
#include <algorithm>
#ifndef EXAMPLE_ROBOT_DATA_MODEL_DIR
#define EXAMPLE_ROBOT_DATA_MODEL_DIR "path_to_the_model_dir"
#endif
template<typename T>
bool is_in_vector(const std::vector<T> & vector, const T & elt)
{
return vector.end() != std::find(vector.begin(), vector.end(), elt);
}
int main(int argc, char ** argv)
{
const std::string urdf_filename =
(argc <= 1) ? EXAMPLE_ROBOT_DATA_MODEL_DIR + std::string("/ur_description/urdf/ur5_robot.urdf")
: argv[1];
Model model;
std::vector<std::string> list_of_joints_to_lock_by_name;
list_of_joints_to_lock_by_name.push_back("elbow_joint");
list_of_joints_to_lock_by_name.push_back("wrist_3_joint");
list_of_joints_to_lock_by_name.push_back("wrist_2_joint");
list_of_joints_to_lock_by_name.push_back("blabla");
std::vector<JointIndex> list_of_joints_to_lock_by_id;
for (std::vector<std::string>::const_iterator it = list_of_joints_to_lock_by_name.begin();
it != list_of_joints_to_lock_by_name.end(); ++it)
{
const std::string & joint_name = *it;
if (model.existJointName(joint_name))
list_of_joints_to_lock_by_id.push_back(model.getJointId(joint_name));
else
std::cout << "joint: " << joint_name << " does not belong to the model" << std::endl;
}
Eigen::VectorXd q_neutral =
neutral(model);
PINOCCHIO_UNUSED_VARIABLE(q_neutral);
std::cout << "\n\nFIRST CASE: BUILD A REDUCED MODEL FROM A LIST OF JOINT TO LOCK" << std::endl;
Model reduced_model =
buildReducedModel(model, list_of_joints_to_lock_by_id, q_rand);
std::cout << "List of joints in the original model:" << std::endl;
for (JointIndex joint_id = 1; joint_id < model.joints.size(); ++joint_id)
std::cout << "\t- " << model.names[joint_id] << std::endl;
std::cout << "List of joints in the reduced model:" << std::endl;
for (JointIndex joint_id = 1; joint_id < reduced_model.
joints.size(); ++joint_id)
std::cout <<
"\t- " << reduced_model.
names[joint_id] << std::endl;
std::cout << "\n\nSECOND CASE: BUILD A REDUCED MODEL FROM A LIST OF JOINT TO KEEP UNLOCKED"
<< std::endl;
std::vector<std::string> list_of_joints_to_keep_unlocked_by_name;
list_of_joints_to_keep_unlocked_by_name.push_back("shoulder_pan_joint");
list_of_joints_to_keep_unlocked_by_name.push_back("shoulder_lift_joint");
list_of_joints_to_keep_unlocked_by_name.push_back("wrist_1_joint");
std::vector<JointIndex> list_of_joints_to_keep_unlocked_by_id;
for (std::vector<std::string>::const_iterator it =
list_of_joints_to_keep_unlocked_by_name.begin();
it != list_of_joints_to_keep_unlocked_by_name.end(); ++it)
{
const std::string & joint_name = *it;
if (model.existJointName(joint_name))
list_of_joints_to_keep_unlocked_by_id.push_back(model.getJointId(joint_name));
else
std::cout << "joint: " << joint_name << " does not belong to the model";
}
list_of_joints_to_lock_by_id.clear();
for (JointIndex joint_id = 1; joint_id < model.joints.size(); ++joint_id)
{
const std::string joint_name = model.names[joint_id];
if (is_in_vector(list_of_joints_to_keep_unlocked_by_name, joint_name))
continue;
else
{
list_of_joints_to_lock_by_id.push_back(joint_id);
}
}
Model reduced_model2 =
buildReducedModel(model, list_of_joints_to_lock_by_id, q_rand);
std::cout << "List of joints in the second reduced model:" << std::endl;
for (JointIndex joint_id = 1; joint_id < reduced_model2.
joints.size(); ++joint_id)
std::cout <<
"\t- " << reduced_model2.
names[joint_id] << std::endl;
}
ModelTpl< Scalar, Options, JointCollectionTpl > & buildModel(const std::string &filename, const typename ModelTpl< Scalar, Options, JointCollectionTpl >::JointModel &rootJoint, const std::string &rootJointName, ModelTpl< Scalar, Options, JointCollectionTpl > &model, const bool verbose=false, const bool mimic=false)
Build the model from a URDF file with a particular joint as root of the model tree inside the model g...
Main pinocchio namespace.
void neutral(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ReturnType > &qout)
Return the neutral configuration element related to the model configuration space.
void randomConfiguration(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorIn1 > &lowerLimits, const Eigen::MatrixBase< ConfigVectorIn2 > &upperLimits, const Eigen::MatrixBase< ReturnType > &qout)
Generate a configuration vector uniformly sampled among provided limits.
void buildReducedModel(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, std::vector< JointIndex > list_of_joints_to_lock, const Eigen::MatrixBase< ConfigVectorType > &reference_configuration, ModelTpl< Scalar, Options, JointCollectionTpl > &reduced_model)
Build a reduced model from a given input model and a list of joint to lock.
JointModelVector joints
Vector of joint models.
std::vector< std::string > names
Name of the joints.