Skip to content

manipulation: add TransitionPlanner::planPathSingle to work around eigenpy (1,N) Ref<MatrixXd> corruption#124

Open
thanhndv212 wants to merge 1 commit intohumanoid-path-planner:develfrom
thanhndv212:devel
Open

manipulation: add TransitionPlanner::planPathSingle to work around eigenpy (1,N) Ref<MatrixXd> corruption#124
thanhndv212 wants to merge 1 commit intohumanoid-path-planner:develfrom
thanhndv212:devel

Conversation

@thanhndv212
Copy link
Copy Markdown

When a (1,N) numpy array is passed as matrixIn_t (Eigen::Ref), numpy marks it as both C- and F-contiguous (layout is irrelevant for a single row). eigenpy's is_arr_layout_compatible_with_mat_type checks only the F-contiguous flag, sees true, and creates a direct Map with NumpyMapStride = Stride<0,0>. The compile-time-zero strides override the actual numpy strides, so only element (0,0) maps correctly; all (0,c) for c > 0 read garbage memory.

planPath(qInit, qGoals, reset) is preserved unchanged and works correctly for multi-row goals matrices (rows > 1), where C- and F-contiguous flags differ and eigenpy correctly allocates a copy.

planPathSingle(qInit, qGoal, reset) is added as a safe single-goal alternative: it accepts two 1D ConfigurationIn_t (Ref, handled correctly by eigenpy's IsVectorAtCompileTime specialisation) and builds a C++-owned MatrixXd(1,n) internally before calling planPath.

…genpy (1,N) Ref<MatrixXd> corruption

When a (1,N) numpy array is passed as matrixIn_t (Eigen::Ref<const MatrixXd>),
numpy marks it as both C- and F-contiguous (layout is irrelevant for a single
row). eigenpy's is_arr_layout_compatible_with_mat_type<MatrixXd> checks only
the F-contiguous flag, sees true, and creates a direct Map with
NumpyMapStride = Stride<0,0>. The compile-time-zero strides override the
actual numpy strides, so only element (0,0) maps correctly; all (0,c) for
c > 0 read garbage memory.

planPath(qInit, qGoals, reset) is preserved unchanged and works correctly
for multi-row goals matrices (rows > 1), where C- and F-contiguous flags
differ and eigenpy correctly allocates a copy.

planPathSingle(qInit, qGoal, reset) is added as a safe single-goal
alternative: it accepts two 1D ConfigurationIn_t (Ref<const VectorXd>,
handled correctly by eigenpy's IsVectorAtCompileTime specialisation) and
builds a C++-owned MatrixXd(1,n) internally before calling planPath.
@florent-lamiraux
Copy link
Copy Markdown
Contributor

Hello @thanhndv212.
Thank you for this thorough diagnosis. It seems to me that the issue comes from eigenpy and that you understand it pretty well. Would it be relevant to propose a fix in eigenpy. I do not like the idea of adding another method in TransitionPlanner.
@nim65s : this is the bug I talked you about a while ago.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants