Index: branches/simulator/projects/simulator/simulator/gui/gtk_gui.h
===================================================================
--- branches/simulator/projects/simulator/simulator/gui/gtk_gui.h	(revision 1005)
+++ branches/simulator/projects/simulator/simulator/gui/gtk_gui.h	(revision 1006)
@@ -17,3 +17,5 @@
  **/
 int gtk_gui_run(int argc, char** argv);
 
+void gui_refresh(void);
+
Index: branches/simulator/projects/simulator/simulator/gui/gtk_environment_view.c
===================================================================
--- branches/simulator/projects/simulator/simulator/gui/gtk_environment_view.c	(revision 1005)
+++ branches/simulator/projects/simulator/simulator/gui/gtk_environment_view.c	(revision 1006)
@@ -342,7 +342,10 @@
 	return FALSE;
 }
 
-	/*gdk_threads_enter();
-	gtk_widget_queue_draw_area(widget, 0, row, view->width, 1);
-	gdk_threads_leave();*/
+void gtk_environment_view_refresh(GtkWidget* view)
+{
+	gdk_threads_enter();
+	gtk_widget_queue_draw(view);
+	gdk_threads_leave();
+}
 
Index: branches/simulator/projects/simulator/simulator/gui/gtk_environment_view.h
===================================================================
--- branches/simulator/projects/simulator/simulator/gui/gtk_environment_view.h	(revision 1005)
+++ branches/simulator/projects/simulator/simulator/gui/gtk_environment_view.h	(revision 1006)
@@ -45,5 +45,7 @@
 GtkWidget* gtk_environment_view_new(void);
 GtkType gtk_environment_view_get_type(void);
 
+void gtk_environment_view_refresh(GtkWidget* view);
+
 #endif
 
Index: branches/simulator/projects/simulator/simulator/gui/gtk_gui.c
===================================================================
--- branches/simulator/projects/simulator/simulator/gui/gtk_gui.c	(revision 1005)
+++ branches/simulator/projects/simulator/simulator/gui/gtk_gui.c	(revision 1006)
@@ -5,6 +5,9 @@
 #include "gtk_gui.h"
 #include "gtk_environment_view.h"
 
+GtkWidget* window;
+GtkWidget* view;
+
 void destroy_callback(int arg)
 {
 	gtk_main_quit();
@@ -12,10 +15,7 @@
 
 int gtk_gui_run(int argc, char** argv)
 {
-	GtkWidget* window;
-	GtkWidget* view;
-	
-	g_thread_init(NULL);
+	//g_thread_init(NULL);
 	gdk_threads_init();
 	gdk_threads_enter();
 	gtk_init(&argc, &argv);
@@ -43,3 +43,8 @@
 	return 0;
 }
 
+void gui_refresh()
+{
+	gtk_environment_view_refresh(view);
+}
+
Index: branches/simulator/projects/simulator/simulator/core/main.c
===================================================================
--- branches/simulator/projects/simulator/simulator/core/main.c	(revision 1005)
+++ branches/simulator/projects/simulator/simulator/core/main.c	(revision 1006)
@@ -9,6 +9,9 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <signal.h>
 
 #include "gtk_gui.h"
 #include "robot.h"
@@ -22,10 +25,23 @@
 		printf("Usage: simulator <robot execetuable>\n");
 		exit(-1);
 	}
+
 	robot_create(argv[1]);
 
-	printf("returned to parent\n");
-
+	sigset_t set;
+	//TODO: errors
+	sigemptyset(&set);
+	sigaddset(&set, SIGCHLD);
+	pthread_sigmask(SIG_BLOCK, &set, NULL);
+	g_thread_init(NULL);
+	gdk_threads_init();
+	g_thread_create(robot_event_loop, NULL, TRUE, NULL);
+	
+	//TODO: better thread to put this in?
+	sigemptyset(&set);
+	sigaddset(&set, SIGCHLD);
+	pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+	
 	gtk_gui_run(argc, argv);
 
 	return 0;
Index: branches/simulator/projects/simulator/simulator/core/robot.c
===================================================================
--- branches/simulator/projects/simulator/simulator/core/robot.c	(revision 1005)
+++ branches/simulator/projects/simulator/simulator/core/robot.c	(revision 1006)
@@ -20,8 +20,10 @@
 #include <sys/types.h>
 #include <sys/shm.h>
 #include <errno.h>
+#include <pthread.h>
 
 #include "robot.h"
+#include "gtk_gui.h"
 
 void sig_chld_handler(int sig);
 
@@ -30,9 +32,15 @@
 // an expanding array of robots
 Robot* robots = NULL;
 int robots_size = 0;
+int num_robots = 0;
 
 int iterator_pos = 0;
 
+// signalled when all robots have run for a bit
+pthread_mutex_t all_finished_mutex;
+pthread_cond_t all_finished_cond;
+int finished = 0;
+
 int robots_initialize(void)
 {
 	int i;
@@ -46,6 +54,10 @@
 	memset(robots, 0, sizeof(Robot) * robots_size);
 	for (i = 0; i < robots_size; i++)
 		robots[i].id = -1;
+	
+	finished = 0;
+	pthread_mutex_init(&all_finished_mutex, NULL);
+	pthread_cond_init(&all_finished_cond, NULL);
 
 	return 0;
 }
@@ -59,6 +71,7 @@
 	int pid;
 	int id = first_available_id;
 	Robot* r = &robots[id];
+	printf("ID: %d\n", id);
 	// do shared memory stuff here
 	key_t key = IPC_PRIVATE;
 	//Memory accessible only to children with r/w privileges
