blob: 9d680654dcc925184c1c48e3f0fcdebcce6ea459 [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>
Brian Silverman6ae77dd2013-03-29 22:28:08 -070011
12#include "aos/common/time.h"
13#include "aos/atom_code/camera/Buffers.h"
14#include "aos/externals/libjpeg/include/jpeglib.h"
Brian Silverman5b3e51e2013-03-29 22:53:44 -070015#include "aos/atom_code/init.h"
Austin Schuh86bec782013-04-04 05:50:52 +000016#include "aos/common/logging/logging.h"
Brian Silverman6ae77dd2013-03-29 22:28:08 -070017
18#include "vision/OpenCVWorkTask.h"
19#include "vision/CameraProcessor.h"
20#include "vision/BinaryServer.h"
21#include "vision/PacketNotifier.h"
22#include "vision/JPEGRoutines.h"
23
24
Brian Silverman6ae77dd2013-03-29 22:28:08 -070025namespace frc971 {
26namespace vision {
27
28} // namespace vision
29} // namespace frc971
30
31void reciever_main(frc971::vision::PacketNotifier *notify){
32 frc971::vision::BinaryServer test(8020,notify);
33}
34
Austin Schuh86bec782013-04-04 05:50:52 +000035namespace {
36void SaveImageToFile(IplImage *image, const char *filename) {
37 FILE *file = fopen(filename, "w");
38
39 fputs("P3\n320 240\n255\n", file);
40 ::cv::Mat img(image);
41 for (int i = 0; i < img.rows; i++) {
42 for (int j = 0; j < img.cols; j++) {
43 // You can now access the pixel value with cv::Vec3b
44 fprintf(file, "%d %d %d ",
45 img.at<cv::Vec3b>(i,j)[0],
46 img.at<cv::Vec3b>(i,j)[1],
47 img.at<cv::Vec3b>(i,j)[2]);
48
49 }
50 fputs("\n", file);
51 }
52 fclose(file);
53}
54}
55
Brian Silverman6ae77dd2013-03-29 22:28:08 -070056#include "frc971/queues/CameraTarget.q.h"
57using frc971::vision::targets;
58
59#include <iostream>
60void sender_main(frc971::vision::PacketNotifier *notify){
61 ::aos::InitNRT();
62 ::aos::camera::Buffers buffers;
63 CvSize size;
64 size.width = ::aos::camera::Buffers::Buffers::kWidth;
65 size.height = ::aos::camera::Buffers::Buffers::kHeight;
66
67 // create processing object
68 ProcessorData processor(size.width, size.height, false);
69
70 printf("started sender main\n");
Austin Schuh86bec782013-04-04 05:50:52 +000071 LOG(INFO, "Camera server started\n");
Brian Silverman6ae77dd2013-03-29 22:28:08 -070072 while(true){
73 //usleep(7500);
74 size_t data_size;
75 timeval timestamp_timeval;
76 const void *image = buffers.GetNext(
Austin Schuh86bec782013-04-04 05:50:52 +000077 true, &data_size, &timestamp_timeval, NULL);
78 ::aos::time::Time timestamp(timestamp_timeval);
Brian Silverman6ae77dd2013-03-29 22:28:08 -070079
80 //TODO(pschuh): find proper way to cast away const for this: :(
Austin Schuh86bec782013-04-04 05:50:52 +000081 // parker you prolly want const_cast<type>(var);
82 LOG(INFO, "Got new image\n");
Brian Silverman6ae77dd2013-03-29 22:28:08 -070083 unsigned char *buffer = (unsigned char *)notify->GetBuffer();
Brian Silverman88da2062013-08-28 16:22:31 -070084 frc971::vision::process_jpeg(buffer,
85 (unsigned char *)const_cast<void *>(image),
86 data_size);
Austin Schuh86bec782013-04-04 05:50:52 +000087
Brian Silverman6ae77dd2013-03-29 22:28:08 -070088 // build the headers on top of the buffer
Austin Schuh86bec782013-04-04 05:50:52 +000089 cvSetData(processor.src_header_image,
90 buffer,
91 ::aos::camera::Buffers::Buffers::kWidth * 3);
Brian Silverman6ae77dd2013-03-29 22:28:08 -070092
Austin Schuh86bec782013-04-04 05:50:52 +000093 // Reset.
94 processor.clear();
95 // transform the buffer into targets
96 processor.threshold(buffer);
Brian Silverman6ae77dd2013-03-29 22:28:08 -070097
Austin Schuh86bec782013-04-04 05:50:52 +000098 processor.getContours();
99 processor.filterToTargets();
100
101 // could be used for debug ie drawContours
102 //std::vector<std::vector<cv::Point> > target_contours;
103 //std::vector<std::vector<cv::Point> > best_contours;
104 std::vector<Target>::iterator target_it;
105 Target *best_target = NULL;
106 // run through the targets
107 LOG(INFO, "Found %u targets\n", processor.target_list.size());
108 for(target_it = processor.target_list.begin();
109 target_it != processor.target_list.end(); target_it++){
110 //target_contours.push_back(*(target_it->this_contour));
111 // select the highest target
112 if (best_target == NULL) {
113 best_target = &*target_it;
114 } else {
115 if (target_it->height < best_target->height) {
116 best_target = &*target_it;
117 }
118 }
119 }
120 // if we found one then send it on
121 if (best_target != NULL) {
122 LOG(INFO, "Target is %f\n", best_target->rect.centroid.x);
123 targets.MakeWithBuilder()
124 .percent_azimuth_off_center(
125 best_target->rect.centroid.y / (double)::aos::camera::Buffers::kHeight - 0.5)
126 .percent_elevation_off_center(
127 best_target->rect.centroid.x / (double)::aos::camera::Buffers::kWidth - 0.5)
128 .timestamp(timestamp.ToNSec())
129 .Send();
Brian Silverman6ae77dd2013-03-29 22:28:08 -0700130 }
131 notify->Notify();
Austin Schuh86bec782013-04-04 05:50:52 +0000132 //static int counter = 0;
133 //if (++counter > 2) {
134 //break;
135 //}
Brian Silverman6ae77dd2013-03-29 22:28:08 -0700136 }
137 ::aos::Cleanup();
138}
139
140
141int main(int /*argc*/, char** /*argv*/){
142 frc971::vision::PacketNotifier *notify = frc971::vision::PacketNotifier::MMap(
143 ::aos::camera::Buffers::kHeight * ::aos::camera::Buffers::kWidth * 3);
144 pid_t pid = fork();
145 if(pid < 0){
146 fprintf(stderr,"%s:%d: Error in fork()\n",__FILE__,__LINE__);
147 }
148 if(pid == 0){
149 notify->RegisterSender();
150 sender_main(notify);
151 }else{
152 notify->RegisterReciever();
153 reciever_main(notify);
154 }
155}
156