Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
365 kakl 1
/*****************************************************************************/
2
/*
3
 *  vector.cpp - Control program for Vector robot
4
 *
5
 *      Copyright (C) 2007 KAKL
6
 *
7
 *      This program is free software; you can redistribute it and/or modify
8
 *      it under the terms of the GNU General Public License as published by
9
 *      the Free Software Foundation; either version 2 of the License, or
10
 *      (at your option) any later version.
11
 *
12
 *      This program is distributed in the hope that it will be useful,
13
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *      GNU General Public License for more details.
16
 *
17
 */
18
/*****************************************************************************/
19
 
20
#include <iostream>
21
#include <getopt.h>
22
#include <errno.h>
23
#include <string.h>
24
#include <pthread.h>
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <unistd.h>
28
#include "linux/i2c-dev.h"
29
#include "linux/i2c.h"
30
#include <sys/ioctl.h>
31
#include <sys/types.h>
32
#include <sys/stat.h>
33
#include <fcntl.h>
34
#include "geocalc.h"
369 kakl 35
#include "track.h"
365 kakl 36
 
37
using namespace std;
38
 
39
 
40
#define BC_Addr	    0x0B
377 kakl 41
#define US1_Addr	(0xE2>>1)
42
#define US2_Addr	(0xE4>>1)
43
#define US3_Addr	(0xE6>>1)
44
#define CMPS_Addr   (0xC0>>1)
45
#define M1	        (0xA0>>1)
46
#define M2	        (0xA2>>1)
365 kakl 47
 
377 kakl 48
#define SEVER 122
372 kakl 49
 
367 kakl 50
char vystup[50];
51
pthread_t thread_1, thread_2, thread_3;
365 kakl 52
FILE *pRouraO,*pRouraI;
379 kakl 53
unsigned int vzdalenost, lus, rus;
365 kakl 54
char command,ble;
377 kakl 55
int param;
365 kakl 56
int file;
377 kakl 57
double nord, east;
58
int done; // vlajka, ze se neco udelalo
59
int last_cross; // posledni krizovatka
379 kakl 60
int korekce; // Byla korekce podle kompasu nebo zdi
61
int bod;
380 kakl 62
int start;
365 kakl 63
 
367 kakl 64
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
65
 
365 kakl 66
void *print_tele(void *unused);
367 kakl 67
void *gps(void *unused);
366 kakl 68
//void *sensors(void *unused);
365 kakl 69
 
379 kakl 70
void I2C_addr (int Addr)  // vybere adresu cidla se kterym se bude komunikovat
365 kakl 71
{
72
    if (ioctl(file, I2C_SLAVE, Addr) == -1)
73
    {
74
        fprintf(stderr, "Failed to set address to 0x%02x.\n", Addr);
75
        exit(-5);
76
    }
77
}
78
 
379 kakl 79
int i2c_init()   // zinicializuje i2c
80
{
81
	file = open("/dev/i2c-0", O_RDWR);
82
	if (file < 0)
83
	{
84
		cerr << "Could not open /dev/i2c-0." << endl;
85
		return -1;
86
	}
87
	return 0;
88
}
89
 
372 kakl 90
void go (int Addr, int speed) // nastavi rychlost motoru
367 kakl 91
{
92
    char Buf[1];
93
 
94
    I2C_addr (Addr);
95
    Buf[0]=speed;
96
    write(file, Buf, 1);
97
}
98
 
372 kakl 99
unsigned int echo(int Addr)  // precte vzdalenost z US cidla
371 kakl 100
{
101
    char Buf[3];
102
 
103
    I2C_addr(Addr);
104
    Buf[0]=0x0;
105
    Buf[1]=0x51;
106
    write(file, Buf, 2);
107
    usleep(80000);
108
    read(file, Buf, 3);
109
    return (Buf[1]*256+Buf[2]);
110
}
111
 
377 kakl 112
unsigned char read_azimut_mag()  // precte azimut z kompasu
113
{
114
    char Buf[3];      // promena pro manipulaci s i2c
115
 
116
    I2C_addr(CMPS_Addr);
117
    Buf[0]=1;
118
    write(file,Buf,1);
119
    read(file, Buf,1);
120
    return (Buf[0]-SEVER);
121
}
122
 
123
void calib()  // kalibrace kompasu
124
{
125
    char Buf[3];      // promena pro manipulaci s i2c
126
 
127
    I2C_addr(CMPS_Addr);
128
    Buf[0]=15;
129
    Buf[1]=0xFF;
130
    write(file,Buf,2);
131
}
132
 
