blob: b3c56aeccb1e956e77f477977ac844cf3adfc5a5 [file] [log] [blame]
Brian Silverman2ccf8c52016-03-15 00:22:26 -04001#include <stdlib.h>
2#include <netdb.h>
3#include <unistd.h>
4
5#include <vector>
6#include <memory>
7
8#include "aos/linux_code/init.h"
9#include "aos/common/time.h"
10#include "aos/common/logging/logging.h"
11#include "aos/common/logging/queue_logging.h"
12#include "aos/vision/events/udp.h"
13
14#include "y2016/vision/vision.q.h"
15#include "y2016/vision/vision_data.pb.h"
16#include "y2016/vision/stereo_geometry.h"
17#include "y2016/constants.h"
18
19namespace y2016 {
20namespace vision {
21
22void Main() {
23 StereoGeometry stereo(constants::GetValues().vision_name);
24 LOG(INFO, "calibration: %s\n",
25 stereo.calibration().ShortDebugString().c_str());
Brian Silverman2ccf8c52016-03-15 00:22:26 -040026
Austin Schuhc65b0ea2016-03-16 22:09:19 -070027 VisionData left_target;
28 aos::time::Time left_rx_time{0, 0};
29
30 VisionData right_target;
31 aos::time::Time right_rx_time{0, 0};
32
33 ::aos::vision::RXUdpSocket recv(8080);
34 char rawData[65507];
35 bool got_left = false;
36 bool got_right = false;
37
38 while (true) {
39 // TODO(austin): Don't malloc.
40 VisionData target;
41 int size = recv.Recv(rawData, 65507);
42 aos::time::Time now = aos::time::Time::Now();
43
44 if (target.ParseFromArray(rawData, size)) {
45 if (target.camera_index() == 0) {
46 left_target = target;
47 left_rx_time = now;
48 got_left = true;
49 } else {
50 right_target = target;
51 right_rx_time = now;
Brian Silverman2ccf8c52016-03-15 00:22:26 -040052 got_right = true;
53 }
54 } else {
Austin Schuhc65b0ea2016-03-16 22:09:19 -070055 LOG(ERROR, "oh noes: parse error\n");
56 continue;
57 }
58
59 if (now > left_rx_time + aos::time::Time::InMS(50)) {
60 got_left = false;
61 }
62 if (now > right_rx_time + aos::time::Time::InMS(50)) {
63 got_right = false;
Brian Silverman2ccf8c52016-03-15 00:22:26 -040064 }
65
66 if (got_left && got_right) {
Austin Schuhc65b0ea2016-03-16 22:09:19 -070067 bool left_image_valid = left_target.target_size() > 0;
68 bool right_image_valid = right_target.target_size() > 0;
69
Brian Silverman2ccf8c52016-03-15 00:22:26 -040070 auto new_vision_status = vision_status.MakeMessage();
Austin Schuhc65b0ea2016-03-16 22:09:19 -070071 new_vision_status->left_image_valid = left_image_valid;
72 new_vision_status->right_image_valid = right_image_valid;
73 if (left_image_valid && right_image_valid) {
74 const ::aos::vision::Vector<2> center0(
75 (left_target.target(0).left_corner_x() +
76 left_target.target(0).right_corner_x()) /
77 2.0,
78 (left_target.target(0).left_corner_y() +
79 left_target.target(0).right_corner_y()) /
80 2.0);
81 // out of sync.
82 const ::aos::vision::Vector<2> center1(
83 (right_target.target(0).left_corner_x() +
84 right_target.target(0).right_corner_x()) /
85 2.0,
86 (right_target.target(0).left_corner_y() +
87 right_target.target(0).right_corner_y()) /
88 2.0);
89 double distance, horizontal_angle, vertical_angle;
90 stereo.Process(center0, center1, &distance, &horizontal_angle,
91 &vertical_angle);
92 new_vision_status->left_image_timestamp = left_target.image_timestamp();
93 new_vision_status->right_image_timestamp = right_target.image_timestamp();
94 new_vision_status->left_send_timestamp = left_target.send_timestamp();
95 new_vision_status->right_send_timestamp = right_target.send_timestamp();
96 new_vision_status->horizontal_angle = horizontal_angle;
97 new_vision_status->vertical_angle = vertical_angle;
98 new_vision_status->distance = distance;
99 }
Brian Silverman2ccf8c52016-03-15 00:22:26 -0400100 LOG_STRUCT(DEBUG, "vision", *new_vision_status);
101
102 if (!new_vision_status.Send()) {
103 LOG(ERROR, "Failed to send vision information\n");
104 }
105 }
Austin Schuhc65b0ea2016-03-16 22:09:19 -0700106
107 if (target.camera_index() == 0) {
108 LOG(DEBUG, "left_target: %s\n", left_target.ShortDebugString().c_str());
109 } else {
110 LOG(DEBUG, "right_target: %s\n", right_target.ShortDebugString().c_str());
111 }
Brian Silverman2ccf8c52016-03-15 00:22:26 -0400112 }
113}
114
115} // namespace vision
116} // namespace y2016
117
118int main(int /*argc*/, char ** /*argv*/) {
119 ::aos::InitNRT();
120 ::y2016::vision::Main();
121}