Project

General

Profile

Revision 1218

Fixing Station/Robot communication

View differences:

trunk/code/projects/diagnostic_station/station/comm_robot.c
1 1
#include <dragonfly_lib.h>
2 2
#include <wireless.h>
3
#include <string.h>
3 4

  
5
#include "global.h"
4 6
#include "comm_robot.h"
5 7
#include "../common/comm_station_robot.h"
6 8

  
7
char new_data = 0;
8
char finished = 0;
9
char data_received[10];
9
//char new_data = 0;
10
//char finished = 0;
11
//char data_received[10];
10 12

  
13
uint8_t received_buffer[10]; // Maximum length of a packet to be handled
14
uint8_t received_length;
15
bool received_data;
16

  
17

  
18

  
19
// *********************
20
// ** Motor direction **
21
// *********************
22

  
23
/**
24
  * All the functions in this file use these motor settings: a pair (direction/velocity) maps to a pair motor_direction/
25
  * motor_velocity. motor_direction and motor_velocity are the values passed to the library functions and also sent
26
  * to the robot. direction also includes an "off" direction. If the direction is off, the motor_velocity is always 0.\
27
  **/
28

  
11 29
char *motor_direction_string (uint8_t direction)
12 30
{
13 31
	if (direction==motor_direction_forward)
......
20 38
		return "?";
21 39
}
22 40

  
23

  
24
static uint8_t motor_direction (uint8_t direction)
41
static uint8_t motor_direction (uint8_t direction, uint8_t velocity)
25 42
{
26 43
	if (direction==motor_direction_backward)
27 44
		return BACKWARD;
......
36 53
	else
37 54
		return velocity;
38 55
}
39
	
