Project

General

Profile

Revision 952

Wrote mex file code to interface between matlab and the wireless library.

View differences:

trunk/code/projects/mapping/matlab/receive.c
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
	
59
	/*Return stuff to matlab
60
	//deliberately ignore nrhs.	
61
	if(nlhs != 4){
62
		mexErrMsgTxt("Error: Expect output arguments [P IR T R]\n 
63
					  where P = [X Y], IR = [IR1, IR2 ...],\n
64
					  T = angle, and R = Robot number."); 
65
	}
66
	
67
	double* point, ranges, theta;
68
	int index,i,j;
69
	
70
	pthread_rwlock_rdlock(&buffer_lock);
71
	{
72

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

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

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

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

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

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

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

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

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

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

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

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

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

  
trunk/code/projects/mapping/matlab/Makefile
1
CC= gcc
2
CFLAGS= -Wall -g
3
LIBS= -lpthread -lwireless
4

  
5
all: test
6

  
7
test: *.c ../../libwireless/lib/*.c 
8
	$(CC) $(CFLAGS) *.c -L../../../lib/bin -o test -DWL_DEBUG $(LIBS)
9

  
10
clean:
11
	rm *.o test ../lib/*.o
12

  

Also available in: Unified diff