-
Notifications
You must be signed in to change notification settings - Fork 24
Description
I just encountered a very tricky silent bug while slinging around AffineMap, LinearMap, Transformation etc.
In summary, I have some 3D rotation matrices stored as LinearMap and tried to combine it with a translation stored as Vector. Spot the error in this code:
using CoordinateTransformations, Rotations
rot = LinearMap(RotY(1/2*pi))
# ...
loc = rand(3)
# ...
pose_map = AffineMap(rot, loc)
# ...
f(pmap::AffineMap) = ...
@test f(pose_map) == test_value # <- compiles just fine, but result completely wrongIt turns out that AffineMap(::LinearMap, ::Vector) actually calls an overloaded function AffineMap(::Transformation, ::Any) and returns an AffineMap just fine, but with AffineMap.v == zeros(3)!
CoordinateTransformations.jl/src/affine.jl
Lines 121 to 125 in b97c74a
| function AffineMap(trans::Transformation, x0) | |
| dT = transform_deriv(trans, x0) | |
| Tx = trans(x0) | |
| AffineMap(dT, Tx - dT*x0) | |
| end |
I.e.
# continued
@assert pose_map.linear == rot.linear # true
@assert pose_map.translation == loc # false. instead
@assert pose_map.translation == zeros(length(loc)) # <- π€―This is a super tricky bug, as it's completely silent, and occurs from a "misuse" of the interface that is very subtle.
Perhaps it would make sense to rename the function
function AffineMap(trans::Transformation, x0)
dT = transform_deriv(trans, x0)
Tx = trans(x0)
AffineMap(dT, Tx - dT*x0)
endto something like AffineMapApprox (or something similar), although I realize that would be a breaking change.
Alternatively, we could overload AffineMap(::LinearTransformation, ::Any), e.g. giving a warning like
@warn "
AffineMap(rot::LinearTransformation, ::Any)might not do what you want. TryAffineMap(rot.linear, x)instead."