Skip to content

Commit b3a0a47

Browse files
committed
First parse at top level vision page
1 parent a6d0fef commit b3a0a47

File tree

1 file changed

+83
-216
lines changed

1 file changed

+83
-216
lines changed

programming/vision/index.md

Lines changed: 83 additions & 216 deletions
Original file line numberDiff line numberDiff line change
@@ -6,69 +6,53 @@ title: Vision
66
Vision
77
======
88

9-
The `sr.robot3` library contains support for detecting fiducial markers with the provided webcam.
10-
Markers are attached to various items in the Student Robotics arena.
11-
Each marker encodes a number in a machine-readable way, which means that robots can identify these objects.
12-
For information on which markers codes are which, see the [markers page](./markers).
9+
Your robot is able to use a webcam to detect [fiducial markers](https://en.wikipedia.org/wiki/Fiducial_marker).
10+
Specifically it can detect [AprilTags](https://april.eecs.umich.edu/software/apriltag), using the `36H11` marker set.
1311

14-
Using knowledge of the physical size of the different markers and the characteristics of the webcam,
15-
your robot can calculate the position of markers in 3D space relative to the camera.
16-
Therefore, if the robot can see a marker that is at a fixed location in the arena,
17-
a robot can calculate its exact position in the arena.
12+
Each marker is unique and encodes a number in a machine-readable way, which means that robots can identify these objects.
1813

19-
Under the hood, the vision system is based on [AprilTag](https://april.eecs.umich.edu/software/apriltag/) and [OpenCV](https://opencv.org), using the `36H11` marker set.
14+
Using [Pose Estimation](https://en.wikipedia.org/wiki/3D_pose_estimation), it can calculate the orientation and position of the marker relative to the webcam.
15+
Markers are attached to various items in the Student Robotics arena, in known locations.
16+
Using the marker poses and their locations, we can either calculate the location of object relative to the robot or the position of the robot relative to the arena.
17+
18+
For information on markers, see the [markers page](./markers).
2019

2120
[Camera](#camera) {#camera}
2221
===========================
2322

2423
The interface to the vision system is through the camera, accessible through `R.camera`.
2524

2625
see
27-
: Take a photo through the webcam, and return a list of [`Marker`](#Marker) instances, each of which describes one of the markers that were found in the image.
26+
: Take a photo through the webcam, and return a list of [`Marker`](#marker) instances, each of which describes one of the markers that were found in the image.
2827

29-
Here's an example that will repeatedly print out the distance to each arena marker that the robot can see:
28+
Here's an example that will repeatedly print out the distance, in meters, to each marker that the robot can see:
3029

3130
~~~~~ python
3231
from sr.robot3 import *
33-
R = Robot()
32+
robot = Robot()
3433

3534
while True:
36-
markers = R.camera.see()
35+
markers = robot.camera.see()
3736
print("I can see", len(markers), "markers:")
3837

39-
for m in markers:
40-
print(" - Marker #{0} is {1} metres away".format(m.id, m.distance / 1000))
41-
~~~~~
42-
43-
see_ids
44-
: Take a photo through the webcam, and return a list of marker ids (**not** full `Marker` objects). This doesn't do the same [pose estimation](https://en.wikipedia.org/wiki/3D_pose_estimation) calculations as `see`, and so is much faster to run.
45-
46-
~~~~~ python
47-
from sr.robot3 import *
48-
R = Robot()
49-
50-
while True:
51-
marker_ids = R.camera.see_ids()
52-
53-
if 0 in marker_ids:
54-
print("I can see marker 0!")
55-
else:
56-
print("I cannot see marker 0!")
38+
for marker in markers:
39+
print(" - Marker #{0} is {1} metres away".format(marker.id, marker.distance / 1000))
5740
~~~~~
5841

59-
<div class="info" markdown="1">
60-
The simulated camera does not have `capture` or `save` methods.
42+
<div class="info">
43+
Taking images while moving will cause them to be blurry, which will cause marker detection to fail.
44+
Try pausing movement while taking an image.
6145
</div>
6246

6347
save
6448
: Take a photo through the webcam, and save it to the provided location.
6549

6650
~~~~~ python
6751
from sr.robot3 import *
68-
R = Robot()
52+
robot = Robot()
6953

70-
# `R.usbkey` is the path to your USB drive
71-
R.camera.save(R.usbkey / "initial-view.png")
54+
# `robot.usbkey` is the path to your USB drive
55+
robot.camera.save(robot.usbkey / "initial-view.png")
7256
~~~~~
7357

7458
capture
@@ -77,57 +61,52 @@ capture
7761
~~~~~ python
7862
import cv2
7963
from sr.robot3 import *
80-
R = Robot()
64+
robot = Robot()
8165

82-
frame = R.camera.capture()
66+
frame = robot.camera.capture()
8367

8468
# Flip the image with OpenCV
8569
flipped = cv2.flip(frame, 0)
8670
~~~~~
8771

88-
[Field of View](#fov) {#fov}
89-
-------------------
72+
[Frame argument](#frame_args) {#frame_args}
73+
-------------------------------------------
9074

91-
The Logitech C500 has a [field of view][fov] of 72&deg; and the C270 has a field of view of 60&deg;.
75+
The slowest part of vision is capturing the image.
76+
You can use a frame with the other vision commands to avoid recapturing.
77+
This may be useful if you wish to use both your own vision algorithms and our marker detection on the same frames.
9278

93-
[fov]: https://en.wikipedia.org/wiki/Field_of_view
79+
~~~~~ python
80+
from sr.robot3 import *
81+
robot = Robot()
9482

95-
[Definition of Axes](#axes) {#axes}
96-
===================================
83+
# Capture an OpenCV frame
84+
frame = robot.camera.capture()
9785

98-
The vision system describes the markers it can see using three coordinate
99-
systems. These are intended to be complementary to each other and contain
100-
the same information in different forms.
86+
# Run marker detection on the captured frame
87+
markers = robot.camera.see(frame=frame)
10188

102-
The axis definitions match those in common use, as follows:
89+
# Save the frame with marker annotation
90+
robot.camera.save("photo.jpg", frame=frame)
10391

104-
x-axis
105-
: The horizontal axis running left-to-right in front of the camera.
106-
Rotation about this axis is equivalent to leaning towards or away from
107-
the camera.
92+
# Do some other vision algorithm with the OpenCV frame here
93+
~~~~~
10894

109-
y-axis
110-
: The vertical axis running top-to-bottom in front of the camera.
111-
Rotation about this axis is equivalent to turning on the spot,
112-
to the left or right.
95+
[Field of View](#fov) {#fov}
96+
----------------------------
11397

114-
z-axis
115-
: The axis leading away from the camera to infinity.
116-
Rotation about this axis is equivalent to being rolled sideways.
98+
The Logitech C500 has a [field of view][fov] of 72&deg; and the C270 has a field of view of 60&deg;.
99+
100+
[fov]: https://en.wikipedia.org/wiki/Field_of_view
117101

118102
<div class="info">
119-
Note that the axes are all defined relative to the camera. Since we have
120-
no way to know how you've mounted your camera, you may need to account
121-
for that in your usage of the vision system's data.
103+
Note that the axes are all defined relative to the camera.
104+
Since we have no way to know how you've mounted your camera, you may need to account for that in your usage of the vision system's data.
122105
</div>
123106

124-
[Objects of the Vision System](#vision_objects) {#vision_objects}
125-
==============================
126-
127-
The vision system is made up of a number of objects, the primary of which is the `Marker`:
107+
[Marker](#marker) {#marker}
108+
===========================
128109

129-
[`Marker`](#Marker) {#Marker}
130-
----------
131110
A `Marker` object contains information about a *detected* marker.
132111
It has the following attributes:
133112

@@ -137,171 +116,59 @@ id
137116
size
138117
: The physical size of the marker, as the vision system expects it.
139118

140-
<div class="info" markdown="1">
141-
Pixel coordinate information is not available in the simulator.
142-
</div>
143-
144119
pixel_centre
145-
: A [`PixelCoordinates`](#PixelCoordinates) describing the position of the centre of the marker.
120+
: A [`PixelCoordinates`](#PixelCoordinates) describing the position of the centre of the marker in the image.
146121

147122
pixel_corners
148-
: A list of 4 [`PixelCoordinates`](#PixelCoordinates) instances, each representing the position of the corners of the marker.
123+
: A list of 4 [`PixelCoordinates`](#PixelCoordinates) instances, each representing the position of a corner of the marker in the image.
149124

150-
distance
151-
: The distance between the camera and the centre of the marker, in millimetres.
125+
position
126+
: A `Position` instance describing the position of the marker.
127+
See the [Position page](./position) for detailed definitions and diagrams.
128+
129+
distance
130+
: The distance between the camera and the centre of the marker, in millimetres.
131+
132+
horizontal_angle
133+
: Horizontal angle from the camera to the marker, in radians.
134+
Ranges -&pi; to &pi;.
135+
Positive to the right.
136+
Directly in front is 0.
137+
138+
vertical_angle
139+
: Vertical angle from the camera to the marker, in radians.
140+
Ranges -&pi; to &pi;.
141+
Positive values upwards.
142+
Directly in front is 0.
152143

153144
orientation
154-
: An [`Orientation`](#Orientation) instance describing the orientation of the marker.
145+
: An `Orientation` instance describing the orientation of the marker.
146+
See the [Orientation page](./orientation) for detailed definitions and diagrams.
147+
148+
yaw
149+
: The Yaw of the marker, a rotation about the vertical axis, in radians.
150+
Positive values indicate a rotation clockwise from the perspective of the marker.
151+
Zero values have the marker facing the camera square-on.
155152

156-
spherical
157-
: A [`SphericalCoordinate`](#SphericalCoordinate) instance describing the position of the marker relative to the camera.
153+
pitch
154+
: The Pitch of the marker, a rotation about the transverse axis, in radians.
155+
Positive values indicate a rotation upwards from the perspective of the marker.
156+
Zero values have the marker facing the camera square-on.
157+
158+
roll
159+
: The Roll of the marker, a rotation about the longitudinal axis, in radians.
160+
Positive values indicate a rotation clockwise from the perspective of the marker.
161+
Zero values have the marker facing the camera square-on.
158162

159-
cartesian
160-
: A [`CartesianCoordinates`](#CartesianCoordinates) instance describing the position of the marker relative to the camera.
161163

162164
<a id="Coordinate"/>
163165

164166
[`PixelCoordinates`](#PixelCoordinates) {#PixelCoordinates}
165167
---------
166168

167-
<div class="info" markdown="1">
168-
Pixel coordinate information is not available in the simulator.
169-
</div>
170-
171169
A named tuple of `x` and `y` coordinates for the point, in pixels relative to the top left of the image.
172170

173171
~~~~~ python
174172
# Print the x and y coordinates of the pixel location
175173
print(marker.pixel_centre.x, marker.pixel_centre.y)
176174
~~~~~
177-
178-
<a id="ThreeDCoordinate"/>
179-
180-
[`CartesianCoordinates`](#CartesianCoordinates) {#CartesianCoordinates}
181-
---------
182-
183-
A named tuple of `x`, `y` and `z` coordinates for the point, in millimeters relative to the camera.
184-
Increasing values are to the right, below and away from the camera respectively.
185-
186-
~~~~~ python
187-
# Print the x, y and z coordinates of the marker's location
188-
print(marker.cartesian.x, marker.cartesian.y, marker.cartesian.z)
189-
~~~~~
190-
191-
[`Orientation`](#Orientation) {#Orientation}
192-
---------------
193-
194-
<div class="info" markdown="1">
195-
Orientation information is returned in different formats between the simulator and the physical robot kits.
196-
One (possibly both) of them may change to resolve this.
197-
198-
In the simulator the `roll`, `pitch` and `yaw` properties are strict aliases for the `rot_x`, `rot_y` and `rot_z` properties.
199-
Additionally the `rotation_matrix` and `quaternion` properties are not present.
200-
</div>
201-
<div class="warning" markdown="1">
202-
There is a bug in the simulator such that the `rot_x` and `rot_z` values are not reliable -- specifically they depend on the orientation of the robot itself within the simulated environment in addition to the orientation of the marker. This is believed to be a bug in Webots simulation software.
203-
</div>
204-
205-
An `Orientation` object describes the orientation of a marker.
206-
207-
rot_x
208-
: Rotation of the marker about the cartesian x-axis, in radians. This is a
209-
pitch-like rotation.
210-
211-
Leaning a marker towards the camera increases the value of `rot_x`, while
212-
leaning it away from the camera decreases it. A value of either π or -π
213-
indicates that the marker is upright (there is a discontinuity in the value
214-
at π and -π, as both values represent the same position).
215-
216-
rot_y
217-
: Rotation of the marker about the cartesian y-axis, in radians. This is a
218-
yaw-like rotation.
219-
220-
Turning a marker clockwise (as viewed from above) decreases the value of
221-
`rot_y`, while turning it anticlockwise increases it. A value of 0 means
222-
that the marker is perpendicular to the line of sight of the camera.
223-
224-
rot_z
225-
: Rotation of the marker about the cartesian z-axis, in radians. This is a
226-
roll-like rotation.
227-
228-
Turning a marker anticlockwise (as viewed from the camera) increases the
229-
value of `rot_z`, while turning it clockwise decreases it. A value of 0
230-
indicates that the marker is upright.
231-
232-
There are additional attributes for the [principal axis rotations](https://en.wikipedia.org/wiki/Aircraft_principal_axes) of the marker.
233-
234-
yaw
235-
: A rotation about the about the vertical axis, in radians (an axis top to
236-
bottom through the token). Turning a marker clockwise (as viewed from above)
237-
increases the value of `yaw`, while turning it anticlockwise decreases it. A
238-
value of 0 means that the marker is perpendicular to the line of sight of
239-
the camera.
240-
241-
This differs from `rot_y` in the direction that increases the value.
242-
243-
pitch
244-
: A rotation about the transverse axis, in radians (an axis right to left
245-
across the token). Tilting the marker backward increases the value of
246-
`pitch`, while tilting it forwards decreases it. A value of 0 indicates that
247-
the marker is facing the camera square-on.
248-
249-
This differs from `rot_x` in the zero point and direction to increase the value.
250-
251-
roll
252-
: A rotation about the longitudinal axis, in radians (an axis normal from the
253-
apparent front to the back of the token, normal to the marker). Rotating the
254-
marker anti-clockwise (from the perspective of the camera) increases the
255-
value of `roll`, while rotating it clockwise decreases it. A value of 0
256-
indicates that the marker is upright.
257-
258-
This differs from `rot_x` in the zero point and direction to increase the value.
259-
260-
Finally there are attributes which express the orientation in other forms:
261-
262-
rotation_matrix
263-
: The [rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix) represented by this orientation.
264-
This 3×3 matrix is represented by a list of 3 lists, each with 3 values, in an arrangement compatible with tools such as `numpy`.
265-
266-
quaternion
267-
: The [quaternion](https://en.wikipedia.org/wiki/Quaternion) represented by this orientation.
268-
On the physical kits this is implemented as a [`pyquaternion.Quaternion`](https://kieranwynn.github.io/pyquaternion/#quaternion-features) instance.
269-
270-
<a id="Spherical"/>
271-
272-
[`SphericalCoordinate`](#SphericalCoordinate) {#SphericalCoordinate}
273-
---------------
274-
275-
<div class="info" markdown="1">
276-
Spherical coordinate information is returned in different formats between the simulator and the physical robot kits.
277-
278-
The simulator does not provide the `theta` or `phi` values and the values for `rot_x` and `rot_y` may be slightly different for equivalent positions.
279-
</div>
280-
281-
The spherical coordinates system has three values to specify a specific point in space.
282-
283-
distance
284-
: The radial distance, the distance from the origin to the point, in millimetres.
285-
286-
theta
287-
: This is the angle from directly in front of the camera to the vector which
288-
points to the location in the horizontal plane, in radians. A positive value
289-
indicates a counter-clockwise rotation. Zero is at the centre of the image.
290-
291-
phi
292-
: The polar angle from the y-axis of the camera "down" to the vector which
293-
points to the location, in radians. Zero is directly upward.
294-
295-
Also available are two computed angles which express the same location slightly differently:
296-
297-
rot_x
298-
: Approximate rotation around the X-axis, in radians.
299-
This is the angle from the camera's horizontal plane to the vector which
300-
points to the location. Zero is at the centre of the image. Values increase
301-
towards the bottom of the image.
302-
303-
rot_y
304-
: Rotation around the Y-axis, in radians. This is similar to `theta`, however
305-
values increase towards the right of the image. Zero is at the centre of the image.
306-
307-
The camera is located at the origin, where the coordinates are (0, 0, 0).

0 commit comments

Comments
 (0)