Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / mapping / matlab / receive.c @ 953

History | View | Annotate | Download (5.51 KB)

1
#include <stdio.h>
2
#include <stdlib.h>
3
//#include <mex.h>
4
#include <pthread.h>
5
#include <unistd.h>
6
#include "../../libwireless/lib/wireless.h"
7
#include "../../libwireless/lib/wl_token_ring.h"
8

    
9
#define WL_COM_PORT "/dev/ttyUSB1" 
10
#define WL_CHANNEL 0xE
11

    
12
#define MAP_RECEIVE_GROUP 1
13
#define MAP_REQUEST_GROUP 2
14

    
15
#define POINT_RAW 1 // packet type for map data points w/ raw encoder data
16
#define POINT_ODO 2 // packet type for map data points w/ odometry data
17

    
18
#define BUFFER_SIZE 1000
19
#define BUFFER_EMPTY -1
20

    
21
pthread_rwlock_t buffer_lock;
22
pthread_t receive_thread;
23

    
24
int packets_received; //Used to block overlapping packet requests.
25

    
26
void packet_receive(char type, int source, unsigned char* packet, int length);
27

    
28
PacketGroupHandler receiveHandler = {MAP_REQUEST_GROUP, NULL, NULL, &packet_receive, NULL};
29
PacketGroupHandler requestHandler = {MAP_RECEIVE_GROUP, NULL, NULL, NULL, NULL};
30

    
31
//Buffers
32
short robot_buffer[BUFFER_SIZE];                        //by #
33
short range_buffer[BUFFER_SIZE][5];                 //IR1, IR2 ... 
34
short coordinate_buffer[BUFFER_SIZE][2];        //X Y
35
float orientation_buffer[BUFFER_SIZE];
36

    
37
int tail_index; //Points to the newest data in the buffers.
38
int head_index; //Points to the oldest data in the buffers.
39

    
40
int receive_initialized = 0;
41

    
42
void* buffer_data(void* arg);
43

    
44
//void mexFunction(int nlhs, mxArray* ret[], int nrhs, const mxArray* args[]){
45
int main(){        
46
        if(!receive_initialized){        
47
                
48
                //Initialization
49
                head_index = BUFFER_EMPTY;
50
                tail_index = BUFFER_EMPTY;        
51
                 
52
                pthread_rwlock_init(&buffer_lock, NULL);
53

    
54
                pthread_create(&receive_thread, NULL, buffer_data, NULL);
55
                receive_initialized = 1;
56
        }
57
        
58
        while(1){}
59
        
60
        /*Return stuff to matlab
61
        //deliberately ignore nrhs.        
62
        if(nlhs != 4){
63
                mexErrMsgTxt("Error: Expect output arguments [P IR T R]\n 
64
                                          where P = [X Y], IR = [IR1, IR2 ...],\n
65
                                          T = angle, and R = Robot number."); 
66
        }
67
        
68
        double* point, ranges, theta;
69
        int index,i,j;
70
        
71
        pthread_rwlock_rdlock(&buffer_lock);
72
        {
73

74
                if(tail_index == BUFFER_EMPTY || head_index == BUFFER_EMPTY){
75
                        //Appropriately return with nothing.
76
                }
77
                else{
78
                        //TODO Check for the 'already empty' case.
79

80
                        int num_buffer_elements = tail_index - head_index;
81
                        if(num_buffer_elements < 0) num_buffer_elements += BUFFER_SIZE;        
82

83
                        ret[0] = mxCreateDoubleMatrix(num_buffer_elements, 2, mxREAL);
84
                        ret[1] = mxCreateDoubleMatrix(num_buffer_elements, 5, mxREAL);
85
                        ret[2] = mxCreateDoubleMatrix(num_buffer_elements, 1, mxREAL);
86
                        ret[3] = mxCreateDoubleMatrix(num_buffer_elements, 1, mxREAL);
87
                
88
                        point  = mxGetPr(ret[0]);
89
                        ranges = mxGetPr(ret[1]);
90
                        theta = mxGetPr(ret[2]);
91
                        robot = mxGetPr(ret[3]);
92
                        
93
                        for(index = head_index; index <= tail_index; index = (index + 1)%1024){
94
                                point[i][0] = (double)coordinate_buffer[index][0];        
95
                                point[i][1] = (double)coordinate_buffer[index][1];        
96
                                
97
                                for(j=0;j<5;j++)
98
                                        ranges[i][j] = (double)range_buffer[index][j];
99

100
                                theta[i] = (double)(orientation_buffer[index]);        
101
                                robot[i] = (double)(robot_buffer[index]);
102
                        }
103
                        head_index = BUFFER_EMPTY;
104
                        tail_index = BUFFER_EMPTY;
105
        }        
106
        pthread_rwlock_unlock(&buffer_lock);
107
        */
108
        return -1;
109
}
110

    
111
/*
112
 * buffer_data continuously runs through the robots and
113
 * waits for them to respond.
114
 */
