gucoordinates
conversions_tests.cc
Go to the documentation of this file.
1/*
2 * conversions_tests.cc
3 * tests
4 *
5 * Created by Callum McColl on 18/06/2020.
6 * Copyright © 2020 Callum McColl. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials
18 * provided with the distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgement:
22 *
23 * This product includes software developed by Callum McColl.
24 *
25 * 4. Neither the name of the author nor the names of contributors
26 * may be used to endorse or promote products derived from this
27 * software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
33 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
37 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * -----------------------------------------------------------------------
42 * This program is free software; you can redistribute it and/or
43 * modify it under the above terms or under the terms of the GNU
44 * General Public License as published by the Free Software Foundation;
45 * either version 2 of the License, or (at your option) any later version.
46 *
47 * This program is distributed in the hope that it will be useful,
48 * but WITHOUT ANY WARRANTY; without even the implied warranty of
49 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50 * GNU General Public License for more details.
51 *
52 * You should have received a copy of the GNU General Public License
53 * along with this program; if not, see http://www.gnu.org/licenses/
54 * or write to the Free Software Foundation, Inc., 51 Franklin Street,
55 * Fifth Floor, Boston, MA 02110-1301, USA.
56 *
57 */
58
60
61#include <stdio.h>
62
63namespace CGTEST {
64
66
67 TEST_F(ConversionsTests, ConvertsToCorrectPercentCoordinate) {
68 const gu_pixel_coordinate topLeftEdge = { -959, 540, 1920, 1080 };
69 const gu_pixel_coordinate topRightEdge = { 960, 540, 1920, 1080 };
70 const gu_pixel_coordinate bottomLeftEdge = { -959, -539, 1920, 1080 };
71 const gu_pixel_coordinate bottomRightEdge = { 960, -539, 1920, 1080 };
72 const gu_pixel_coordinate middle = { 0, 0, 1920, 1080 };
73 percent_equal((gu_percent_coordinate) {-1.0, 1.0}, px_coord_to_pct_coord(topLeftEdge));
74 percent_equal((gu_percent_coordinate) {1.0, 1.0}, px_coord_to_pct_coord(topRightEdge));
75 percent_equal((gu_percent_coordinate) {-1.0, -1.0}, px_coord_to_pct_coord(bottomLeftEdge));
76 percent_equal((gu_percent_coordinate) {1.0, -1.0}, px_coord_to_pct_coord(bottomRightEdge));
77 percent_near((gu_percent_coordinate) {0.0, 0.0}, px_coord_to_pct_coord(middle));
78 }
79
80 TEST_F(ConversionsTests, ConvertsToCorrectPixelCoordinate) {
81 const gu_percent_coordinate topLeftEdge = { -1.0, 1.0 };
82 const gu_percent_coordinate topRightEdge = { 1.0, 1.0 };
83 const gu_percent_coordinate bottomLeftEdge = { -1.0, -1.0 };
84 const gu_percent_coordinate bottomRightEdge = { 1.0, -1.0 };
85 const gu_percent_coordinate middle = { 0, 0 };
86 pixel_equal((gu_pixel_coordinate) { -959, 540, 1920, 1080 }, pct_coord_to_px_coord(topLeftEdge, 1920, 1080));
87 pixel_equal((gu_pixel_coordinate) { 960, 540, 1920, 1080 }, pct_coord_to_px_coord(topRightEdge, 1920, 1080));
88 pixel_equal((gu_pixel_coordinate) { -959, -539, 1920, 1080 }, pct_coord_to_px_coord(bottomLeftEdge, 1920, 1080));
89 pixel_equal((gu_pixel_coordinate) { 960, -539, 1920, 1080 }, pct_coord_to_px_coord(bottomRightEdge, 1920, 1080));
90 pixel_equal((gu_pixel_coordinate) { 1, 1, 1920, 1080 }, pct_coord_to_px_coord(middle, 1920, 1080));
91 }
92
93 TEST_F(ConversionsTests, ConvertsFromCameraToPixelCoordinate) {
94 const gu_camera_coordinate topLeftEdge = { 0, 0, 1920, 1080 };
95 const gu_camera_coordinate topRightEdge = { 1919, 0, 1920, 1080 };
96 const gu_camera_coordinate bottomLeftEdge = { 0, 1079, 1920, 1080 };
97 const gu_camera_coordinate bottomRightEdge = { 1919, 1079, 1920, 1080 };
98 const gu_pixel_coordinate ptopLeftEdge = { -959, 540, 1920, 1080 };
99 const gu_pixel_coordinate ptopRightEdge = { 960, 540, 1920, 1080 };
100 const gu_pixel_coordinate pbottomLeftEdge = { -959, -539, 1920, 1080 };
101 const gu_pixel_coordinate pbottomRightEdge = { 960, -539, 1920, 1080 };
102 const gu_pixel_coordinate otopLeftEdge = cam_coord_to_px_coord(topLeftEdge);
103 const gu_pixel_coordinate otopRightEdge = cam_coord_to_px_coord(topRightEdge);
104 const gu_pixel_coordinate obottomLeftEdge = cam_coord_to_px_coord(bottomLeftEdge);
105 const gu_pixel_coordinate obottomRightEdge = cam_coord_to_px_coord(bottomRightEdge);
106 pixel_equal(ptopLeftEdge, otopLeftEdge);
107 pixel_equal(ptopRightEdge, otopRightEdge);
108 pixel_equal(pbottomLeftEdge, obottomLeftEdge);
109 pixel_equal(pbottomRightEdge, obottomRightEdge);
110 }
111
112 TEST_F(ConversionsTests, ConvertsFromPixelToCameraCoordinate) {
113 const gu_camera_coordinate topLeftEdge = { 0, 0, 1920, 1080 };
114 const gu_camera_coordinate topRightEdge = { 1919, 0, 1920, 1080 };
115 const gu_camera_coordinate bottomLeftEdge = { 0, 1079, 1920, 1080 };
116 const gu_camera_coordinate bottomRightEdge = { 1919, 1079, 1920, 1080 };
117 const gu_pixel_coordinate ptopLeftEdge = { -959, 540, 1920, 1080 };
118 const gu_pixel_coordinate ptopRightEdge = { 960, 540, 1920, 1080 };
119 const gu_pixel_coordinate pbottomLeftEdge = { -959, -539, 1920, 1080 };
120 const gu_pixel_coordinate pbottomRightEdge = { 960, -539, 1920, 1080 };
121 const gu_camera_coordinate otopLeftEdge = px_coord_to_cam_coord(ptopLeftEdge);
122 const gu_camera_coordinate otopRightEdge = px_coord_to_cam_coord(ptopRightEdge);
123 const gu_camera_coordinate obottomLeftEdge = px_coord_to_cam_coord(pbottomLeftEdge);
124 const gu_camera_coordinate obottomRightEdge = px_coord_to_cam_coord(pbottomRightEdge);
125 camera_equal(topLeftEdge, otopLeftEdge);
126 camera_equal(topRightEdge, otopRightEdge);
127 camera_equal(bottomLeftEdge, obottomLeftEdge);
128 camera_equal(bottomRightEdge, obottomRightEdge);
129 }
130
131 TEST_F(ConversionsTests, ConvertsFromPercentToRelativeCoordinate) {
132 const gu_percent_coordinate centrePoint = { 0.0, 0.0};
133 const gu_camera_pivot camera_pivot = GU_NAO_V5_HEAD(5.0, 0.0);
134 const gu_relative_coordinate result = pct_coord_to_rr_coord(centrePoint, camera_pivot, 0);
135 ASSERT_EQ(result.distance, 4316);
136 ASSERT_EQ(result.direction, 0);
137 }
138
139 TEST_F(ConversionsTests, ConvertsFromPercentToRelativeCoordinate3) {
140 const gu_percent_coordinate centrePoint = {0.0, 0.5};
141 const gu_camera_pivot camera_pivot = GU_NAO_V5_HEAD(15.0, 0.0);
142 const gu_relative_coordinate result = pct_coord_to_rr_coord(centrePoint, camera_pivot, 0);
143 ASSERT_EQ(result.distance, 6117);
144 ASSERT_EQ(result.direction, 0);
145 }
146
147 TEST_F(ConversionsTests, ConvertsFromRelativeCoordinateToPercent) {
148 const gu_relative_coordinate coord = { 0.0, 4300 };
149 const gu_camera_pivot camera_pivot = GU_NAO_V5_HEAD(5.0, 0.0);
150 const gu_percent_coordinate result = rr_coord_to_pct_coord(coord, camera_pivot, 0);
151 ASSERT_TRUE((result.x - 0.0) < 0.01);
152 ASSERT_TRUE((result.y - 0.0) < 0.01);
153 }
154
155 TEST_F(ConversionsTests, ConvertsFromRelativeCoordinateToPercent2) {
156 const gu_relative_coordinate coord = { 0.0, 1530 };
157 const gu_camera_pivot camera_pivot = GU_NAO_V5_HEAD(15.0, 0.0);
158 const gu_percent_coordinate result = rr_coord_to_pct_coord(coord, camera_pivot, 0);
159 ASSERT_LT((result.x - 0.0), 0.01);
160 ASSERT_LT((result.y - 0.0), 0.01);
161 }
162
163 TEST_F(ConversionsTests, ConvertsFromRelativeCoordinateToPercent3) {
164 const gu_relative_coordinate coord = { 0.0, 6290};
165 const gu_camera_pivot camera_pivot = GU_NAO_V5_HEAD(15.0, 0.0);
166 const gu_percent_coordinate result = rr_coord_to_pct_coord(coord, camera_pivot, 0);
167 ASSERT_LT((result.x - 0.0), 0.01);
168 ASSERT_LT((result.y - 0.5), 0.01);
169 }
170
171 TEST_F(ConversionsTests, ConvertsFromRelativeCoordinateToPercentClamped) {
172 const gu_camera topCamera = { 6.364, 5.871, 1.2, 47.64, 60.91 };
173 const gu_camera_pivot pivot = { 0.0, 0.0, 41.7, {topCamera}, 1 };
174 const gu_relative_coordinate coord = { 30, 108 };
175 const gu_percent_coordinate out = clamped_rr_coord_to_pct_coord(coord, pivot, 0);
176 ASSERT_GE(out.x, -1.0);
177 ASSERT_GE(out.y, -1.0);
178 ASSERT_LE(out.x, 1.0);
179 ASSERT_LE(out.y, 1.0);
180 }
181
182 TEST_F(ConversionsTests, ConvertsFromRelativeCoordinateToFieldCoordinate) {
183 const gu_relative_coordinate coord = { .direction = 0.0, .distance = 10 };
184 const gu_field_coordinate target = rr_coord_to_field_coord(coord, 40);
185 ASSERT_EQ(target.position.x, 10);
186 ASSERT_EQ(target.position.y, 0);
187 ASSERT_EQ(target.heading, 40);
188 const gu_relative_coordinate coord2 = { .direction = -45.0, .distance = 20 };
189 const gu_field_coordinate target2 = rr_coord_to_field_coord(coord2, 40);
190 ASSERT_EQ(target2.position.x, 14);
191 ASSERT_EQ(target2.position.y, -14);
192 ASSERT_EQ(target2.heading, 40);
193 const gu_relative_coordinate coord3 = { .direction = -60.0, .distance = 60 };
194 const gu_field_coordinate target3 = rr_coord_to_field_coord(coord3, 12);
195 ASSERT_EQ(target3.position.x, 30);
196 ASSERT_EQ(target3.position.y, -52);
197 ASSERT_EQ(target3.heading, 12);
198 }
199
200 TEST_F(ConversionsTests, ConvertsToRelativeCoordinateFromFieldSource) {
201 const gu_field_coordinate source = { { 10, 10 }, 45 };
202 const gu_relative_coordinate target = { .direction = 45.0, .distance = 50};
203 const gu_field_coordinate coord = rr_coord_to_field_coord_from_source(target, source, 23);
204 ASSERT_EQ(coord.position.x, 10);
205 ASSERT_EQ(coord.position.y, 60);
206 ASSERT_EQ(coord.heading, 23);
207 const gu_relative_coordinate target2 = { .direction = -45.0, .distance = 50 };
208 const gu_field_coordinate coord2 = rr_coord_to_field_coord_from_source(target2, source, 26);
209 ASSERT_EQ(coord2.position.x, 60);
210 ASSERT_EQ(coord2.position.y, 10);
211 ASSERT_EQ(coord2.heading, 26);
212 const gu_relative_coordinate target3 = { .direction = 105.0, .distance = 60 };
213 const gu_field_coordinate coord3 = rr_coord_to_field_coord_from_source(target3, source, -18);
214 ASSERT_EQ(coord3.position.x, -42);
215 ASSERT_EQ(coord3.position.y, 40);
216 ASSERT_EQ(coord3.heading, -18);
217 const gu_relative_coordinate target4 = { .direction = -135.0, .distance = 100 };
218 const gu_field_coordinate coord4 = rr_coord_to_field_coord_from_source(target4, source, 80);
219 ASSERT_EQ(coord4.position.x, 10);
220 ASSERT_EQ(coord4.position.y, -90);
221 ASSERT_EQ(coord4.heading, 80);
222 }
223
224 TEST_F(ConversionsTests, ConvertsFromFieldCoordinateToRelativeCoordinate) {
225 const gu_field_coordinate source = { { 10, 10 }, 45 };
226 const gu_cartesian_coordinate target = { 20, 20 };
227 const gu_relative_coordinate coord = field_coord_to_rr_coord_to_target(source, target);
228 ASSERT_EQ(round(coord.direction), 0.0);
229 ASSERT_EQ(coord.distance, 14);
230 const gu_field_coordinate source2 = { {10, 10}, 90 };
231 const gu_cartesian_coordinate target2 = { 20, 20 };
232 const gu_relative_coordinate result2 = field_coord_to_rr_coord_to_target(source2, target2);
233 ASSERT_EQ(round(result2.direction), -45.0);
234 ASSERT_EQ(result2.distance, 14);
235 const gu_field_coordinate source3 = { {-10, 10}, 90};
236 const gu_cartesian_coordinate target3 = { -20, 20 };
237 const gu_relative_coordinate result3 = field_coord_to_rr_coord_to_target(source3, target3);
238 ASSERT_EQ(round(result3.direction), 45.0);
239 ASSERT_EQ(result3.distance, 14);
240 const gu_field_coordinate source4 = { {-10, 10}, 180};
241 const gu_cartesian_coordinate target4 = { -20, 20 };
242 const gu_relative_coordinate result4 = field_coord_to_rr_coord_to_target(source4, target4);
243 ASSERT_EQ(round(result4.direction), -45.0);
244 ASSERT_EQ(result4.distance, 14);
245 const gu_field_coordinate source5 = { {-10, -10}, 0};
246 const gu_cartesian_coordinate target5 = { -20, -20 };
247 const gu_relative_coordinate result5 = field_coord_to_rr_coord_to_target(source5, target5);
248 ASSERT_EQ(round(result5.direction), -135.0);
249 ASSERT_EQ(result5.distance, 14);
250 const gu_field_coordinate source6 = { {-10, -10}, 90};
251 const gu_cartesian_coordinate target6 = { -20, -20 };
252 const gu_relative_coordinate result6 = field_coord_to_rr_coord_to_target(source6, target6);
253 ASSERT_EQ(round(result6.direction), 135.0);
254 ASSERT_EQ(result6.distance, 14);
255 const gu_field_coordinate source7 = { {-10, -10}, -90};
256 const gu_cartesian_coordinate target7 = { -20, -20 };
257 const gu_relative_coordinate result7 = field_coord_to_rr_coord_to_target(source7, target7);
258 ASSERT_EQ(round(result7.direction), -45.0);
259 ASSERT_EQ(result7.distance, 14);
260 const gu_field_coordinate source8 = { {-10, -10}, -120};
261 const gu_cartesian_coordinate target8 = { -20, -20 };
262 const gu_relative_coordinate result8 = field_coord_to_rr_coord_to_target(source8, target8);
263 ASSERT_EQ(round(result8.direction), -15.0);
264 ASSERT_EQ(result8.distance, 14);
265 const gu_field_coordinate source9 = { {10, -20}, 180};
266 const gu_cartesian_coordinate target9 = { 20, -10 };
267 const gu_relative_coordinate result9 = field_coord_to_rr_coord_to_target(source9, target9);
268 ASSERT_EQ(round(result9.direction), -135.0);
269 ASSERT_EQ(result9.distance, 14);
270 const gu_field_coordinate source10 = { {10, -20}, -60};
271 const gu_cartesian_coordinate target10 = { 20, -10 };
272 const gu_relative_coordinate result10 = field_coord_to_rr_coord_to_target(source10, target10);
273 ASSERT_EQ(round(result10.direction), 105.0);
274 ASSERT_EQ(result10.distance, 14);
275 const gu_field_coordinate source11 = { {30, -70}, 0};
276 const gu_cartesian_coordinate target11 = { -90, 60 };
277 const gu_relative_coordinate result11 = field_coord_to_rr_coord_to_target(source11, target11);
278 ASSERT_EQ(round(result11.direction), 133.0);
279 ASSERT_EQ(result11.distance, 177);
280 const gu_field_coordinate source12 = { {10, 10}, 0};
281 const gu_cartesian_coordinate target12 = { 0, 10 };
282 const gu_relative_coordinate result12 = field_coord_to_rr_coord_to_target(source12, target12);
283 ASSERT_EQ(round(result12.direction), 180.0);
284 ASSERT_EQ(result12.distance, 10);
285 }
286
287 TEST_F(ConversionsTests, ConvertsFromRelativeToCartesianFromSource)
288 {
289 const gu_cartesian_coordinate source = {-900, 1200};
290 const gu_relative_coordinate coord1 = {2.0, 260};
292 ASSERT_EQ(result1.x, -640);
293 ASSERT_EQ(result1.y, 1209);
294
295 const gu_relative_coordinate coord2 = {5.0, 3420};
297 ASSERT_EQ(result2.x, 2507);
298 ASSERT_EQ(result2.y, 1498);
299 }
300
301 TEST_F(ConversionsTests, ConvertesFromCartesianToRelativeFromSource)
302 {
303 const gu_cartesian_coordinate source = {-900, 1200};
304 const gu_cartesian_coordinate coord1 = {-640, 1210};
306 ASSERT_EQ(round(result1.direction), 2.0);
307 ASSERT_EQ(result1.distance, 260);
308
309 const gu_cartesian_coordinate coord2 = {2510, 1500};
311 ASSERT_EQ(round(result2.direction), 5.0);
312 ASSERT_EQ(result2.distance, 3423);
313 }
314
315 TEST_F(ConversionsTests, ConvertsToFieldFromRelativeFromField)
316 {
317 const gu_field_coordinate source = { {-900, 1200}, 70 };
318 const gu_relative_coordinate coord1 = {2.0, 260};
320 ASSERT_EQ(result1.x, -820);
321 ASSERT_EQ(result1.y, 1447);
322
323 const gu_relative_coordinate coord2 = {5.0, 3420};
325 ASSERT_EQ(result2.x, -15);
326 ASSERT_EQ(result2.y, 4503);
327 }
328
329 TEST_F(ConversionsTests, ConvertsToRelativeFromFieldToTarget)
330 {
331 const gu_field_coordinate source = { {-900, 1200}, 70 };
332 const gu_cartesian_coordinate coord1 = {0, 4500};
333 const gu_relative_coordinate result1 = field_coord_to_rr_coord_to_target(source, coord1);
334 ASSERT_EQ(round(result1.direction), 5.0);
335 ASSERT_EQ(result1.distance, 3421);
336 }
337
338} // namespace
gu_percent_coordinate px_coord_to_pct_coord(const gu_pixel_coordinate coord)
Definition: conversions.c:95
gu_percent_coordinate clamped_rr_coord_to_pct_coord(const gu_relative_coordinate coord, const gu_camera_pivot camera_pivot, const int cameraOffset)
Definition: conversions.c:157
gu_relative_coordinate cartesian_coord_to_rr_coord_from_source(const gu_cartesian_coordinate source, const gu_cartesian_coordinate target)
Definition: conversions.c:226
gu_cartesian_coordinate rr_coord_to_cartesian_coord_from_source(const gu_relative_coordinate coord, const gu_cartesian_coordinate source)
Definition: conversions.c:188
gu_field_coordinate rr_coord_to_field_coord_from_source(const gu_relative_coordinate coord, const gu_field_coordinate source, const degrees_t heading)
Definition: conversions.c:211
gu_camera_coordinate px_coord_to_cam_coord(const gu_pixel_coordinate coord)
Definition: conversions.c:85
gu_pixel_coordinate pct_coord_to_px_coord(const gu_percent_coordinate coord, const pixels_u res_width, const pixels_u res_height)
Definition: conversions.c:105
gu_cartesian_coordinate rr_coord_to_cartesian_coord_from_field(const gu_relative_coordinate coord, const gu_field_coordinate source)
Definition: conversions.c:196
gu_relative_coordinate pct_coord_to_rr_coord(const gu_percent_coordinate coord, const gu_camera_pivot camera_pivot, const int cameraOffset)
Definition: conversions.c:115
gu_pixel_coordinate cam_coord_to_px_coord(const gu_camera_coordinate coord)
Definition: conversions.c:75
gu_percent_coordinate rr_coord_to_pct_coord(const gu_relative_coordinate coord, const gu_camera_pivot camera_pivot, const int cameraOffset)
Definition: conversions.c:142
gu_relative_coordinate field_coord_to_rr_coord_to_target(const gu_field_coordinate source, const gu_cartesian_coordinate target)
Definition: conversions.c:237
gu_field_coordinate rr_coord_to_field_coord(const gu_relative_coordinate coord, const degrees_t heading)
Definition: conversions.c:202
#define GU_NAO_V5_HEAD(p, y)
TEST_F(CameraCoordinateTests, Equality)
A gu_camera_coordinate represents the coordinate of a pixel within an image where the (0,...
A gu_camera_pivot represents the pivot point which a gu_camera is attached to.
Definition: camera_pivot.h:87
A cartesian_coordinate is a general coordinate for representing positions on a tow dimensional plane.
millimetres_t y
The y coordinate of the position in centimetres.
millimetres_t x
The x coordinate of the position in centimetres.
A field_coordinate is a coordinate for an object that faces a certain direction (such as a robot) on ...
degrees_t heading
The direction where the object is facing.
gu_cartesian_coordinate position
The position of the object on the field.
A gu_percent_coordinate represents the coordinate of a pixel within an image.
percent_d y
The y coordinate of the pixel within the image as a percentage.
percent_d x
The x coordinate of the pixel within the image as a percentage.
A gu_pixel_coordinate represents the coordinate of a pixel within an image.
A coordinate that is relative to some other coordinate.
degrees_d direction
The heading towards the coordinate.
millimetres_u distance
The distance to the coordinate.