blob: df4d4502272f1c05cc4b8bd88b7978ed1d08f304 [file] [log] [blame]
Brian Silverman6ae77dd2013-03-29 22:28:08 -07001#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include <sys/mman.h>
5#include <errno.h>
6#include <string.h>
7#include <vector>
8#include <netinet/in.h>
9#include <netinet/tcp.h>
10#include <arpa/inet.h>
11#include "opencv2/opencv.hpp"
12
13#include "aos/common/time.h"
14#include "aos/atom_code/camera/Buffers.h"
15#include "aos/externals/libjpeg/include/jpeglib.h"
Brian Silverman5b3e51e2013-03-29 22:53:44 -070016#include "aos/atom_code/init.h"
Austin Schuh86bec782013-04-04 05:50:52 +000017#include "aos/common/logging/logging.h"
Brian Silverman6ae77dd2013-03-29 22:28:08 -070018
19#include "vision/OpenCVWorkTask.h"
20#include "vision/CameraProcessor.h"
21#include "vision/BinaryServer.h"
22#include "vision/PacketNotifier.h"
23#include "vision/JPEGRoutines.h"
24
25
Brian Silverman6ae77dd2013-03-29 22:28:08 -070026namespace frc971 {
27namespace vision {
28
29} // namespace vision
30} // namespace frc971
31
32void reciever_main(frc971::vision::PacketNotifier *notify){
33 frc971::vision::BinaryServer test(8020,notify);
34}
35
Austin Schuh86bec782013-04-04 05:50:52 +000036namespace {
37void SaveImageToFile(IplImage *image, const char *filename) {
38 FILE *file = fopen(filename, "w");
39
40 fputs("P3\n320 240\n255\n", file);
41 ::cv::Mat img(image);
42 for (int i = 0; i < img.rows; i++) {
43 for (int j = 0; j < img.cols; j++) {
44 // You can now access the pixel value with cv::Vec3b
45 fprintf(file, "%d %d %d ",
46 img.at<cv::Vec3b>(i,j)[0],
47 img.at<cv::Vec3b>(i,j)[1],
48 img.at<cv::Vec3b>(i,j)[2]);
49
50 }
51 fputs("\n", file);
52 }
53 fclose(file);
54}
55}
56
Brian Silverman6ae77dd2013-03-29 22:28:08 -070057#include "frc971/queues/CameraTarget.q.h"
58using frc971::vision::targets;
59
60#include <iostream>
61void sender_main(frc971::vision::PacketNotifier *notify){
62 ::aos::InitNRT();
63 ::aos::camera::Buffers buffers;
64 CvSize size;
65 size.width = ::aos::camera::Buffers::Buffers::kWidth;
66 size.height = ::aos::camera::Buffers::Buffers::kHeight;
67
68 // create processing object
69 ProcessorData processor(size.width, size.height, false);
70
71 printf("started sender main\n");
Austin Schuh86bec782013-04-04 05:50:52 +000072 LOG(INFO, "Camera server started\n");
Brian Silverman6ae77dd2013-03-29 22:28:08 -070073 while(true){
74 //usleep(7500);
75 size_t data_size;
76 timeval timestamp_timeval;
77 const void *image = buffers.GetNext(
Austin Schuh86bec782013-04-04 05:50:52 +000078 true, &data_size, &timestamp_timeval, NULL);
79 ::aos::time::Time timestamp(timestamp_timeval);
Brian Silverman6ae77dd2013-03-29 22:28:08 -070080
81 //TODO(pschuh): find proper way to cast away const for this: :(
Austin Schuh86bec782013-04-04 05:50:52 +000082 // parker you prolly want const_cast<type>(var);
83 LOG(INFO, "Got new image\n");
Brian Silverman6ae77dd2013-03-29 22:28:08 -070084 unsigned char *buffer = (unsigned char *)notify->GetBuffer();
Austin Schuh86bec782013-04-04 05:50:52 +000085 frc971::vision::process_jpeg(buffer, (unsigned char *)image, data_size);
86
Brian Silverman6ae77dd2013-03-29 22:28:08 -070087 // build the headers on top of the buffer
Austin Schuh86bec782013-04-04 05:50:52 +000088 cvSetData(processor.src_header_image,
89 buffer,
90 ::aos::camera::Buffers::Buffers::kWidth * 3);
Brian Silverman6ae77dd2013-03-29 22:28:08 -070091
Austin Schuh86bec782013-04-04 05:50:52 +000092 // Reset.
93 processor.clear();
94 // transform the buffer into targets
95 processor.threshold(buffer);
Brian Silverman6ae77dd2013-03-29 22:28:08 -070096
Austin Schuh86bec782013-04-04 05:50:52 +000097 processor.getContours();
98 processor.filterToTargets();
99
100 // could be used for debug ie drawContours
101 //std::vector<std::vector<cv::Point> > target_contours;
102 //std::vector<std::vector<cv::Point> > best_contours;
103 std::vector<Target>::iterator target_it;
104 Target *best_target = NULL;
105 // run through the targets
106 LOG(INFO, "Found %u targets\n", processor.target_list.size());
107 for(target_it = processor.target_list.begin();
108 target_it != processor.target_list.end(); target_it++){
109 //target_contours.push_back(*(target_it->this_contour));
110 // select the highest target
111 if (best_target == NULL) {
112 best_target = &*target_it;
113 } else {
114 if (target_it->height < best_target->height) {
115 best_target = &*target_it;
116 }
117 }
118 }
119 // if we found one then send it on
120 if (best_target != NULL) {
121 LOG(INFO, "Target is %f\n", best_target->rect.centroid.x);
122 targets.MakeWithBuilder()
123 .percent_azimuth_off_center(
124 best_target->rect.centroid.y / (double)::aos::camera::Buffers::kHeight - 0.5)
125 .percent_elevation_off_center(
126 best_target->rect.centroid.x / (double)::aos::camera::Buffers::kWidth - 0.5)
127 .timestamp(timestamp.ToNSec())
128 .Send();
Brian Silverman6ae77dd2013-03-29 22:28:08 -0700129 }
130 notify->Notify();
Austin Schuh86bec782013-04-04 05:50:52 +0000131 //static int counter = 0;
132 //if (++counter > 2) {
133 //break;
134 //}
Brian Silverman6ae77dd2013-03-29 22:28:08 -0700135 }
136 ::aos::Cleanup();
137}
138
139
140int main(int /*argc*/, char** /*argv*/){
141 frc971::vision::PacketNotifier *notify = frc971::vision::PacketNotifier::MMap(
142 ::aos::camera::Buffers::kHeight * ::aos::camera::Buffers::kWidth * 3);
143 pid_t pid = fork();
144 if(pid < 0){
145 fprintf(stderr,"%s:%d: Error in fork()\n",__FILE__,__LINE__);
146 }
147 if(pid == 0){
148 notify->RegisterSender();
149 sender_main(notify);
150 }else{
151 notify->RegisterReciever();
152 reciever_main(notify);
153 }
154}
155