379 kakl 133
void TL (unsigned char azimut2) // otoci robota na zadany azimut rotaci vlevo
377 kakl 134
{
135
    unsigned char azimut1;
136
 
137
    go(M1, 0);
138
    go(M2, 120);
139
    do
140
    {
141
        azimut1=read_azimut_mag();
142
//printf("az1: %d - az2: %d\n", azimut1, azimut2);
143
        usleep(10000);
379 kakl 144
    } while( (azimut1!=azimut2)&&((azimut1+1)!=azimut2)&&((azimut1+2)!=azimut2)&&((azimut1+3)!=azimut2)&&((azimut1+4)!=azimut2) );
377 kakl 145
    go(M1, 0);
146
    go(M2, 0);
147
}
148
 
379 kakl 149
void TR (unsigned char azimut2) // otoci robota na zadany azimut rotaci v pravo
377 kakl 150
{
151
    unsigned char azimut1;
152
 
153
    go(M1, 120);
154
    go(M2, 0);
155
    do
156
    {
157
        azimut1=read_azimut_mag();
158
        usleep(10000);
379 kakl 159
    } while( (azimut1!=azimut2)&&((azimut1-1)!=azimut2)&&((azimut1-2)!=azimut2)&&((azimut1-3)!=azimut2)&&((azimut1-4)!=azimut2) );
377 kakl 160
    go(M1, 0);
161
    go(M2, 0);
162
}
163
 
379 kakl 164
void SlowLeft()
371 kakl 165
{
379 kakl 166
    go(M1, 40);
167
    go(M2, 60);
168
}
169
 
170
void SlowRight()
171
{
172
    go(M1, 60);
173
    go(M2, 40);
174
}
175
 
176
void FindNearestCrossing(void) // vykonej nejakou akci (zatoceni) pokud se robot nachazi pobliz nejakeho waypointu
177
{
371 kakl 178
    int n;
377 kakl 179
    double dist, pomN, pomE;
379 kakl 180
    unsigned char azimut;
371 kakl 181
 
377 kakl 182
    pthread_mutex_lock(&mutex);         // prepis souradnic do pracovnich promennych
183
    pomN=nord; pomE=east;
184
    pthread_mutex_unlock(&mutex);
380 kakl 185
korekce=0;
379 kakl 186
//    if (last_cross!=-1) if ( GeoCalc::EllipsoidDistance(pomN, pomE, cros[last_cross].n, cros[last_cross].e)>((double)cros[n].dia+5) ) done=0; // znovu naviguj, pokud si dal nez... od krizovatky
371 kakl 187
    n=0;
188
    do
189
    {
190
        if (0==cros[n].id) break;
377 kakl 191
        dist=GeoCalc::EllipsoidDistance(pomN, pomE, cros[n].n, cros[n].e);
192
        if (dist <= (double)cros[n].dia)
371 kakl 193
        {
377 kakl 194
//printf("Point ID: %d - Distance: %f\n",cros[n].id, dist);
380 kakl 195
korekce=1;
379 kakl 196
            if (last_cross!=cros[n].id)
377 kakl 197
            {
379 kakl 198
                bod=cros[n].id;
377 kakl 199
                #include "nav.h"
379 kakl 200
//                done=1;
377 kakl 201
            }
371 kakl 202
            break;
203
        }
204
    } while(++n<POINTS);
205
}
206
 
379 kakl 207
/*
208
void FindWay(void) // koriguj smer podle kompasu
365 kakl 209
{
379 kakl 210
    int n;
211
    double dist, pomN, pomE;
212
 
213
    pthread_mutex_lock(&mutex);         // prepis souradnic do pracovnich promennych
214
    pomN=nord; pomE=east;
215
    pthread_mutex_unlock(&mutex);
216
//    if (last_cross!=-1) if ( GeoCalc::EllipsoidDistance(pomN, pomE, cros[last_cross].n, cros[last_cross].e)>((double)cros[n].dia+5) ) done=0; // znovu naviguj, pokud si dal nez... od krizovatky
217
    n=0;
218
    do
219
    {
220
        if (0==way[n].id) break;
221
        dist=GeoCalc::EllipsoidDistance(pomN, pomE, way[n].n, way[n].e);
222
        if (dist <= (double)way[n].dia)
223
        {
224
            if (last_way!=way[n].id)
225
            {
226
                last_way=way[n].id;
227
                switch (way[n].id)
228
                {
229
                    case 1:
230
                        TL(way[n].azimut);
231
                        break;
232
                    case 2:
233
                        TL(80);
234
                        break;
235
                };
236
 
237
            }
238
            break;
239
        }
240
    } while(++n<POINTS);
372 kakl 241
}
379 kakl 242
*/
365 kakl 243
 
