Project

General

Profile

Revision 1006

Threading issues worked out better... Ready to add motion.

View differences:

branches/simulator/projects/simulator/simulator/gui/gtk_gui.h
17 17
 **/
18 18
int gtk_gui_run(int argc, char** argv);
19 19

  
20
void gui_refresh(void);
21

  
branches/simulator/projects/simulator/simulator/gui/gtk_environment_view.c
342 342
	return FALSE;
343 343
}
344 344

  
345
	/*gdk_threads_enter();
346
	gtk_widget_queue_draw_area(widget, 0, row, view->width, 1);
347
	gdk_threads_leave();*/
345
void gtk_environment_view_refresh(GtkWidget* view)
346
{
347
	gdk_threads_enter();
348
	gtk_widget_queue_draw(view);
349
	gdk_threads_leave();
350
}
348 351

  
branches/simulator/projects/simulator/simulator/gui/gtk_environment_view.h
45 45
GtkWidget* gtk_environment_view_new(void);
46 46
GtkType gtk_environment_view_get_type(void);
47 47

  
48
void gtk_environment_view_refresh(GtkWidget* view);
49

  
48 50
#endif
49 51

  
branches/simulator/projects/simulator/simulator/gui/gtk_gui.c
5 5
#include "gtk_gui.h"
6 6
#include "gtk_environment_view.h"
7 7

  
8
GtkWidget* window;
9
GtkWidget* view;
10

  
8 11
void destroy_callback(int arg)
9 12
{
10 13
	gtk_main_quit();
......
12 15

  
13 16
int gtk_gui_run(int argc, char** argv)
14 17
{
15
	GtkWidget* window;
16
	GtkWidget* view;
17
	
18
	g_thread_init(NULL);
18
	//g_thread_init(NULL);
19 19
	gdk_threads_init();
20 20
	gdk_threads_enter();
21 21
	gtk_init(&argc, &argv);
......
43 43
	return 0;
44 44
}
45 45

  
46
void gui_refresh()
47
{
48
	gtk_environment_view_refresh(view);
49
}
50

  
branches/simulator/projects/simulator/simulator/core/main.c
9 9

  
10 10
#include <stdlib.h>
11 11
#include <stdio.h>
12
#include <gtk/gtk.h>
13
#include <glib.h>
14
#include <signal.h>
12 15

  
13 16
#include "gtk_gui.h"
14 17
#include "robot.h"
......
22 25
		printf("Usage: simulator <robot execetuable>\n");
23 26
		exit(-1);
24 27
	}
28

  
25 29
	robot_create(argv[1]);
26 30

  
27
	printf("returned to parent\n");
28

  
31
	sigset_t set;
32
	//TODO: errors
33
	sigemptyset(&set);
34
	sigaddset(&set, SIGCHLD);
35
	pthread_sigmask(SIG_BLOCK, &set, NULL);
36
	g_thread_init(NULL);
37
	gdk_threads_init();
38
	g_thread_create(robot_event_loop, NULL, TRUE, NULL);
39
	
40
	//TODO: better thread to put this in?
41
	sigemptyset(&set);
42
	sigaddset(&set, SIGCHLD);
43
	pthread_sigmask(SIG_UNBLOCK, &set, NULL);
44
	
29 45
	gtk_gui_run(argc, argv);
30 46

  
31 47
	return 0;
branches/simulator/projects/simulator/simulator/core/robot.c
20 20
#include <sys/types.h>
21 21
#include <sys/shm.h>
22 22
#include <errno.h>
23
#include <pthread.h>
23 24

  
24 25
#include "robot.h"
26
#include "gtk_gui.h"
25 27

  
26 28
void sig_chld_handler(int sig);
27 29

  
......
30 32
// an expanding array of robots
31 33
Robot* robots = NULL;
32 34
int robots_size = 0;
35
int num_robots = 0;
33 36

  
34 37
int iterator_pos = 0;
35 38

  
39
// signalled when all robots have run for a bit
40
pthread_mutex_t all_finished_mutex;
41
pthread_cond_t all_finished_cond;
42
int finished = 0;
43

  
36 44
int robots_initialize(void)
37 45
{
38 46
	int i;
......
46 54
	memset(robots, 0, sizeof(Robot) * robots_size);
47 55
	for (i = 0; i < robots_size; i++)
48 56
		robots[i].id = -1;
57
	
58
	finished = 0;
59
	pthread_mutex_init(&all_finished_mutex, NULL);
60
	pthread_cond_init(&all_finished_cond, NULL);
49 61

  
50 62
	return 0;
51 63
}
......
59 71
	int pid;
60 72
	int id = first_available_id;
61 73
	Robot* r = &robots[id];
74
	printf("ID: %d\n", id);
62 75
	// do shared memory stuff here
63 76
	key_t key = IPC_PRIVATE;
64 77
	//Memory accessible only to children with r/w privileges
......
120 133
		do {
121 134
			first_available_id++;
122 135
		} while (first_available_id < robots_size &&
123
				robots[first_available_id].id != 0);
136
				robots[first_available_id].id != -1);
124 137
		// resize the array if necessary
