QuakeGod
2024-07-27 842bb64195f958b050867c50db66fc0aa413dafb
提交 | 用户 | age
8b51c7 1 #include "YDLidar.h"
Q 2
3 int nPosX;
4 int nPosY;
5 int nPosZ;
6
7 int nPosZ1,nPosZ2;
8
9 int pCount1=0;
10 int pCount2=0;
11
12 int dCount1=0;
13 int dCount2=0;
14
15 int vCount1=0;
16 int vCount2=0;
17
18
19 void Uart3SendPacket(char * str, int len);
20 void Uart5SendPacket(char * str, int len);
21
22 //正弦表,0 - 360 代表 0 - 2PI,结果0 - 1000 表示0 - 1,表中只有0 - PI/2即1/4周期的数据,其他的数据用对称和镜像得到。
5dd1b7 23 const int SinTable[] =  
8b51c7 24 {
Q 25 0,17,35, 52, 70, 87, 105, 122, 139, 156, 174, 191, 208, 225, 242, 259, 276, 292,
26 309, 326, 342, 358, 375, 391, 407, 423, 438, 454, 469, 485, 500, 515, 530, 545,
27 559, 574, 588, 602, 616, 629, 643, 656, 669, 682, 695, 707, 719, 731, 743, 755,
28 766, 777, 788, 799, 809, 819, 829, 839, 848, 857, 866, 875, 883, 891, 899, 906,
29 914, 921, 927, 934, 940, 946, 951, 956, 961, 966, 970, 974, 978, 982, 985, 988,
30 990, 993, 995, 996, 998, 999, 999, 1000, 1000,
31 1000, 999, 999, 998, 996, 995,
32 993, 990, 988, 985, 982, 978, 974, 970, 966, 961, 956, 951, 946, 940, 934, 927,
33 921, 914, 906, 899, 891, 883, 875, 866, 857, 848, 839, 829, 819, 809, 799, 788,
34 777, 766, 755, 743, 731, 719, 707, 695, 682, 669, 656, 643, 629, 616, 602, 588,
35 574, 559, 545, 530, 515, 500, 485, 469, 454, 438, 423, 407, 391, 375, 358, 342,
36 326, 309, 292, 276, 259, 242, 225, 208, 191, 174, 156, 139, 122, 105, 87, 70,
37 52, 35, 17, 0, -17, -35, -52, -70, -87, -105, -122, -139, -156, -174, -191,
38 -208, -225, -242, -259, -276, -292, -309, -326, -342, -358, -375, -391, -407,
39 -423, -438, -454, -469, -485, -500, -515, -530, -545, -559, -574, -588, -602,
40 -616, -629, -643, -656, -669, -682, -695, -707, -719, -731, -743, -755, -766,
41 -777, -788, -799, -809, -819, -829, -839, -848, -857, -866, -875, -883, -891,
42 -899, -906, -914, -921, -927, -934, -940, -946, -951, -956, -961, -966, -970,
43 -974, -978, -982, -985, -988, -990, -993, -995, -996, -998, -999, -999, -1000,
44 -1000, -1000, -999, -999, -998, -996, -995, -993, -990, -988, -985, -982, -978,
45 -974, -970, -966, -961, -956, -951, -946, -940, -934, -927, -921, -914, -906,
46 -899, -891, -883, -875, -866, -857, -848, -839, -829, -819, -809, -799, -788,
47 -777, -766, -755, -743, -731, -719, -707, -695, -682, -669, -656, -643, -629,
48 -616, -602, -588, -574, -559, -545, -530, -515, -500, -485, -469, -454, -438,
49 -423, -407, -391, -375, -358, -342, -326, -309, -292, -276, -259, -242, -225,
50 -208, -191, -174, -156, -139, -122, -105, -87, -70, -52, -35, -17
51 };
5dd1b7 52 const int CosTable[] =
8b51c7 53 {
Q 54     1000 ,999 ,999 ,998 ,996 ,995 ,993 ,990 ,988 ,985 ,982 ,978 ,974 ,970 ,966 ,961
55 ,956 ,951 ,946 ,940 ,934 ,927 ,921 ,914 ,906 ,899 ,891 ,883 ,875 ,866 ,857 ,848
56 ,839 ,829 ,819 ,809 ,799 ,788 ,777 ,766 ,755 ,743 ,731 ,719 ,707 ,695 ,682 ,669
57 ,656 ,643 ,629 ,616 ,602 ,588 ,574 ,559 ,545 ,530 ,515 ,500 ,485 ,469 ,454 ,438
58 ,423 ,407 ,391 ,375 ,358 ,342 ,326 ,309 ,292 ,276 ,259 ,242 ,225 ,208 ,191 ,174
59 ,156 ,139 ,122 ,105 ,87 ,70 ,52 ,35 ,17 ,0 ,-17 ,-35 ,-52 ,-70 ,-87 ,-105 ,-122
60 ,-139 ,-156 ,-174 ,-191 ,-208 ,-225 ,-242 ,-259 ,-276 ,-292 ,-309 ,-326 ,-342
61 ,-358 ,-375 ,-391 ,-407 ,-423 ,-438 ,-454 ,-469 ,-485 ,-500 ,-515 ,-530 ,-545
62 ,-559 ,-574 ,-588 ,-602 ,-616 ,-629 ,-643 ,-656 ,-669 ,-682 ,-695 ,-707 ,-719
63 ,-731 ,-743 ,-755 ,-766 ,-777 ,-788 ,-799 ,-809 ,-819 ,-829 ,-839 ,-848 ,-857
64 ,-866 ,-875 ,-883 ,-891 ,-899 ,-906 ,-914 ,-921 ,-927 ,-934 ,-940 ,-946 ,-951
65 ,-956 ,-961 ,-966 ,-970 ,-974 ,-978 ,-982 ,-985 ,-988 ,-990 ,-993 ,-995 ,-996
66 ,-998 ,-999 ,-999 ,-1000 ,-1000 ,-1000 ,-999 ,-999 ,-998 ,-996 ,-995 ,-993 ,-990
67 ,-988 ,-985 ,-982 ,-978 ,-974 ,-970 ,-966 ,-961 ,-956 ,-951 ,-946 ,-940 ,-934
68 ,-927 ,-921 ,-914 ,-906 ,-899 ,-891 ,-883 ,-875 ,-866 ,-857 ,-848 ,-839 ,-829
69 ,-819 ,-809 ,-799 ,-788 ,-777 ,-766 ,-755 ,-743 ,-731 ,-719 ,-707 ,-695 ,-682
70 ,-669 ,-656 ,-643 ,-629 ,-616 ,-602 ,-588 ,-574 ,-559 ,-545 ,-530 ,-515 ,-500
71 ,-485 ,-469 ,-454 ,-438 ,-423 ,-407 ,-391 ,-375 ,-358 ,-342 ,-326 ,-309 ,-292
72 ,-276 ,-259 ,-242 ,-225 ,-208 ,-191 ,-174 ,-156 ,-139 ,-122 ,-105 ,-87 ,-70 ,-52
73 ,-35 ,-17 ,0 ,17 ,35 ,52 ,70 ,87 ,105 ,122 ,139 ,156 ,174 ,191 ,208 ,225 ,242
74 ,259 ,276 ,292 ,309 ,326 ,342 ,358 ,375 ,391 ,407 ,423 ,438 ,454 ,469 ,485 ,500
75 ,515 ,530 ,545 ,559 ,574 ,588 ,602 ,616 ,629 ,643 ,656 ,669 ,682 ,695 ,707 ,719
76 ,731 ,743 ,755 ,766 ,777 ,788 ,799 ,809 ,819 ,829 ,839 ,848 ,857 ,866 ,875 ,883
77 ,891 ,899 ,906 ,914 ,921 ,927 ,934 ,940 ,946 ,951 ,956 ,961 ,966 ,970 ,974 ,978
78 ,982 ,985 ,988 ,990 ,993 ,995 ,996 ,998 ,999 ,999 ,1000 ,1000
79 };
80
81
5dd1b7 82 const unsigned char sintab[256]={    //正弦表,0 - 1024代表 0 - 2PI,结果0 - 255表示0 - 1,表中只有0 - PI/2即1/4周期的数据,其他的数据用对称和镜像得到。
8b51c7 83  0, 1, 3, 4, 6, 7, 9, 10, 12, 14, 15, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 32, 34, 36, 37, 39, 40, 42, 43, 45, 46,
Q 84  48, 49, 51, 53, 54, 56, 57, 59, 60, 62, 63, 65, 66, 68, 69, 71, 72, 74, 75, 77, 78, 80, 81, 83, 84, 86, 87, 89, 90,
85  92, 93, 95, 96, 97, 99, 100, 102, 103, 105, 106, 108, 109, 110, 112, 113, 115, 116, 117, 119, 120, 122, 123, 124,
86  126, 127, 128, 130, 131, 132, 134, 135, 136, 138, 139, 140, 142, 143, 144, 146, 147, 148, 149, 151, 152, 153, 155,
87  156, 157, 158, 159, 161, 162, 163, 164, 166, 167, 168, 169, 170, 171, 173, 174, 175, 176, 177, 178, 179, 181, 182,
88  183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
89  205, 206, 207, 208, 209, 210, 211, 211, 212, 213, 214, 215, 216, 217, 217, 218, 219, 220, 221, 221, 222, 223,
90  224, 225, 225, 226, 227, 227, 228, 229, 230, 230, 231, 232, 232, 233, 234, 234, 235, 235, 236, 237, 237, 238,
91  238, 239, 239, 240, 241, 241, 242, 242, 243, 243, 244, 244, 244, 245, 245, 246, 246, 247, 247, 247, 248, 248, 
92  249, 249, 249, 250, 250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 
93  254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,// 255 
94 };
95
96     
97
98
99 char StartCMD[2] = { 0xA5,0x60 };
100 char StopCMD[2] = { 0xA5,0x65 };
101
102
103 int StartAngle;
104 int EndAngle;
105
106 int YdLidarStart(int nIdx)
107 {
108     if (nIdx == 0 || nIdx == -1 ) {
109         Uart3SendPacket(StartCMD,sizeof(StartCMD));
110     }
111     if (nIdx == 1 || nIdx == -1) {
112         Uart5SendPacket(StartCMD,sizeof(StartCMD));
113     }
114         return 0;
115 };
116
117
118 int YdLidarStop(int nIdx){
119     if (nIdx == 0 || nIdx == -1 ) {
120         Uart3SendPacket(StopCMD,sizeof(StopCMD));
121     }
122     if (nIdx == 1 || nIdx == -1) {
123         Uart5SendPacket(StopCMD,sizeof(StopCMD));
124     }
125     return 0;
126 };
127
128 char startFlag0 = 0;
129 char startFlag1 = 0;
130
131 #define VALID_DATA_MAX 200
132 stLidarDot validData0[200];
133 stLidarDot validData1[200];
134
135 int nValidCount0 = 0;
136 int nValidCount1 = 0;
137
138 #define SUB_DEGREE 64
139
140 #define START_DEGREE 135
141 #define END_DEGREE 225
142
143 #define MAX_DISTANCE 500                //mm
144
145 //整数求SIN值,带线性插值功能, 输入0 - 360*64 为 0 - 2PI,一个周期;输出-1000 至 +1000,代表-1到+1;
146 int sini(int a)
147 {
148     
149     a = a % (360 * SUB_DEGREE);
150     int b;
151     b=a / SUB_DEGREE;
152     int xx = a % SUB_DEGREE;
153     if (b< 90 )
154     {
155         int d1= SinTable[b ];
156         int d2 =SinTable[b+1 ];
157         int d;
158         d = ((SUB_DEGREE-xx) * d1 + xx * d2 ) / SUB_DEGREE;
159         
160         return (d);
161     }
162     else if (b<180 )
163     {    
164         int c;
165         c=180-b;
166         
167         int d1= SinTable[c ];
168         int d2 =SinTable[c-1 ];
169         int d;
170         d = ((SUB_DEGREE-xx) * d1 + xx * d2 ) / SUB_DEGREE;
171         
172         return (d);
173     }
174     
175     else if (b<270)
176     {
177         int c;
178         c=b-180;
179         int d1= SinTable[c ];
180         int d2 =SinTable[c+1 ];
181         int d;
182         d = ((SUB_DEGREE-xx) * d1 + xx * d2 ) / SUB_DEGREE;
183         
184         return (-d);
185     }
186     else 
187     {
188         int c;
189         c=360 -b;
190         int d1= SinTable[c ];
191         int d2 =SinTable[c-1 ];
192         int d;
193         d = ((SUB_DEGREE-xx) * d1 + xx * d2 ) / SUB_DEGREE;
194         
195         return (-d);
196     }
197     
5dd1b7 198 //    return a;
8b51c7 199 }
Q 200
201 int cosi(int a)
202 {
203     return sini(a+90*SUB_DEGREE);
204 }
205
206 int YdLidarParsePkt(int nLidarIdx, stLidarDotsPkt * pLindarPkt, int len1)
207 {
208     int iRet = 0;
209     if (pLindarPkt->StSign != 0x55AA) return 0;        // check for start sign
210     if ((pLindarPkt->CT & 0x01) != 0x00) return 0;        // check for CT bit0. 
211     if (pLindarPkt->LSN<2) return 0;
212     
213     int startAngle = (pLindarPkt->FSA >> 1);    // degree * 64;
214     int endAngle = (pLindarPkt->LSA >> 1);         // degree * 64;
215     if (startAngle >= endAngle)return 0;
216     int nCount = pLindarPkt->LSN;    
217     int diffAngle = (endAngle - startAngle);
218     int eachAngle = diffAngle / (nCount - 1);    
219     
220     if (nLidarIdx == 0) 
221     {
222         pCount1++;
223         for (int i = 0;i < nCount && i < 40 ;i++)
224         {
225             float intensity = pLindarPkt->LidarDotDatas[i].intensity;
226             int angle = eachAngle * i + startAngle;    // degree * 64
227             dCount1++;
228             
229             if (angle < START_DEGREE * SUB_DEGREE )    startFlag0 = 1;
230             if (angle > START_DEGREE * SUB_DEGREE && angle < END_DEGREE * SUB_DEGREE) // &&x>100000&&x<250000)
231             {
232                 int value = (pLindarPkt->LidarDotDatas[i].s2 << 6) + (pLindarPkt->LidarDotDatas[i].s1 >> 2); // distance
233                 
234                 int x = value * sini(angle - 90 * SUB_DEGREE );            //     uM
235                 int y = value * cosi(angle - 90 * SUB_DEGREE );            //  uM
236                 
237                 //vectorX.push_back(x);
238                 //vectorY.push_back(y);
239                 validData0[nValidCount0].distance = value;
240                 validData0[nValidCount0].x = x;
241                 validData0[nValidCount0].y = y;
242                 if (nValidCount0 < 200 - 1 ) nValidCount0 ++;
243                 vCount1++;
244             }
245
246             if (angle > END_DEGREE * SUB_DEGREE)
247             {
248                 if (startFlag0 == 1 && nValidCount0 > 0)
249                 {
250
251                         int min = 1000000, max = -1000000;
252                         int minX = 1000000;
253                         for (int i = 0;i < nValidCount0;i++)
254                         {
255                             if (validData0[i].distance < 5000) continue;
256                             
257                             if (validData0[i].y > 0)
258                             {
259                                 if (validData0[i].y < min)
260                                     min = validData0[i].y;
261                             }
262                             if (validData0[i].y < 0)
263                             {
264                                 if (validData0[i].y > max)
265                                     max = validData0[i].y;
266                             }
267                         }
268                         float avg=0;
269                         for (int i = 0;i < nValidCount0;i++)
270                         {
271                             if (validData0[i].x < minX) 
272                             {
273                                 minX = validData0[i].x;
274                             }
275                         }
276                         if (min != 0 && max != 0)
277                         {
278                             avg = (min + max) / 2000;
279                         }
280                         
281                         nPosX = avg;
282                         nPosZ1 = minX/1000;
283                 }
284                 startFlag0 = 0;
285                 nValidCount0 = 0;
286             }
287         }
288     }
289
290     if (nLidarIdx == 1) 
291     {
292         pCount2++;
293         for (int i = 0;i < nCount && i < 40 ;i++)
294         {
295             float intensity = pLindarPkt->LidarDotDatas[i].intensity;
296             int angle = eachAngle * i + startAngle;
297
298             dCount2++;
299             
300             if (angle < START_DEGREE * SUB_DEGREE)    startFlag1 = 1;
301             if (angle > START_DEGREE * SUB_DEGREE && angle < END_DEGREE * SUB_DEGREE ) // &&x>100000&&x<250000)
302             {
303                 int value = (pLindarPkt->LidarDotDatas[i].s2 << 6) + (pLindarPkt->LidarDotDatas[i].s1 >> 2);
304
305                 int x = value * sini(angle - 90 * SUB_DEGREE );            //    uM
306                 int y = value * cosi(angle - 90 * SUB_DEGREE );            //    uM //vectorX.push_back(x);
307                 //vectorY.push_back(y);
308                 validData1[nValidCount1].distance = value; 
309                 validData1[nValidCount1].x = x;
310                 validData1[nValidCount1].y = y;
311                 nValidCount1 ++;
312                 vCount2 ++;
313             }
314
315             if (angle > END_DEGREE * SUB_DEGREE)
316             {
317                 if (startFlag1 == 1 && nValidCount1 > 0 )
318                 {
319                         int minDisIndex = 0;
320                         int minDistance = 99999999;
321                         
322                         int min = 1000000, max = -1000000;
323                         int minX = 1000000;
324                         for (int i = 0;i < nValidCount1;i++)
325                         {
326                             if (validData1[i].distance < 30) continue;        // skip too small points;
327                             
328                             if (validData1[i].distance < minDistance) {
329                                 minDisIndex = i;
330                                 minDistance = validData1[i].distance;
331                             }
332
333                             if (validData1[i].x < minX) 
334                             {
335                                 minX = validData1[i].x;
336                             }
337                             
338                             if (validData1[i].y > 0)
339                             {
340                                 if (validData1[i].y < min)
341                                     min = validData1[i].y;
342                             }
343                             if (validData1[i].y < 0)
344                             {
345                                 if (validData1[i].y > max)
346                                     max = validData1[i].y;
347                             }
348                             
349                         }
350                         int avg=0;
351                         int leftcount = 0;
352                         int midcount = 0;
353                         int rightcount =0;
354                         for (int i = 0;i < nValidCount1;i++)
355                         {
356                             if (validData1[i].distance < 30) continue;        // skip too small points;
357                             // 找中间空洞;
358                             if (validData1[i].x > minX + 50000) {
359                                             // points, 50mm higher that minX;
360                                 if (leftcount>5 && rightcount <5) midcount++;
361                                 
362                                 continue;        //skip 
363                             }else {
364                                     if (midcount ==0) {leftcount++;}
365                                     else {rightcount++;}
366                             }
367                         }
368                         if (min != 0 && max != 0)
369                         {
370                             avg = (min + max) / 2000;
371                         }
372                         
373                         nPosY = avg;
374                         nPosZ1 = minX/1000;
375                         nPosY = validData1[minDisIndex].y /1000;
376 //                        nPosZ2 = validData1[minDisIndex].x /1000;
377                         nPosZ2 = midcount;
378                 }
379                 startFlag1 = 0;
380                 nValidCount1 = 0;
381             }
382         }
383     }    
384     nPosZ = (nPosZ1 + nPosZ2) /2;
385     
386     return iRet;
387 }
388
389