115
void* buffer_data(void* arg){
116
        int robot_num, num_robots;        
117

    
118
        pthread_detach(pthread_self());
119
        
120
        //General communication initialization.        
121
        wl_set_com_port(WL_COM_PORT);        
122
        wl_init();
123
        wl_set_channel(WL_CHANNEL);
124
        wl_register_packet_group(&receiveHandler);
125

    
126
        //Token ring / sensor network initialization.
127
        wl_token_ring_register();        
128
        
129
        //Continuously iterate over all the robots - buffering data.
130
        while(1){
131
                
132
                wl_token_iterator_begin();
133
                
134
                num_robots = wl_token_get_num_robots();
135
                
136
                //Initialize the 'packets received' number. 
137
                packets_received = 0;
138
        
139
                //Send a data request to all robots.
140
                while(wl_token_iterator_has_next()){
141
                        robot_num = wl_token_iterator_next();
142
                    
143
                        wl_send_robot_to_robot_global_packet(MAP_REQUEST_GROUP, 
144
                                POINT_ODO, NULL, 0, robot_num, 0);
145
                    
146

    
147
                }
148
                
149
                //Wait for all packets to be received before sending more requests.
150
                while(packets_received < num_robots 
151
                   && packets_received < wl_token_get_num_robots()){
152
                        
153
                        usleep(10000); //10ms
154
                }
155
                
156
                usleep(10000); 
157
        }
158
}
159

    
160
void packet_receive (char type, int source, unsigned char* packet, int length) {
161
        printf("A packet came in!\n");        
162
        if(type==POINT_ODO){        
163

    
164
                if(length!=18) printf("Packet came without the standard length!\n");
165

    
166
                // expected input: x y theta(double) IR1 IR2 IR3 IR4 IR5
167
                // Pull in data:
168
                
169
                short x,y,i;
170
                short ranges[5];        
171
                
172
                x = ((short)packet[1] << 8)  | (short)packet[0];
173
                y = ((short)packet[3] << 8)  | (short)packet[2];
174

    
175
                for(i=0; i<5; i++){
176
                        ranges[i] 
177
                           = ((short)packet[8+2*i+1] << 8) | (short)packet[8 + 2*i];
178
                }
179

    
180
                float theta = *((float*)(packet + 4));
181
        
182
                //Write new data to buffers. (Lock down!)
183
                pthread_rwlock_wrlock(&buffer_lock);
184
                {        
185
                        //Note that you write no matter what.        
186
                        tail_index = (tail_index + 1) % BUFFER_SIZE; 
187
                        
188
                        //Write the robots number.
189
                        robot_buffer[tail_index] = source;
190
                        
191
                        //Write in range data.
192
                        for(i=0; i<5; i++) range_buffer[tail_index][i] = ranges[i];
193
                        
194
                        coordinate_buffer[tail_index][0] = x;
195
                        coordinate_buffer[tail_index][1] = y;
196
                        
197
                        orientation_buffer[tail_index] = theta;
198
                        
199
                        //If the oldest member didn't exist, buffer was empty.
200
                        if(head_index == BUFFER_EMPTY) head_index = 0;
201
                
202
                        //Otherwise check for overwritten data.        
203
                        else if(tail_index == head_index) 
204
                                head_index = (head_index +1) % BUFFER_SIZE;  
205
                        
206
                }
207
                pthread_rwlock_unlock(&buffer_lock);
208
                
209
                //Increment for the transmit thread.
210
                packets_received++;
211
        }
212
}
213