Expand description
RobotModelBackend over the robot-served libfcimodels shared object.
On FCI v5 (Franka Emika Robot, FER, libfranka 0.9.2) the robot does not publish a
URDF. It serves a compiled model instead: Robot::loadModel issues a
LoadModelLibrary command, libfranka writes the returned bytes to a
temporary file, dlopens it and calls plain C functions out of it
(src/library_downloader.cpp, src/library_loader.h, src/model_library.h,
src/libfcimodels.h, src/model.cpp, all of 0.9.2).
This module is the Rust equivalent of franka::ModelLibrary +
franka::LibraryLoader: SoModelBackend::open / SoModelBackend::from_bytes
bind all thirty exported symbols once, up front, exactly like
ModelLibrary::ModelLibrary does in its initialiser list, and the
RobotModelBackend impl dispatches the ten crate::model::Frame values
onto them the way franka::Model does in model.cpp.
§Symbols and frames
libfcimodels.h (0.9.2) declares, all extern "C" and all column-major:
| symbol | signature | used for |
|---|---|---|
O_T_J1 .. O_T_J8 | (const double q[7], double out[16]) | pose of joints 1..7 and the flange |
O_T_J9 | (const double q[7], const double F_T_EE[16], double out[16]) | pose of the end-effector / stiffness frame |
Ji_J_J1 | (double out[42]) | body Jacobian of joint 1 — no q |
Ji_J_J2 .. Ji_J_J8 | (const double q[7], double out[42]) | body Jacobian of joints 2..7 and the flange |
Ji_J_J9 | (const double q[7], const double F_T_EE[16], double out[42]) | body Jacobian of the end-effector / stiffness frame |
O_J_J1 | (double out[42]) | zero Jacobian of joint 1 — no q |
O_J_J2 .. O_J_J8 | (const double q[7], double out[42]) | zero Jacobian of joints 2..7 and the flange |
O_J_J9 | (const double q[7], const double F_T_EE[16], double out[42]) | zero Jacobian of the end-effector / stiffness frame |
M_NE | (const double q[7], const double I_load[9], double m_load, const double F_x_Cload[3], double out[49]) | mass matrix |
c_NE | (const double q[7], const double dq[7], const double I_load[9], double m_load, const double F_x_Cload[3], double out[7]) | Coriolis vector |
g_NE | (const double q[7], const double g_earth[3], double m_load, const double F_x_Cload[3], double out[7]) | gravity vector |
The frame mapping is model.cpp’s: Joint1..Joint7 are J1..J7, Flange
is J8, EndEffector is J9 evaluated with F_T_EE, and Stiffness is
J9 evaluated with the column-major product F_T_EE * EE_T_K — libfranka
forms exactly that product with
Eigen::Matrix4d(F_T_EE.data()) * Eigen::Matrix4d(EE_T_K.data()), and Eigen
is column-major by default.
§Load parameters
The _load arguments are named after the payload in the C header, but
franka::Model::mass/coriolis/gravity pass robot_state.I_total,
robot_state.m_total and robot_state.F_x_Ctotal, i.e. the combined
end-effector-plus-payload body. This backend therefore forwards the trait’s
i_total / m_total / f_x_ctotal unchanged, which is what libfranka does.
§Gravity and Coriolis
c_NE takes no gravity vector: the FCI v5 franka::Model::coriolis
(model.cpp, 0.9.2) has no gravity_earth parameter at all, unlike the FCI
v10 franka::RobotModel::coriolis this crate’s trait is shaped after.
RobotModelBackend::coriolis’s gravity_earth argument is consequently
ignored here; the Coriolis vector the FER’s own model returns is
gravity-free by construction. g_NE does take g_earth and receives the
trait’s gravity_earth verbatim.
§Platform
The robot serves a native shared object, so the process that loads it must
match the (architecture, system) pair it asked for. In practice that is
libfcimodels_x64.so on x86-64 Linux; see
crate::model::model_library::load_from_robot.
Structs§
- SoModel
Backend RobotModelBackendbacked by the robot’s ownlibfcimodelsshared object.