Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (5.64 KB)

1
/* This version of receive initializes
2
 * the token ring and then waits for
3
 * the robots to send data.
4
 */
5

    
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <mex.h>
9
#include <pthread.h>
10
#include <unistd.h>
11
#include "../../libwireless/lib/wireless.h"
12
#include "../../libwireless/lib/wl_token_ring.h"
13

    
14
#define WL_COM_PORT "/dev/ttyUSB1" 
15
#define WL_CHANNEL 0xE
16

    
17
#define MAP_REQUEST_GROUP 23
18

    
19
#define DATA_POINT 2 /* packet type for map data points w/ odometry data*/
20
#define DATA_REQUEST 3
21
#define DATA_SERVER_REPLY 4 /*Just to give the robot a target.*/
22
#define DATA_SERVER_IDENTIFY 5
23

    
24
#define BUFFER_SIZE 1000
25

    
26
pthread_rwlock_t buffer_lock;
27
pthread_t receive_thread;
28

    
29
void packet_receive(char type, int source, unsigned char* packet, int length);
30

    
31
PacketGroupHandler requestHandler = {MAP_REQUEST_GROUP, NULL, NULL, &packet_receive, NULL};
32

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

    
39
int tail_index; /*Points to the newest data in the buffers.*/
40
int head_index; /*Points to the oldest data in the buffers.*/
41

    
42
void* run_wireless(void* arg);
43
void init_wireless(void);
44

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

    
55
                pthread_create(&receive_thread, NULL, run_wireless, NULL);
56
                return;
57
        }
58
        
59
        /*Return stuff to matlab*/
60
        /*deliberately ignore nrhs.        */
61

    
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
        int target, index,i,j;
69
        
70
        if(tail_index == -1 || head_index == -1){
71
                double* point, *ranges, *theta, *robot;
72
                /*Appropriately return with nothing. (til I figure that out, return 0's)*/
73
                ret[0] = mxCreateDoubleMatrix(1, 2, mxREAL);
74
                ret[1] = mxCreateDoubleMatrix(1, 5, mxREAL);
75
                ret[2] = mxCreateDoubleMatrix(1, 1, mxREAL);
76
                ret[3] = mxCreateDoubleMatrix(1, 1, mxREAL);
77
                        
78
                point  = mxGetPr(ret[0]);
79
                ranges = mxGetPr(ret[1]);
80
                theta = mxGetPr(ret[2]);
81
                robot = mxGetPr(ret[3]);
82

    
83
                point[0] = point[1] = 0.0;
84
                        
85
                ranges[0] = ranges[1] = ranges[2] = 0.0;
86
                ranges[3] = ranges[4] = 0.0;
87

    
88
                theta[0] = 0.0;
89
                robot[0] = 0.0;
90
        }
91
        else{ /*Copy the buffer data and set the buffer to empty.*/
92
                pthread_rwlock_rdlock(&buffer_lock);
93
                {
94
                        double** point, **ranges, *theta, *robot;
95
                        
96
                        int num_buffer_elements = tail_index - head_index;
97
                        if(num_buffer_elements < 0) num_buffer_elements += BUFFER_SIZE;        
98

    
99
                        ret[0] = mxCreateDoubleMatrix(num_buffer_elements, 2, mxREAL);
100
                        ret[1] = mxCreateDoubleMatrix(num_buffer_elements, 5, mxREAL);
101
                        ret[2] = mxCreateDoubleMatrix(num_buffer_elements, 1, mxREAL);
102
                        ret[3] = mxCreateDoubleMatrix(num_buffer_elements, 1, mxREAL);
103
                
104
                        point  = (double**)mxGetPr(ret[0]);
105
                        ranges = (double**)mxGetPr(ret[1]);
106
                        theta = mxGetPr(ret[2]);
107
                        robot = mxGetPr(ret[3]);
108

    
109
                        for(index = 0; index < num_buffer_elements; index++){
110
                                int target = (tail_index + index) % BUFFER_SIZE;        
111
                                point[i][0] = (double)coordinate_buffer[target][0];        
112
                                point[i][1] = (double)coordinate_buffer[target][1];        
113
                                
114
                                for(j=0;j<5;j++)
115
                                        ranges[i][j] = (double)range_buffer[target][j];
116

    
117
                                theta[i] = (double)(orientation_buffer[target]);        
118
                                robot[i] = (double)(robot_buffer[target]);
119
                        }
120
                        head_index = -1;
121
                        tail_index = -1;
122
                }
123
                pthread_rwlock_unlock(&buffer_lock);
124
        }
