Project

General

Profile

Revision 1028

Changes all around. Matlab server is now passive, might work soon.

View differences:

trunk/code/projects/mapping/matlab/receive2.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_REQUEST_GROUP 23
13

  
14
#define DATA_POINT 2 /* packet type for map data points w/ odometry data*/
15
#define DATA_REQUEST 3
16

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

  
20
pthread_rwlock_t buffer_lock;
21
pthread_t receive_thread;
22

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

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

  
27
PacketGroupHandler requestHandler = {MAP_REQUEST_GROUP, NULL, NULL, &packet_receive, NULL};
28

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

  
35
int tail_index; /*Points to the newest data in the buffers.*/
36
int head_index; /*Points to the oldest data in the buffers.*/
37

  
38
void init_wireless(void);
39
void* run_wireless(void*);
40

  
41
void mexFunction(int nlhs, mxArray* ret[], int nrhs, const mxArray* args[]){
42
	
43
	if(nrhs == 1){	
44
		
45
		/*Initialization*/
46
		init_wireless();
47
		
48
		pthread_rwlock_init(&buffer_lock, NULL);
49
		pthread_create(&receive_thread, NULL, run_wireless, NULL);
50
		
51
		return;
52
	}
53
	
54
	/*Return stuff to matlab*/
55
	/*deliberately ignore nrhs.	*/
56

  
57
	if(nlhs != 4){
58
		mexErrMsgTxt("Error: Expect output arguments [P IR T R]\n  \
59
					  where P = [X Y], IR = [IR1, IR2 ...],\n \
60
					  T = angle, and R = Robot number."); 
61
	}
62
	
63
	int index,i,j;
64
	
65
	pthread_rwlock_rdlock(&buffer_lock);
66
	{
67

  
68
		if(tail_index == BUFFER_EMPTY || head_index == BUFFER_EMPTY){
69
			double* point, *ranges, *theta, *robot;
70
			
71
			/*Appropriately return with nothing. (all 0's)*/
72
			ret[0] = mxCreateDoubleMatrix(1, 2, mxREAL);
73
			ret[1] = mxCreateDoubleMatrix(1, 5, mxREAL);
74
			ret[2] = mxCreateDoubleMatrix(1, 1, mxREAL);
75
			ret[3] = mxCreateDoubleMatrix(1, 1, mxREAL);
76
			
77
			point  = mxGetPr(ret[0]);
78
			ranges = mxGetPr(ret[1]);
79
			theta = mxGetPr(ret[2]);
80
			robot = mxGetPr(ret[3]);
81

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

  
87
			theta[0] = 0.0;
88
			robot[0] = 0.0;
89

  
90
			return;
91
		}
92

  
93
		else{
94
			double** point, **ranges, *theta, *robot;
95
			
96
			int buf_count, 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
			/*This may not work on some computers.*/
105
			point  = (double**)mxGetPr(ret[0]);
106
			ranges = (double**)mxGetPr(ret[1]);
107
			theta = mxGetPr(ret[2]);
108
			robot = mxGetPr(ret[3]);
109
			
110
			for(index = head_index, buf_count = 0; buf_count < num_buffer_elements; 
111
				buf_count++, index = (index + 1)%1024){
112
				
113
				point[i][0] = (double)coordinate_buffer[index][0];	
114
				point[i][1] = (double)coordinate_buffer[index][1];	
115
				
116
				for(j=0;j<5;j++)
117
					ranges[i][j] = (double)range_buffer[index][j];
118

  
119
				theta[i] = (double)(orientation_buffer[index]);	
120
				robot[i] = (double)(robot_buffer[index]);
121
			}
122

  
123
			head_index = tail_index = BUFFER_EMPTY;
124
		}
125
	}	
126
	pthread_rwlock_unlock(&buffer_lock);
127
}
128

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

  
136
	/*Token ring / sensor network initialization.*/
137
	wl_token_ring_register();	
138
}
139

  
140
void* run_wireless(void* arg){
141
	pthread_detach(pthread_self());
142
	while(1){
143
		wl_do();
144
		usleep(5000);
145
	}
146
}
147

  
148
void packet_receive (char type, int source, unsigned char* packet, int length) {
149
	printf("A packet came in!\n");	
150
	if(type==DATA_POINT){	
151

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

  
154
		/* expected input: x y theta(double) IR1 IR2 IR3 IR4 IR5*/
155
		/* Pull in data:*/
156
		
157
		short x,y,i;
158
		short ranges[5];	
159
		
160
		x = ((short)packet[1] << 8)  | (short)packet[0];
161
		y = ((short)packet[3] << 8)  | (short)packet[2];
162

  
163
		for(i=0; i<5; i++){
164
			ranges[i] 
165
			   = ((short)packet[8+2*i+1] << 8) | (short)packet[8 + 2*i];
166
		}
167

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

  
trunk/code/projects/mapping/matlab/receive.c
12 12
#include "../../libwireless/lib/wireless.h"
13 13
#include "../../libwireless/lib/wl_token_ring.h"
14 14

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

  
18 18
#define MAP_REQUEST_GROUP 23
19 19

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

  
23 24
#define BUFFER_SIZE 1000
24 25
#define BUFFER_EMPTY -1
......
26 27
pthread_rwlock_t buffer_lock;
27 28
pthread_t receive_thread;
28 29

  
29
int packets_received; /*Used to block overlapping packet requests.*/
30

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

  
33 32
PacketGroupHandler requestHandler = {MAP_REQUEST_GROUP, NULL, NULL, &packet_receive, NULL};
......
41 40
int tail_index; /*Points to the newest data in the buffers.*/
42 41
int head_index; /*Points to the oldest data in the buffers.*/
43 42

  
44
void* buffer_data(void* arg);
43
void* run_wireless(void* arg);
45 44
void init_wireless(void);
46 45

  
47 46
void mexFunction(int nlhs, mxArray* ret[], int nrhs, const mxArray* args[]){
......
54 53
 		
55 54
		pthread_rwlock_init(&buffer_lock, NULL);
56 55

  
57
		pthread_create(&receive_thread, NULL, buffer_data, NULL);
56
		pthread_create(&receive_thread, NULL, run_wireless, NULL);
58 57
		return;
59 58
	}
60 59
	
......
74 73

  
75 74
		if(tail_index == BUFFER_EMPTY || head_index == BUFFER_EMPTY){
76 75
			double* point, *ranges, *theta, *robot;
77
			/*Appropriately return with nothing.*/
76
			/*Appropriately return with nothing. (til I figure that out, return 0's)*/
78 77
			ret[0] = mxCreateDoubleMatrix(1, 2, mxREAL);
79 78
			ret[1] = mxCreateDoubleMatrix(1, 5, mxREAL);
80 79
			ret[2] = mxCreateDoubleMatrix(1, 1, mxREAL);
......
93 92
			theta[0] = 0.0;
94 93
			robot[0] = 0.0;
95 94

  
96
			return;
97 95
		}
98
		else{
96
		else{ /*Copy the buffer data and set the buffer to empty.*/
99 97
			double** point, **ranges, *theta, *robot;
100 98
			
101 99
			int num_buffer_elements = tail_index - head_index;
......
106 104
			ret[2] = mxCreateDoubleMatrix(num_buffer_elements, 1, mxREAL);
107 105
			ret[3] = mxCreateDoubleMatrix(num_buffer_elements, 1, mxREAL);
108 106
		
109
			/*This may not work on some computers.*/
110 107
			point  = (double**)mxGetPr(ret[0]);
111 108
			ranges = (double**)mxGetPr(ret[1]);
112 109
			theta = mxGetPr(ret[2]);
......
140 137
	wl_token_ring_register();	
141 138
}
142 139

  
143
/*
144
 * buffer_data continuously runs through the robots and
145
 * waits for them to respond.
140

  
141
/*Call wl_do and occasionally send a broadcast packet declaring the 
142
 * number of the server.
146 143
 */
147
void* buffer_data(void* arg){
144
void* run_wireless(void* arg){
148 145
	int robot_num, num_robots,time_out, i;	
149 146

  
150 147
	pthread_detach(pthread_self());
151 148
	
152 149
	init_wireless();
150
	printf("Wireless initialized\n");
153 151
	
154
	/*Continuously iterate over all the robots - buffering data.*/
155
	
152
	int a = 0;
156 153
	while(1){
154
		/*Passively wait for packets to arrive.*/
157 155
		wl_do();
158

  
159
		printf("sending new round of packets\n");	
160
		wl_token_iterator_begin();
161
		
162
		num_robots = wl_token_get_num_robots();
163
		
164
		/*Initialize the 'packets received' number. */
165
		packets_received = 0;
166
	
167
		/*Send a data request to all robots.*/
168
		while(wl_token_iterator_has_next()){
169
			wl_do();
170
			
171
			robot_num = wl_token_iterator_next();
172
    		
173
			printf("sending a packet to robot %d\n",robot_num);
174
			wl_send_robot_to_robot_global_packet(MAP_REQUEST_GROUP, 
175
				DATA_REQUEST, NULL, 0, robot_num, 0);
176
            	
177
			for(i=0;i<50;i++){
178
				wl_do();	
179
				usleep(10000); /*500ms*/
180
			}
181
		}
182
		
183
		time_out = 50; /*50 * 10ms = 1s*/
184

  
185
		/*Wait for all packets to be received 
186
		 * before sending more requests.
187
		 * ring etc.) For example, if a robot drops
188
		 * a packet (highly likely) it is not dealt with
189
		 * */
190
		while(packets_received < num_robots 
191
		   && packets_received < wl_token_get_num_robots() && time_out){
192
			
193
			wl_do();
194
			time_out--;	
195
			usleep(10000); /*10ms*/
196
		}
197

  
198
		for(i=0;i<50;i++){
199
			wl_do();	
200
			usleep(10000); /*500ms*/
201
		}
202 156
	}
203 157
}
204 158

  
......
206 160
	printf("A packet came in!\n");	
207 161
	if(type==DATA_POINT){	
208 162

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

  
211 166
		/* expected input: x y theta(double) IR1 IR2 IR3 IR4 IR5*/
212 167
		/* Pull in data:*/
......
250 205
			
251 206
		}
252 207
		pthread_rwlock_unlock(&buffer_lock);
253
		
254
		/*Increment for the transmit thread.*/
255
		packets_received++;
256 208
	}
209
	if(type == DATA_INIT){
210
		wl_send_global_packet(MAP_REQUEST_GROUP, DATA_INIT, NULL, 0, 0);
211
		printf("Announcing self as server\n");
212
	}
257 213
}
258 214

  
trunk/code/projects/mapping/matlab/testRobot/test.c
4 4

  
5 5
#include <dragonfly_lib.h>
6 6
#include <wireless.h>
7
#include <wl_token_ring.h>
7 8
#include <encoders.h>
9
#include <bom.h>
8 10
#include "odometry.h"
9 11

  
10 12
#define MAP_REQUEST_GROUP 23
11 13

  
14
#define DATA_INIT 4
12 15
#define DATA_POINT 2 
13 16
#define DATA_REQUEST 3
14 17

  
18
#define WL_CHANNEL = 0xE
19

  
15 20
int state;
16 21
int velocity;
22
int server = -1;
17 23
char buf[100];
18 24

  
19 25
void respond(char type, int source, unsigned char* packet, int length);
26
void transmit(void);
20 27

  
21 28
PacketGroupHandler requestHandler = {MAP_REQUEST_GROUP, 
22 29
	NULL, NULL, respond, NULL};
......
24 31
int main(void)
25 32
{
26 33
    /* initialize components and join the token ring */
27
    dragonfly_init(ORB | RANGE | BOM | COMM);
34
    dragonfly_init(RANGE | BOM | COMM);
28 35
    odometry_init();
29 36
    
30 37
	wl_init();
31
    wl_set_channel(0xE);
38
    wl_set_channel(WL_CHANNEL);
32 39
    wl_register_packet_group(&requestHandler);
33 40
    
34 41
    wl_token_ring_register();
42
	wl_token_ring_set_bom_functions(transmit, bom_off, get_max_bom);
35 43
    wl_token_ring_join();
36 44

  
37 45
    while(1)
......
58 66
		store[7] = 125;	// IR4 range
59 67
		store[8] = 125;	// IR5 range
60 68

  
69
		char* data = (char*)store;
70

  
61 71
		wl_send_robot_to_robot_global_packet(MAP_REQUEST_GROUP, 
62
			DATA_POINT, &store, 0, source, 0);
72
			DATA_POINT, data, 18, source, 0);
63 73
	}
74
	else if(type==DATA_INIT){
75
		server = source;
76
	}
64 77
}
65 78

  
79
void transmit(){
80
	bom_on();
66 81

  
82
	/*If a server hasn't declared itself, return.*/
83
	if(server == -1) return;
84
	
85
	int store[9];
86
	store[0] = 0; //X
87
    store[1] = 0; //Y
88
    *((double*)(store + 2)) = 5.0; //Theta.
89
    store[4] = 125;	// IR1 range
90
	store[5] = 125;	// IR2 range
91
	store[6] = 125;	// IR3 range
92
	store[7] = 125;	// IR4 range
93
	store[8] = 125;	// IR5 range
94

  
95
	char* data = (char*)store;
96

  
97
	wl_send_robot_to_robot_global_packet(MAP_REQUEST_GROUP, 
98
		DATA_POINT, data, 18, server, 0);
99
}
100

  
101

  
102

  
trunk/code/projects/mapping/matlab/testRobot/Makefile
8 8
endif
9 9

  
10 10
# Target file name (without extension).
11
TARGET = robot_main
11
TARGET = test
12 12

  
13 13
# Uncomment this to use the wireless library
14 14
USE_WIRELESS = 1
trunk/code/projects/mapping/matlab/Makefile
2 2
CFLAGS=
3 3
LIBS= -lpthread -lwireless
4 4

  
5
all: receive receive2
5
all: receive
6 6

  
7 7
test: *.c ../../libwireless/lib/*.c 
8 8
	$(CC) $(CFLAGS) *.c -L../../../lib/bin -DWL_DEBUG $(LIBS)
......
10 10
receive:
11 11
	 mex -g receive.c -L../../libwireless/lib -lwireless
12 12

  
13
receive2:
14
	 mex -g receive2.c -L../../libwireless/lib -lwireless
15

  
16 13
clean:
17 14
	rm *.o 
18 15

  

Also available in: Unified diff