40 56

  
57

  
58
// ***************************
59
// ** Common comm functions	**
60
// ***************************
61

  
41 62
// A packet that is followed by a "done" packet from the robot.
42 63
static void send_command_packet (char type, char *data, int len)
43 64
{
44 65
	wl_send_global_packet (station_robot_group, type, data, len, 0);
45 66
	
46
	// TODO: is it guaranteed that the package will be sent on the next call to wl_do, or
67
	// TODO: is it guaranteed that the packet will be sent on the next call to wl_do, or
47 68
	// do we have to call wl_do in a loop?
48 69

  
49 70
	// TODO: wait for "done" from robot.
......
54 75
// A packet that is followed by a data packet from the robot
55 76
static void send_request_packet(char type, char *data, int len)
56 77
{
78
	received_data=false;
79
	
80
	// Send the request packet
57 81
	wl_send_global_packet (station_robot_group, type, data, len, 0);
58
	while(!new_data){
82
	
83
	// When the reply is received, the receive handler will set received_data to the buffer containing the data. Wait
84
	// until this happens, periodically calling the wl_do function to handle incoming messages.
85
	
86
	// FIXME pretend that we received the data right away
87
//	received_data=true;
88
//	received_length=0;
89
	
90
	while(!received_data)
91
	{
59 92
		wl_do();
60 93
	}
61
	new_data = 0;
62 94
}
63 95

  
64 96

  
97
// *************************
98
// ** Individual commands **
99
// *************************
65 100

  
66 101
void robot_set_orbs (uint8_t red1, uint8_t green1, uint8_t blue1, uint8_t red2, uint8_t green2, uint8_t blue2)
67 102
{
......
83 118
{
84 119
	char data[4];
85 120
	
86
	data[0]=motor_direction (direction1);
87
	data[1]=motor_velocity (direction1, speed1);
88
	data[2]=motor_direction (direction2);
89
	data[3]=motor_velocity (direction2, speed2);
121
	data[0]=motor_direction (direction1, speed1);
122
	data[1]=motor_velocity  (direction1, speed1);
123
	data[2]=motor_direction (direction2, speed2);
124
	data[3]=motor_velocity  (direction2, speed2);
90 125
	
91 126
	send_command_packet (station_robot_set_motors, data, 4);
92 127
}
......
96 131
{
97 132
	char data[6];
98 133
	
99
	data[0]=motor_direction (direction1);
100
	data[1]=motor_velocity (direction1, speed1);
101
	data[2]=motor_direction (direction2);
102
	data[3]=motor_velocity (direction2, speed2);
134
	data[0]=motor_direction (direction1, speed1);
135
	data[1]=motor_velocity  (direction1, speed1);
136
	data[2]=motor_direction (direction2, speed1);
137
	data[3]=motor_velocity  (direction2, speed2);
103 138
	data[4]=WORD_BYTE_0(time_ms);
104 139
	data[5]=WORD_BYTE_1(time_ms);
105 140
	
......
121 156
	send_command_packet (station_robot_set_bom, data, 2);
122 157
}
123 158

  
124
char* robot_read_encoders ()
159

  
160
// *************************
161
// ** Individual requests **
162
// *************************
163

  
164
bool robot_read_encoders (int16_t *left, int16_t *right)
125 165
{
126 166
	send_request_packet (station_robot_read_encoders, NULL, 0);
127
	return data_received;
167
	
168
	// Now the received data is in received_data/received_length
169
	if (received_length>=4)
170
	{
171
		*left =WORD(received_buffer[0], received_buffer[1]);
172
		*right=WORD(received_buffer[2], received_buffer[3]);
173
		return true;
174
	}
175
	else
176
	{
177
		return false;
178
	}
128 179
}
129 180

  
130 181
uint16_t robot_read_bom (uint8_t num)
......
139 190
	return 0;
140 191
}
141 192

  
142
void receive_encoders(int* data, int length){
143
	((int*)data_received)[0] = data[0];
144
	((int*)data_received)[1] = data[1];
145
}
146 193

  
147
void robot_station_receive(char type, int source, unsigned char* packet, int length)
194
// ***********************
195
// ** Receive callbacks **
196
// ***********************
197

  
198
static void robot_station_receive (char type, int source, unsigned char* packet, int length)
148 199
{
149
	switch (type)
150
	{
151
		case robot_station_finished:       new_data = 1;                              break;
152
		case robot_station_data_encoders:  receive_encoders((int*)packet, length);   break;
153
	}
154
	new_data = 1;
200
	// Dump the raw packet
201
	//usb_putc ('[');
202
	//for (uint8_t i=0; i<length; ++i)
203
	//{
204
	//	if (i!=0) usb_putc (' ');
205
	//	usb_puti (packet[i]);
206
	//}
207
	//usb_putc (']');
208
	
209
	// We received some data from the robot. It is not handled immediately as some function is waiting for it.
210
	// TODO introduce a separate packet group for done/data/commands (commands are things to be handled immediately).
211
	
212
	// Note the fact that we received some data
213
	received_data=true;
214
	
215
	// The packet buffer might be overwritten after this function returns, so we have to make a copy of the data.
216
	
217
	// First, determine the number of bytes to copy. It is the minimum of the received length and the size of the data
218
	// buffer the data is copied to.
219
	received_length=length;
220
	if (sizeof (received_buffer)<received_length) received_length=sizeof (received_buffer);
221
	
222
	// Now copy the data
223
	memcpy (received_buffer, packet, received_length);
155 224
}
156 225

  
157 226

  
227
// ********************
228
// ** Initialization **
229
// ********************
230

  
231
// Must not be a local variable because the library doesn't make a copy of it.
232
PacketGroupHandler receive_handler={robot_station_group, NULL, NULL, &robot_station_receive, NULL};
233

  
158 234
void comm_robot_init ()
159 235
{
160
	PacketGroupHandler receive_handler = {robot_station_group, NULL, NULL, &robot_station_receive, NULL};
236
	received_data=NULL;
237
	received_length=0;
238

  
239
	usb_puts("# Initializing robot communication" NL);
240
	xbee_init ();
241
	wl_init();
242
	usb_puts("# Done" NL);
243
	
244
	//PacketGroupHandler xxx_receive_handler = {robot_station_group, NULL, NULL, &robot_station_receive, NULL};
161 245
	wl_register_packet_group(&receive_handler);
162 246
}
trunk/code/projects/diagnostic_station/station/comm_robot.h
1 1
#ifndef _robot_comm_h
2 2
#define _robot_comm_h
3 3

  
4
#include <wireless.h>
5

  
4 6
void comm_robot_init (void);
5 7

  
6 8
char *motor_direction_string (uint8_t direction);
......
10 12
void robot_set_motors_off (void);
11 13
void robot_set_bom (uint16_t bitmask);
12 14

  
13
char* robot_read_encoders (void);
15
bool robot_read_encoders (int16_t *left, int16_t *right);
14 16
uint16_t robot_read_bom (uint8_t num);
15 17
uint16_t robot_read_rangefinder (uint8_t num);
16 18

  
17
void robot_station_receive(char type, int source, unsigned char* packet, int length);
18

  
19 19
#define motor_direction_off 0
20 20
#define motor_direction_forward 1
21 21
#define motor_direction_backward 2
trunk/code/projects/diagnostic_station/station/main.c
40 40
{
41 41
	dragonfly_init (0);
42 42
	orb_init ();
43
	orbs_set (0, 0,255,0,0,0);
43

  
44
	// Initialize before using USB
45
	comm_server_init ();
46

  
47
	orb1_set (0, 0, 255);
48
	comm_robot_init ();
49
	orb2_set (0, 0, 255);
50
	
51
	int16_t left=69, right=105;
52
	
53
	while (1)
54
	{
55
		robot_set_motors (motor_direction_backward, 250, motor_direction_forward, 250);
56
		delay_ms (200);
57
	}
58
	
59
	// Encoder test
60
	while (0)
61
	{
62
		bool result=robot_read_encoders (&left, &right);
63
		usb_puti (result);
64
		usb_puts (" ");
65
		usb_puti (left);
66
		usb_puts (" ");
67
		usb_puti (right);
68
		usb_puts (NL);
69
		
70
		delay_ms (200);
71
	}
72
	
44 73
	while (1);
45 74
	return 0;
46 75
}
......
114 143
	hardware_init ();
115 144

  
116 145
	orb1_set (255, 0, 0); usb_puts("# Initializing wireless" NL);
117
	xbee_init ();
118
	wl_init();
146
	comm_robot_init ();
119 147
	orb2_set (255, 0, 0); usb_puts("# Done" NL);
120 148

  
121 149
	// If button 1 is pressed after initialization of the wireless (which takes about 1s), run all tests.
......
134 162
	}
135 163

  
136 164
	while (1);
165
	return 0;
137 166
}
trunk/code/projects/diagnostic_station/robot/main.c
5 5
#include "../common/comm_station_robot.h"
6 6
#include "../../../lib/include/libdragonfly/encoders.h"
7 7

  
8

  
9
// **********************
10
// ** Command handlers **
11
// **********************
12

  
8 13
static void message_set_orbs (int length, uint8_t *data)
9 14
{
10 15
	if (length>=6)
......
53 58
	}