125
}
126

    
127
void init_wireless(void){
128
        /*General communication initialization.        */
129
        wl_set_com_port(WL_COM_PORT);        
130
        wl_init();
131
        wl_set_channel(WL_CHANNEL);
132
        wl_register_packet_group(&requestHandler);
133

    
134
        /*Token ring / sensor network initialization.*/
135
        wl_token_ring_register();        
136
}
137

    
138

    
139
/*Call wl_do and occasionally send a broadcast packet declaring the 
140
 * number of the server.
141
 */
142
void* run_wireless(void* arg){
143
        
144
        pthread_detach(pthread_self());
145
        
146
        init_wireless();
147
        printf("Wireless initialized!\n");
148
        
149
        int a = 0;
150
        /*Passively wait for packets to arrive.*/
151
        while(1) wl_do();
152
}
153

    
154
void packet_receive (char type, int source, unsigned char* packet, int length) {
155
        printf("A packet came in!\n");        
156
        if(type==DATA_POINT){        
157

    
158
                if(length!=18) 
159
                        printf("Packet came without the standard length!\n");
160

    
161
                /* expected input: x y theta(double) IR1 IR2 IR3 IR4 IR5*/
162
                /* Pull in data:*/
163
                
164
                short x,y,i;
165
                short ranges[5];        
166
                
167
                x = ((short)packet[1] << 8)  | (short)packet[0];
168
                y = ((short)packet[3] << 8)  | (short)packet[2];
169

    
170
                for(i=0; i<5; i++){
171
                        ranges[i] 
172
                           = ((short)packet[8+2*i+1] << 8) | (short)packet[8 + 2*i];
173
                }
174

    
175
                float theta = *((float*)(packet + 4));
176
        
177
                /*Write new data to buffers. (Lock down!)*/
178
                pthread_rwlock_wrlock(&buffer_lock);
179
                {        
180
                        /*Note that you write no matter what.
181
                        * Also, if the buffer is empty, tail_index becomes 0*/
182
                        tail_index = (tail_index + 1) % BUFFER_SIZE; 
183
                        
184
                        /*Write the robots number.*/
185
                        robot_buffer[tail_index] = source;
186
                        
187
                        /*Write in range data.*/
188
                        for(i=0; i<5; i++) range_buffer[tail_index][i] = ranges[i];
189
                        
190
                        coordinate_buffer[tail_index][0] = x;
191
                        coordinate_buffer[tail_index][1] = y;
192
                        
193
                        orientation_buffer[tail_index] = theta;
194
                        
195
                        /*If the oldest member didn't exist, buffer was empty.*/
196
                        if(head_index == -1) head_index = 0;
197
                
198
                        /*Otherwise check for overwritten data.        */
199
                        else if(tail_index == head_index) 
200
                                head_index = (head_index + 1) % BUFFER_SIZE;  
201
                        
202
                }
203
                pthread_rwlock_unlock(&buffer_lock);
204
        }
205
        else if(type == DATA_SERVER_IDENTIFY){
206
                /*Sleep before sending an identity packet.*/
207
                usleep(50000);
208
                wl_send_global_packet(MAP_REQUEST_GROUP, DATA_SERVER_REPLY, NULL, 0, 0);
209
                printf("Announcing self as server\n");
210
        }
211
}
212