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 wrong
It 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)!
|
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)
end
to 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. Try AffineMap(rot.linear, x) instead."
I just encountered a very tricky silent bug while slinging around
AffineMap,LinearMap,Transformationetc.In summary, I have some 3D rotation matrices stored as
LinearMapand tried to combine it with a translation stored asVector. Spot the error in this code:It turns out that
AffineMap(::LinearMap, ::Vector)actually calls an overloaded functionAffineMap(::Transformation, ::Any)and returns an AffineMap just fine, but withAffineMap.v == zeros(3)!CoordinateTransformations.jl/src/affine.jl
Lines 121 to 125 in b97c74a
I.e.
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
to 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