11 #define LINE_MIN_POINTS 7
12 #define LINE_ERROR_THRESHOLD 25
16 typedef struct {float x,y;} Point;
21 int perpendicular_regression(float &r, int &max_diff_idx, const int begin, const int end)
23 int number_points = abs(end-begin) + 1;
25 if (number_points <= 0) return 1;
30 for (int i = begin; i <= end; i++) {
31 sum_x = sum_x + cartes[i].x;
32 sum_y = sum_y + cartes[i].y;
35 float med_x = sum_x / number_points;
36 float med_y = sum_y / number_points;
38 vector<Point> point_average;
42 for (int i = begin; i <= end; i++) {
43 tmp.x = cartes[i].x - med_x;
44 tmp.y = cartes[i].y - med_y;
45 point_average.push_back(tmp);
51 for (int i = 0; i < number_points; i++) {
52 A = A + (point_average[i].x*point_average[i].x - point_average[i].y*point_average[i].y);
53 sum_xy = sum_xy + point_average[i].x * point_average[i].y;
56 if (sum_xy == 0) sum_xy = 1e-8;
60 // tan(q)^2 + A*tan(q) - 1 = 0 ( tan(q) sign as m ) -> quadratic equation
61 float m1 = (-A + sqrt(A*A + 4)) / 2;
62 float m2 = (-A + sqrt(A*A + 4)) / 2;
64 float b1 = med_y - m1*med_x;
65 float b2 = med_y - m2*med_x;
72 for (int i = begin; i < end; i++) {
73 // distance point from the line (A = m1, B = -1, C = b1)
74 dist = fabs( (cartes[i].x*m1 - cartes[i].y + b1) / sqrt(m1*m1 + 1) );
84 for (int i = begin; i < end; i++) {
85 // distance point from the line (A = m2, B = -1, C = b2)
86 dist = fabs( (cartes[i].x*m2 - cartes[i].y + b2) / sqrt(m2*m2 + 1) );
103 // line recursive fitting
104 void line_fitting(int begin, int end) {
105 int line_break_point;
106 cout << "begin: " << begin << " end: " << end << endl << flush;
108 if ((end - begin) < LINE_MIN_POINTS) return;
111 if (perpendicular_regression(r, line_break_point, begin, end)) return; // r = 0
113 if (r < LINE_ERROR_THRESHOLD) {
114 lines.push_back(cartes[begin]);
115 lines.push_back(cartes[end]);
117 cout << endl << "begin X: " << cartes[begin].x << " Y: " << cartes[begin].y << endl << flush;
118 cout << "end X: " << cartes[end].x << " Y: " << cartes[end].y << endl << endl << flush;
120 if (line_break_point == begin)
122 else if (line_break_point == end)
124 line_fitting(begin, line_break_point);
125 line_fitting(line_break_point, end);
126 } // end if (r <= LINE_ERROR_THRESHOLD)
132 // polar to cartesian coordinates
133 void polar_to_cartes(const vector<int> &input_data) {
140 for (int i = 0; i < (int) input_data.size()-1; i += 2) {
141 r = (input_data[i+1] <= 19) ? 0 : input_data[i+1];
142 //fi = HOKUYO_INDEX_TO_RAD(RESOLUTION * input_data[i] - 45) * PI/180;
144 fi = HOKUYO_INDEX_TO_RAD(input_data[i]);
146 point.x = r * cos(fi);
147 point.y = r * sin(fi);
148 cartes.push_back(point);
153 void shape_detect(const vector<int> &input_data) {
154 // polar coordinates to cartesian coordinates
155 polar_to_cartes(input_data);
156 cout << "Cartes vector size: " << cartes.size() << endl << endl;
161 while (distance(cartes[i-1], cartes[i]) < 50cm &&
166 line_fitting(start, i);
171 struct robottype_orte_data orte;
173 void rcv_hokuyo_scan_cb(const ORTERecvInfo *info, void *vinstance,
174 void *recvCallBackParam)
176 struct hokuyo_scan_type *instance = (struct hokuyo_scan_type *)vinstance;
177 struct hokuyo_scan_type scan;
179 switch (info->status) {
185 system("gnuplot graph.dem"); // nebo pres pipe jako v barcam
189 robot.status[COMPONENT_HOKUYO] = STATUS_FAILED;
190 //system("killall -9 hokuyo");
191 DBG("%s: ORTE deadline occurred\n", __FUNCTION__);
195 int robot_init_orte()
199 robot.orte.strength = 20;
201 rv = robottype_roboorte_init(&orte);
205 robottype_subscriber_hokuyo_scan_create(&orte, rcv_hokuyo_scan_cb, &orte);
212 int main(int argc, char** argv) {
215 cout << "Error: Invalid number of input parameters." << endl;
219 vector<int> input_data;
221 ifstream infile (argv[1], ios_base::in);
223 string line; // line input file
224 int number; // number from input file
226 while (getline(infile, line, ',')) {
228 stringstream strStream(line);
230 input_data.push_back(number);
235 shape_detect(input_data);
238 FILE *file = fopen("output_data","w");
240 for (int i = 0; i < (int) lines.size(); i++)
241 fprintf(file, "%f, %f\n", lines[i].x, lines[i].y);
245 file = fopen("cartes_data","w");
247 for (int i = 0; i < (int) cartes.size(); i++)
248 fprintf(file, "%f, %f\n", cartes[i].x, cartes[i].y);