@@ -120,7 +133,7 @@
 		do {
 			first_available_id++;
 		} while (first_available_id < robots_size &&
-				robots[first_available_id].id != 0);
+				robots[first_available_id].id != -1);
 		// resize the array if necessary
 		if (first_available_id >= robots_size)
 		{
@@ -133,6 +146,8 @@
 			}
 		}
 	}
+
+	num_robots++;
 	
 	return id;
 }
@@ -182,9 +197,11 @@
 // allocated memory
 Robot* robot_iterator_next(void)
 {
+	if (iterator_pos >= robots_size)
+		return NULL;
+	do iterator_pos++;
 	while (iterator_pos < robots_size && 
-			robots[iterator_pos].id == -1)
-		iterator_pos++;
+			robots[iterator_pos].id == -1);
 	
 	if (iterator_pos >= robots_size)
 		return NULL;
@@ -194,15 +211,38 @@
 
 void sig_chld_handler(int sig)
 {
-	pid_t pid;
-	int cstat;
+	pthread_mutex_lock(&all_finished_mutex);
+	finished++;
+	if (finished >= num_robots)
+	{
+		pthread_cond_signal(&all_finished_cond);
+	}
+	pthread_mutex_unlock(&all_finished_mutex);
+}
 
-	printf("SIGCHLD: parent waiting\n");
+void* robot_event_loop(void* arg)
+{
+	int i;
+	//TODO: errors
 
-	pid = waitpid(0, &cstat, WUNTRACED);
+	while (1)
+	{
+		pthread_mutex_lock(&all_finished_mutex);
+		// TODO: race condition for adding robots?
+		if (finished < num_robots)
+		{
+			pthread_cond_wait(&all_finished_cond, &all_finished_mutex);
+		}
+		finished = 0;
+		pthread_mutex_unlock(&all_finished_mutex);
+		for (i = 0; i < robots_size; i++)
+		{
+			if (robots[i].id == -1)
+				continue;
+			kill(robots[i].pid, SIGCONT);
+		}
 
-	printf("got %d from %d\n", cstat, pid);
-
-	kill(pid, SIGCONT);
+		gui_refresh();
+	}
 }
 
Index: branches/simulator/projects/simulator/simulator/core/motion.c
===================================================================
--- branches/simulator/projects/simulator/simulator/core/motion.c	(nonexistent)
+++ branches/simulator/projects/simulator/simulator/core/motion.c	(revision 1006)
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "motion.h"
+
+#define CUTOFF	  120
+#define ABS(x) (x<0?-x:x)
+#define TIME      1 /*sec*/
+#define ROBOT_WIDTH 131 /*mm*/
+
+/** move will move a robot from its initial position, (x,y), and theta (in radians) to a new position given speed.
+ * (x,y) and theta will be updated by the move function instead of returning a value
+ * (x,y) is some kind of absolute position in the "world", let's make (0,0) the top left of the "world"
+ * theta will an angle be between 0 - 2*Pi (0 being faces east)
+ * speed is between 0 - 255, there is some magical cutoff point before the motors actually starts running
+ * move will return 0 if successful
+ **/
+int move (int *x, int *y, double *theta, int speed1, int speed2) {
+  if (*theta < 0 || *theta > 2*M_PI) return 1;
+  if (speed1 < 0 || speed1 > 255) return 1;
+  if (speed2 < 0 || speed2 > 255) return 1;
+
+  /* if speed is lower than the cut off, don't move */
+  if (ABS(speed1) < CUTOFF) {
+    speed1 = 0;
+  }
+  if (ABS(speed2) < CUTOFF) {
+    speed2 = 0;
+  }
+  double radius;
+  if (speed1 == speed2) {
+  	/* go straight */
+	*x += cos(*theta) * speed1;
+	*y += sin(*theta) * speed1;
+  	return 0;
+  }
+  radius = ROBOT_WIDTH * speed1 / (speed1 - speed2);
+  
+  double t = speed1 / radius;
+
+  double newx = radius * sin(t);
+  double newy = radius - radius * cos(t);
+
+  *x += newx * cos(*theta);
+  *y += newx * sin(*theta);
+
+  *x += newy * - sin(*theta);
+  *y += newy * cos(*theta);
+
+  *theta = fmod((t + *theta), (2 * M_PI));
+  if (*theta<0) *theta += 2 * M_PI;
+
+  return 0;
+}
+
Index: branches/simulator/projects/simulator/simulator/core/robot.h
===================================================================
--- branches/simulator/projects/simulator/simulator/core/robot.h	(revision 1005)
+++ branches/simulator/projects/simulator/simulator/core/robot.h	(revision 1006)
@@ -38,5 +38,7 @@
 void robot_iterator_reset(void);
 Robot* robot_iterator_next(void);
 
+void* robot_event_loop(void* arg);
+
 #endif
 
Index: branches/simulator/projects/simulator/simulator/Makefile
===================================================================
--- branches/simulator/projects/simulator/simulator/Makefile	(revision 1005)
+++ branches/simulator/projects/simulator/simulator/Makefile	(revision 1006)
@@ -16,7 +16,7 @@
 
 INCLUDES = -I$(COMMON_DIR) -I$(CORE_DIR) -I$(GUI_DIR)
 
-CFLAGS = -Wall
+CFLAGS = -Wall -g
 CFLAGS += $(INCLUDES)
 CFLAGS += `pkg-config --cflags gtk+-2.0 gthread-2.0`
 
