roboticslab-uc3m / kinematics-dynamics

Kinematics and dynamics solvers and controllers.
https://robots.uc3m.es/kinematics-dynamics/
GNU Lesser General Public License v2.1
19 stars 12 forks source link

Review joint sizes shared between controller and solver #162

Closed PeterBowman closed 1 year ago

PeterBowman commented 6 years ago

BasicCartesianControl integrates two distinct members related to the number of controlled joints:

https://github.com/roboticslab-uc3m/kinematics-dynamics/blob/c187abdc0c9b2284d36df0f22cf64ecb238642b2/libraries/YarpPlugins/BasicCartesianControl/BasicCartesianControl.hpp#L229

In the KDL world, the latter is returned by KDL::Chain::getNrOfJoints(). However, it's also important to note that certain solvers work with the number of segments (links), as returned by KDL::Chain::getNrOfSegments().

Since most data travels between API calls inside a container of some sort (std::vector), and its size is not enforced in any way, hard-to-spot errors may arise.

PeterBowman commented 4 years ago

I plan to merge numRobotJoints and numSolverJoints into one entity that represents motor joints, only. That is, the (until and for now) only additional YARP-handled joint, which corresponds to the LacqueyFetch single-motor gripper, will be exposed via a dedicated YARP port to which BasicCartesianControl would have to connect via a separate remote_controlboard device in case it needs to access actuator commands (https://github.com/roboticslab-uc3m/kinematics-dynamics/issues/115). See rationale at https://github.com/roboticslab-uc3m/yarp-devices/issues/228#issuecomment-532200863.

jgvictores commented 4 years ago

Two comments related to the iCub: 1) Specifically on the iCub, I recall the hand joints are coupled to the arm. I know we do not have one, but maybe it is not a great idea to make our controller incompatible with its port layout. 2) In YARP's http://www.yarp.it/classyarp_1_1dev_1_1ICartesianControl.html#a425a689b2ab34bf2d13f1a17197a2ccc class, there is a differentiation between controlled joints and blocked joints (joints that are not controlled). Maybe this kind of mapping would be better?

PeterBowman commented 4 years ago

Ad 1:

Did we ever comply with iCub regarding joint or cartesian control? Are we compatible with iCub in the current state of this repo? If so, what should we keep in mind in order to keep being compliant, e.g. are there any written guidelines for that respect?

Ad 2:

We handle blocked (non-actuated) joints in the solver layer, every axis passing through the BCC is actuated (including gripper joints). In our case, the first N joints belong to a kinematic chain, whereas gripper joints always live at the end of this joint list. Doesn't seem the case for the method you link to. If you actually want to discuss randomly inserted blocked joints, in the current state of things, I think this should be treated at the joint controller level (yarp-devices repo).

PeterBowman commented 4 years ago

If you actually want to speak about randomly inserted blocked joints, in the current state of things, I think this should be discussed at the joint controller level (yarp-devices repo).

Just recalled https://github.com/roboticslab-uc3m/kinematics-dynamics/issues/178.

PeterBowman commented 2 years ago

I plan to merge numRobotJoints and numSolverJoints into one entity that represents motor joints, only.

Done at https://github.com/roboticslab-uc3m/kinematics-dynamics/commit/83b02a2ab551912fb9bf23eb155f500ef6fefa29.

PeterBowman commented 2 years ago
  • The first six force vectors (applied on each link) are null/empty, just the seventh one matters and it should be interpreted as a force exerted on the tool's TCP. Note that there are only six joints in the "standard" chain (gripper aside). KDL sees six joints, but eight links (kinematic chain prepended with H0, and HN appended thereafter). Inverse dynamics are performed on said vector (ref).

Considering this, @jgvictores, would you mind if we 🔥 BREAK THE API 🔥 (just a little bit)? I'd suggest to replace

ICartesianSolver::invDyn(const std::vector<double> &q, const std::vector<double> &qdot, const std::vector<double> &qdotdot,
                         const std::vector<std::vector<double>> &fexts, std::vector<double> &t);

with

ICartesianSolver::invDyn(const std::vector<double> &q, const std::vector<double> &qdot, const std::vector<double> &qdotdot,
                         const std::vector<double> &ftip, std::vector<double> &t);

That is, expect const std::vector<double> &ftip instead of const std::vector<std::vector<double>> &fexts. While fexts is a vector of external wrenches applied on each segment/link, ftip would refer to its last element: external forces applied on the tip.

Why? Because we can't query the number of chain/tree segments as it is required by the current API. Currently, this is hardcoded as I explained in the first comment, and maybe even wrong or buggy. In case we load a kinematics model with more or less segments, the loop in PeriodicThreadImpl.cpp could segfault. Therefore:

The latter alternative assumes that we won't ever want to provide non-zero values for external forces applied on other segments (besides the tip). Keep in mind the signature of ICartesianControl::forc doesn't allow to do so anyway (the input vector is ftip regardless of the underlying solver API).

jgvictores commented 2 years ago

Let's go for it!

PeterBowman commented 1 year ago

Important finding: the diagram represented in the wiki does not depict the actual behavior of KDL solvers accurately enough.

kdl_segment

The Fcog is, in fact, referred to the tip frame of the segment. In other words, the "reference frame" stated in the documentation of RigidBodyInertia is the tip frame, not the local base/root frame.

Further read: https://github.com/orocos/orocos_kinematics_dynamics/issues/170 and https://www.orocos.org/forum/orocos/orocos-users/problem-dynamic-model-and-inverse-dynamic-solver-kdl.

PeterBowman commented 1 year ago

Done at https://github.com/roboticslab-uc3m/kinematics-dynamics/commit/be7289c125da5160815563a29a6076ab448b1cc1.

PeterBowman commented 1 year ago

The interpretation of external/exerted forces is a source of confusion.

The last one requires that sign inversion is performed when passing data between controller and solver. This is done at https://github.com/roboticslab-uc3m/kinematics-dynamics/commit/f9523fc080ac9e70a497e8ea35946a23cf8cd257.