srobo / competition-simulator

A simulator for Student Robotics Virtual Competitions
https://studentrobotics.org/docs/simulator/
MIT License
8 stars 2 forks source link

SR2024 vision API and full stack integration test harness #415

Closed PeterJCLaw closed 10 months ago

PeterJCLaw commented 10 months ago

This updates the vision API to match that expected by the SR2024 kit.

Changes

Included here:

Not included here:

Code review

I suggest we focus on the correctness of the data returned from the API and whether the API shape matches the kit API. It may also be worth splitting the review as I realise the diff is pretty big.

I'm happy to do a walk-through review if that would be useful, alternatively here's a guide to the changes.

The core things to review (and I suggest this order) are:

That covers the core of the logic. Much of the rest of the changes are accounting for the change in alignment of the marker proto to webots axes or are other plumbing:

Verification

I've done some light testing manually with the keyboard robot, though mostly I'm relying on validation from the unit tests. It would be great to do more manual testing that the orientation data in particular is correct.

I've manually compared a small number of the multi-axis markers to the images in april_vision's tests and confirmed that they line up.

Links

Fixes #377

WillB97 commented 10 months ago

You may want to look at how april_vision tests its marker object. It uses webots to generate marker images with markers at known poses and them feeds the images to a test script to assert the calculated poses are correct. Here the two halves can be combined as we're using webots' detection.

WillB97 commented 10 months ago

The order of orientation rotations are shown here: https://github.com/WillB97/april_vision/blob/main/tests/webots_generator/worlds/webots_generator.wbt#L37-L44

The maths required to convert the Webots' orientation to yaw, pitch, roll is:

# Unpack the axis angle to allow for remapping and normalisation
_x, _y, _z, angle = recognition.getOrientation()
# Normalise the axis
axis_mag = hypot(_x, _y, _z)
_x, _y, _z = _x / axis_mag, _y / axis_mag, _z / axis_mag

# Remap the axis to match the kit's coordinate system
x, y, z = -_x, _y, -_z

# Calculate the intrinsic Tait-Bryan angles following the z-y'-x'' convention
# Approximately https://w.wiki/7cuk with some sign corrections,
# adapted to axis-angle and simplified
yaw = atan2(
    z * sin(angle) + x * y * (cos(angle) - 1),
    1 + (y ** 2 + z ** 2) * (cos(angle) - 1),
)
pitch = asin(x * z * (1 - cos(angle)) + y * sin(angle))
roll = atan2(
    x * sin(angle) + y * z * (cos(angle) - 1),
    1 + (x ** 2 + y ** 2) * (cos(angle) - 1),
)
PeterJCLaw commented 10 months ago

I'm going to merge this for speed and to unblock other things. Happy to continue to discuss/address things though.