Filter löschen
Filter löschen

Why Does dcm2angle Work Like This?

9 Ansichten (letzte 30 Tage)
Paul
Paul am 19 Mai 2024
Kommentiert: William Rose am 20 Mai 2024
Suppose I have a direction cosine matrix, brought to my attention by a colleague
C = round(angle2dcm(-pi/2,-pi/2,0,'ZYX'))
C = 3x3
0 0 1 1 0 0 0 1 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Extract the angles with @doc:dcm2angle (Aerospace Toolbox) using the Default option
[a1,a2,a3] = dcm2angle(C,'ZYX','Default');[a1,a2,a3]
ans = 1x3
0 -1.5708 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Because the middle angle is -pi/2, the extracted angle triplets have multiple solutions, but the default result isn't one of them.
Sometime after R2019b and before or at R2022a, an additonal optional argument can be specified, though I could find nothing about this new argument in the release notes nor the bug fixes.
[a1,a2,a3] = dcm2angle(C,'ZYX','Robust');[a1,a2,a3]
ans = 1x3
-1.5708 -1.5708 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Now we get a correct answer.
Trying with @doc:rotm2eul that's used in other toolboxes (Robotics, Navigation, UAV) we see that it returns a correct result without any optional arguments.
eul = rotm2eul(C.','ZYX')
eul = 1x3
0 -1.5708 -1.5708
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
round(angle2dcm(eul(1),eul(2),eul(3),'ZYX'))
ans = 3x3
0 0 1 1 0 0 0 1 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
@doc:dcm2angle with the Robust option actually computes two sets of angles, then computes the DCM with each set, and then compares the recomputed DCMs to the input DCM, and then returns the set of angles that result in a DCM that's closest to the input. @doc:rotm2eul uses a different approach altogether, though is limited to only three axes sequences.
To be sure, the Default option with @doc:dcm2angle is considerably faster than Robust, but Robust appears to take the same amout of time as @doc:rotm2eul
timeit(@() dcm2angle(repmat(C,1,1,1e5),'ZYX','Default'),3)
ans = 0.0065
timeit(@() dcm2angle(repmat(C,1,1,1e5),'ZYX','Robust'),3)
ans = 0.0101
timeit(@() rotm2eul(repmat(C.',1,1,1e5),'ZYX'),1)
ans = 0.0110
Does anyone have a thought as to why dcm2angle is implemented as it is with Default and forces the user to use Robust? And why wouldn't that same reason apply to rotm2eul?
Once MathWorks realized that dcm2angle Default was returning incorrect results in some cases, why patch it with Robust and keep Default instead of just fixing the bug?
  3 Kommentare
Paul
Paul am 19 Mai 2024
Hi William,
As to the first part, If you haven't see it already, check out this answer from @Steven Lord (in his personal capacity).
Following this logic, it would be difficult for MathWorks to address any bug, for which a user has found their own workaround, without implementing the correction through some other means, like an optional argument as in the case of dcm2angle.
I might be able to be convinced otherwise, but the Default implementation is a bug and the way to fix a bug is to fix the bug. Users with critical processes should always check the release notes for bug fixes and behavior changes, though in this case the Robust option wasn't captured as either for R2021b, where it first shows up in the doc page.
William Rose
William Rose am 20 Mai 2024
@Paul, good points. And thanks for the link.

Melden Sie sich an, um zu kommentieren.

Antworten (0)

Kategorien

Mehr zu Quadcopters and Drones finden Sie in Help Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by