379 kakl 244
void turnL(unsigned char angle, signed char speed)    // otoci robota o zadany uhel (otaceni v levo)
372 kakl 245
{
246
int azimut;
247
 
380 kakl 248
    go(M1, 0);
379 kakl 249
    go(M2, speed);
250
    azimut=read_azimut_mag();
380 kakl 251
//    if((azimut-angle)>192) {azimut+=64; angle+=64};
379 kakl 252
    while(read_azimut_mag() >= (azimut - angle)) usleep(10000);
253
    go(M1, 0);
254
    go(M2, 0);
255
}
256
 
257
void turnR(unsigned char angle, signed char speed)    // otoci robota o zadany uhel (otaceni v pravo)
258
{
259
int azimut;
260
 
372 kakl 261
    go(M1, speed);
262
    go(M2, -speed);
263
    azimut=read_azimut_mag();
264
    while(read_azimut_mag() >= (azimut + angle)) usleep(10000);
265
    go(M1, 0);
266
    go(M2, 0);
267
}
268
 
269
int main(int argc, char *argv[], char *envp[])
270
{
271
    int filtr;
272
    signed char test;
273
 
274
	fprintf(stdout, "\n **** Starting Vector Control Programm **** \n \r");
275
 
276
    i2c_init();
277
 
379 kakl 278
    last_cross=-1;
377 kakl 279
    command=0;
280
    filtr=0;
281
    done=0;
379 kakl 282
    korekce=0;
377 kakl 283
 
365 kakl 284
    pthread_create(&thread_1, NULL, print_tele, NULL);
369 kakl 285
    pthread_create(&thread_3, NULL, gps, NULL);
365 kakl 286
//    pthread_create(&thread_2, NULL, sensors, NULL);
287
 
288
    while(true)
289
    {
367 kakl 290
        switch (command)
366 kakl 291
        {
380 kakl 292
            case 'o':   // forward
293
                start=1;
294
                command=0;
295
                break;
296
 
367 kakl 297
            case 'f':   // forward
377 kakl 298
                go(M1, param);
299
                go(M2, param);
300
                sleep(1);
367 kakl 301
                command=0;
302
                break;
377 kakl 303
 
367 kakl 304
            case 'b':   // backward
377 kakl 305
                go(M1, -param);
306
                go(M2, -param);
307
                sleep(1);
367 kakl 308
                command=0;
309
                break;
377 kakl 310
 
372 kakl 311
            case 'v':   // volnobeh
312
                go(M1, -128);
313
                go(M2, -128);
314
                command=0;
315
                break;
377 kakl 316
 
372 kakl 317
            case 's':   // stop
367 kakl 318
                go(M1, 0);
319
                go(M2, 0);
320
                command=0;
321
                break;
377 kakl 322
 
323
            case 'l':   // left
380 kakl 324
    turnL(20, 120);    // otoci robota o zadany uhel (otaceni v levo)
325
//                TL(param);
369 kakl 326
                command=0;
327
                break;
372 kakl 328
 
377 kakl 329
            case 'r':   // right
330
                TR(param);
331
                command=0;
332
                break;
333
 
334
            case 'c':   // kalibrace kompasu
335
                calib();
336
                command=0;
337
                break;
338
 
372 kakl 339
            case 't':   // test
340
                for(test=0;test<127;test++)
341
                {
342
                    go(M1, test);
343
                    go(M2, test);
344
                    usleep(10000);
345
                };
346
                go(M1, 127);
347
                go(M2, 127);
348
                for(test=127;test>-128;test--)
349
                {
350
                    go(M1, test);
351
                    go(M2, test);
352
                    usleep(10000);
353
                };
354
                go(M1, -128);
355
                go(M2, -128);
356
                command=0;
357
                break;
358
 
367 kakl 359
            case 'g':
372 kakl 360
    usleep(180000);  // simulace ostatnich  cidel (zdrzeni)
380 kakl 361
if(start==1)
362
{
363
    go(M1, 127);
364
    go(M2, 127);
365
    sleep(10);
366
    turnL(5, 120);    // otoci robota o zadany uhel (otaceni v levo)
367
    go(M1, 127);
368
    go(M2, 127);
369
    sleep(10);
370
    turnL(5, 120);    // otoci robota o zadany uhel (otaceni v levo)
371
    go(M1, 127);
372
    go(M2, 127);
373
    sleep(5);
374
//    turnL(5, 120);    // otoci robota o zadany uhel (otaceni v levo)
375
    go(M1, 127);
376
    go(M2, 127);
377
    sleep(10);
378
   start=0;
379
};
380
//                FindNearestCrossing();
379 kakl 381
//!!!                FindWay();
372 kakl 382
 
371 kakl 383
                vzdalenost=echo(US3_Addr);
379 kakl 384
                usleep(30000);
385
                lus=echo(US1_Addr);
386
                usleep(30000);
387
                rus=echo(US2_Addr);
388
                usleep(30000);
389
 
380 kakl 390
if ((vzdalenost<30)||(vzdalenost>150))
391
{
392
    go(M1, 0);  // zastav, neni videt doprovod
393
    go(M2, 0);
394
    break;
395
};
396
 
397
                if ((vzdalenost>60)&&(vzdalenost<100))
367 kakl 398
                {
379 kakl 399
 
400
//FindNearestCrossing();
380 kakl 401
//if(korekce==0)
379 kakl 402
                    {
380 kakl 403
                        go(M1, 40);
404
                        go(M2, 60);
405
                        break;
379 kakl 406
                    };
380 kakl 407
//                   filtr=0;
367 kakl 408
                };
380 kakl 409
                if ((vzdalenost>=100))
367 kakl 410
                {
371 kakl 411
                    filtr=0;
380 kakl 412
                    go(M1, 60);
413
                    go(M2, 40);
414
                    break;
367 kakl 415
                }
416
                break;
366 kakl 417
        }
365 kakl 418
    };
366 kakl 419
 
365 kakl 420
	close(file);
421
    pthread_join(thread_1, NULL);
422
    pthread_join(thread_2, NULL);
369 kakl 423
    pthread_join(thread_3, NULL);
365 kakl 424
 
425
	return 0;
426
}
427
 