125 138
		if (first_available_id >= robots_size)
126 139
		{
......
133 146
			}
134 147
		}
135 148
	}
149

  
150
	num_robots++;
136 151
	
137 152
	return id;
138 153
}
......
182 197
// allocated memory
183 198
Robot* robot_iterator_next(void)
184 199
{
200
	if (iterator_pos >= robots_size)
201
		return NULL;
202
	do iterator_pos++;
185 203
	while (iterator_pos < robots_size && 
186
			robots[iterator_pos].id == -1)
187
		iterator_pos++;
204
			robots[iterator_pos].id == -1);
188 205
	
189 206
	if (iterator_pos >= robots_size)
190 207
		return NULL;
......
194 211

  
195 212
void sig_chld_handler(int sig)
196 213
{
197
	pid_t pid;
198
	int cstat;
214
	pthread_mutex_lock(&all_finished_mutex);
215
	finished++;
216
	if (finished >= num_robots)
217
	{
218
		pthread_cond_signal(&all_finished_cond);
219
	}
220
	pthread_mutex_unlock(&all_finished_mutex);
221
}
199 222

  
200
	printf("SIGCHLD: parent waiting\n");
223
void* robot_event_loop(void* arg)
224
{
225
	int i;
226
	//TODO: errors
201 227

  
202
	pid = waitpid(0, &cstat, WUNTRACED);
228
	while (1)
229
	{
230
		pthread_mutex_lock(&all_finished_mutex);
231
		// TODO: race condition for adding robots?
232
		if (finished < num_robots)
233
		{
234
			pthread_cond_wait(&all_finished_cond, &all_finished_mutex);
235
		}
236
		finished = 0;
237
		pthread_mutex_unlock(&all_finished_mutex);
238
		for (i = 0; i < robots_size; i++)
239
		{
240
			if (robots[i].id == -1)
241
				continue;
242
			kill(robots[i].pid, SIGCONT);
243
		}
203 244

  
204
	printf("got %d from %d\n", cstat, pid);
205

  
206
	kill(pid, SIGCONT);
245
		gui_refresh();
246
	}
207 247
}
208 248

  
branches/simulator/projects/simulator/simulator/core/motion.c
1
#include <stdio.h>
2
#include <math.h>
3

  
4
#include "motion.h"
5

  
6
#define CUTOFF	  120
7
#define ABS(x) (x<0?-x:x)
8
#define TIME      1 /*sec*/
9
#define ROBOT_WIDTH 131 /*mm*/
10

  
11
/** move will move a robot from its initial position, (x,y), and theta (in radians) to a new position given speed.
12
 * (x,y) and theta will be updated by the move function instead of returning a value
13
 * (x,y) is some kind of absolute position in the "world", let's make (0,0) the top left of the "world"
14
 * theta will an angle be between 0 - 2*Pi (0 being faces east)
15
 * speed is between 0 - 255, there is some magical cutoff point before the motors actually starts running
16
 * move will return 0 if successful
17
 **/
18
int move (int *x, int *y, double *theta, int speed1, int speed2) {
19
  if (*theta < 0 || *theta > 2*M_PI) return 1;
20
  if (speed1 < 0 || speed1 > 255) return 1;
21
  if (speed2 < 0 || speed2 > 255) return 1;
22

  
23
  /* if speed is lower than the cut off, don't move */
24
  if (ABS(speed1) < CUTOFF) {
25
    speed1 = 0;
26
  }
27
  if (ABS(speed2) < CUTOFF) {
28
    speed2 = 0;
29
  }
30
  double radius;
31
  if (speed1 == speed2) {
32
  	/* go straight */
33
	*x += cos(*theta) * speed1;
34
	*y += sin(*theta) * speed1;
35
  	return 0;
36
  }
37
  radius = ROBOT_WIDTH * speed1 / (speed1 - speed2);
38
  
39
  double t = speed1 / radius;
40

  
41
  double newx = radius * sin(t);
42
  double newy = radius - radius * cos(t);
43

  
44
  *x += newx * cos(*theta);
45
  *y += newx * sin(*theta);
46

  
47
  *x += newy * - sin(*theta);
48
  *y += newy * cos(*theta);
49

  
50
  *theta = fmod((t + *theta), (2 * M_PI));
51
  if (*theta<0) *theta += 2 * M_PI;
52

  
53
  return 0;
54
}
55

  
branches/simulator/projects/simulator/simulator/core/robot.h
38 38
void robot_iterator_reset(void);
39 39
Robot* robot_iterator_next(void);
40 40

  
41
void* robot_event_loop(void* arg);
42

  
41 43
#endif
42 44

  
branches/simulator/projects/simulator/simulator/Makefile
16 16

  
17 17
INCLUDES = -I$(COMMON_DIR) -I$(CORE_DIR) -I$(GUI_DIR)
18 18

  
19
CFLAGS = -Wall
19
CFLAGS = -Wall -g
20 20
CFLAGS += $(INCLUDES)
21 21
CFLAGS += `pkg-config --cflags gtk+-2.0 gthread-2.0`
22 22

  

Also available in: Unified diff