54 59
}
55 60

  
56
static void message_send_encoders (int length, uint8_t *data){
57
	int left = encoder_read(LEFT);
58
	int right = encoder_read(RIGHT);
59
	int vals[2];
60
	vals[0] = left;
61
	vals[1] = right;
62
	wl_send_global_packet (robot_station_group, robot_station_data_encoders, (char*)vals, 8, 0);
61

  
62
// **********************
63
// ** Request handlers **
64
// **********************
65

  
66
static void message_send_encoders (int length, uint8_t *data)
67
{
68
	int16_t left, right;
69
	
70
	SYNC
71
	{
72
		left = encoder_read (LEFT);
73
		right = encoder_read (RIGHT);
74
	}
75
	
76
	char senddata[4];
77
	senddata[0]=WORD_BYTE_0 (left);
78
	senddata[1]=WORD_BYTE_1 (left);
79
	senddata[2]=WORD_BYTE_0 (right);
80
	senddata[3]=WORD_BYTE_1 (right);
81

  
82
	wl_send_global_packet (robot_station_group, robot_station_data_encoders, senddata, 4, 0);
63 83
}
64 84

  
65
void station_robot_receive(char type, int source, unsigned char* packet, int length)
85

  
86
// ***********************
87
// ** Receive callbacks **
88
// ***********************
89

  
90
// TODO: different group for commands and requests
91
static void station_robot_receive (char type, int source, unsigned char* packet, int length)
66 92
{
93
	// TODO why does it keep receiving 0 messages?
94
	//if (type==0) return;
95

  
96
	// Dump the raw packet
97
	usb_puts ("Recvd [");
98
	for (uint8_t i=0; i<length; ++i)
99
	{
100
		if (i!=0) usb_putc (' ');
101
		usb_puti (packet[i]);
102
	}
103
	usb_puts ("]\r\n");
104

  
105

  
106
	
107
	orb_set (0, 0, 255);
108

  
109
	usb_puts ("Received a message: ");
110
	usb_puti (type);
111
	usb_puts ("\r\n");
112
	
67 113
	switch (type)
68 114
	{
115
		// Command messages
69 116
		case station_robot_set_orbs:        message_set_orbs        (length, packet); break;
70 117
		case station_robot_set_motors:      message_set_motors      (length, packet); break;
71 118
		case station_robot_set_bom:         message_set_bom         (length, packet); break;
72 119
		case station_robot_set_motors_off:  message_set_motors_off  (length, packet); break;
73 120
		case station_robot_set_motors_time: message_set_motors_time (length, packet); break;
121
		
122
		// Request messages
74 123
		case station_robot_read_encoders:	message_send_encoders	(length, packet); break;
75 124
	}
125
	
126
	orb_set (255, 127, 0);
76 127
}
77 128

  
129
// **********
130
// ** Main **
131
// **********
78 132

  
79 133
int main(void) {
80
    dragonfly_init(ALL_ON);
134
    dragonfly_init(0);
81 135

  
136
	encoders_init ();
137

  
82 138
    usb_init ();
83 139
    usb_puts ("Diagnostic station robot starting up\r\n");
84 140

  
......
89 145
	wl_init();
90 146
	orb2_set (255, 127, 0);
91 147
	
92
	//usb_puts ("PAN ID: ");  usb_puti (xbee_get_pan_id ());  usb_puts ("\r\n");	// -1
93
	//usb_puts ("Channel: "); usb_puti (xbee_get_channel ()); usb_puts ("\r\n");	// 0
94
	//usb_puts ("Address: "); usb_puti (xbee_get_address ()); usb_puts ("\r\n");	// 4/8
148
	usb_puts ("PAN ID: ");  usb_puti (xbee_get_pan_id ());  usb_puts ("\r\n");	// -1
149
	usb_puts ("Channel: "); usb_puti (xbee_get_channel ()); usb_puts ("\r\n");	// 0
150
	usb_puts ("Address: "); usb_puti (xbee_get_address ()); usb_puts ("\r\n");	// 4/8
95 151
	
96 152
	PacketGroupHandler receive_handler = {station_robot_group, NULL, NULL, &station_robot_receive, NULL};
97 153
	wl_register_packet_group(&receive_handler);

Also available in: Unified diff