366 kakl 428
 
365 kakl 429
void *print_tele(void *unused)
430
{
377 kakl 431
    char pom;
366 kakl 432
 
365 kakl 433
    while(true)
434
    {
435
        pRouraI = fopen("/home/ble/pipe","r");
377 kakl 436
        fscanf(pRouraI,"%1s%d", &pom, &param);
365 kakl 437
        fclose(pRouraI);
377 kakl 438
        if (pom!='i') command=pom;
439
 
365 kakl 440
        pRouraO = fopen("/home/ble/pipe","w");
379 kakl 441
        fprintf(pRouraO,"US3: %u cm - ",vzdalenost);
367 kakl 442
 
377 kakl 443
        pthread_mutex_lock(&mutex);
444
        fprintf(pRouraO,"%fN %fE - ", nord, east);
379 kakl 445
        fprintf(pRouraO,"Bod:%d - ", bod);
377 kakl 446
        fprintf(pRouraO,"Len:%.1f m /", GeoCalc::EllipsoidDistance(nord, east, cros[last_cross].n, cros[last_cross].e));
447
        fprintf(pRouraO,"Az:%.2f Deg - ", GeoCalc::GCAzimuth(nord, east, cros[last_cross].n, cros[last_cross].e));
448
        fprintf(pRouraO,"AzMag: %d (0-255)\n", read_azimut_mag());
379 kakl 449
        fprintf(pRouraO,"US1: %u cm - US2 %u cm\n",lus,rus);
450
 
377 kakl 451
        pthread_mutex_unlock(&mutex);
367 kakl 452
 
365 kakl 453
        fclose(pRouraO);
454
    }
455
}
456
 
367 kakl 457
void *gps(void *unused)
458
{
459
    FILE *pRS232;
369 kakl 460
    double N, E, pomN, pomE, nn, ee;
367 kakl 461
 
462
    while(true)
463
    {
371 kakl 464
        pRS232 = fopen("/dev/ttyS1","r");
369 kakl 465
        fscanf(pRS232,"$GPGGA,%*f,%lf,N,%lf,E,*", &N, &E); // parser NMEA
371 kakl 466
        fclose(pRS232);
369 kakl 467
        nn=ldiv((long)N,100).quot;   // prepocet DDMM.MM na DD.DD
468
        pomN=(N-nn*100)/60+nn;
469
        ee=ldiv((long)E,100).quot;
470
        pomE=(E-ee*100)/60+ee;
471
        pthread_mutex_lock(&mutex);         // prepis souradnic do sdilenych promennych
377 kakl 472
        nord=pomN; east=pomE;
367 kakl 473
        pthread_mutex_unlock(&mutex);
371 kakl 474
        usleep(800000);                     // NMEA nechodi castejc nez 1x za 1s
367 kakl 475
    }
476
}
477
 
379 kakl 478
 
366 kakl 479
/*
365 kakl 480
void *sensors(void *unused)
481
{
482
	char Buf[64];
483
 
484
    while(true)
485
    {
379 kakl 486
        vzdalenost=echo(US3_Addr);
487
        usleep(20000);
488
        left=echo(US1_Addr);
489
        usleep(20000);
490
        right=echo(US1_Addr);
491
        usleep(20000);
365 kakl 492
    }
493
}
366 kakl 494
*/