Description:
base_frame is exposed as a parameter on pose_broadcaster, but it is only ever used as a header.frame_id on posestamped message header, it never enters the kinematics. The pose that gets published is expressed in the model root frame, while the header claims it is in base_frame. On the cartesian_controller side there is a matching gap: incoming target_pose and target_wrench are consumed as-is, with no notion of which frame they are expressed in.
When the model root and the arm base coincide (for example robot arm mounted on table), the two frames are identical and nothing is visibly wrong. As soon as the arm is mounted on something (for example mobile base), the published pose is silently expressed in the wrong frame and the header is misleading.
I ran into this on a robot where the arm base is offset and rotated relative to the model root.
Question:
Is base_frame intended to be a pure TF label, with the understanding that all pose/wrench data is in the model root frame and it is on the user side to provide input accordingly or is this an oversight from developing against a table-mounted arm?
If it is intended, I think the parameter descriptions can be modified to say so explicitly, and pose_broadcaster should probably reject a base_frame that is not the model root rather than accepting one and publishing a mislabelled pose. What do you think ?
If it is an oversight, I am happy to open a PR.
Proposed Fix:
base_frame is the frame that current_pose is published in and that target_pose and target_wrench are interpreted in. Empty means the model root.
for pose_broadcaster:
- Validate
base_frame against the model at configure time, store base_frame_id.
- Publish
data_.oMf[base_frame_id].actInv(data_.oMf[end_effector_frame_id]) so the data matches the header.
for cartesian_controller
- Validate
base_frame, store base_frame_id (0 = model root when empty).
- Lift incoming targets into the root frame before computing the error:
oMtarget = oMb * bMtarget.
- Rotate target_wrench from base_frame axes into whichever frame J is expressed in.
Description:
base_frameis exposed as a parameter onpose_broadcaster, but it is only ever used as aheader.frame_idon posestamped message header, it never enters the kinematics. The pose that gets published is expressed in the model root frame, while the header claims it is inbase_frame. On the cartesian_controller side there is a matching gap: incomingtarget_poseandtarget_wrenchare consumed as-is, with no notion of which frame they are expressed in.When the model root and the arm base coincide (for example robot arm mounted on table), the two frames are identical and nothing is visibly wrong. As soon as the arm is mounted on something (for example mobile base), the published pose is silently expressed in the wrong frame and the header is misleading.
I ran into this on a robot where the arm base is offset and rotated relative to the model root.
Question:
Is
base_frameintended to be a pure TF label, with the understanding that all pose/wrench data is in the model root frame and it is on the user side to provide input accordingly or is this an oversight from developing against a table-mounted arm?If it is intended, I think the parameter descriptions can be modified to say so explicitly, and
pose_broadcastershould probably reject abase_framethat is not the model root rather than accepting one and publishing a mislabelled pose. What do you think ?If it is an oversight, I am happy to open a PR.
Proposed Fix:
base_frameis the frame thatcurrent_poseis published in and thattarget_poseandtarget_wrenchare interpreted in. Empty means the model root.for pose_broadcaster:
base_frameagainst the model at configure time, storebase_frame_id.data_.oMf[base_frame_id].actInv(data_.oMf[end_effector_frame_id])so the data matches the header.for cartesian_controller
base_frame, store base_frame_id (0 = model root when empty).oMtarget = oMb * bMtarget.