diff --git a/groundStation/Makefile b/groundStation/Makefile
index 9123a2455fe5743716377865f398de713d0cef6e..50c78782e80cb912a6eb2f42906b7c363e774a06 100644
--- a/groundStation/Makefile
+++ b/groundStation/Makefile
@@ -3,8 +3,8 @@
 # Generic Variables
 GCC=gcc
 GXX=g++
-CFLAGS= -Wall -Wpedantic -Wextra -Werror -std=c99 -g -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-but-set-variable
-CXXFLAGS= -Wall -Wpedantic -Wextra -Werror -Wno-reorder -Wno-unused-variable -std=c++0x -g
+CFLAGS= -Wall -pedantic -Wextra -Werror -std=gnu99 -g -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-but-set-variable
+CXXFLAGS= -Wall -pedantic -Wextra -Werror -Wno-reorder -Wno-unused-variable -std=c++0x -g
 INCLUDES = $(foreach dir, $(INCDIR), -I$(dir))
 INCDIR=inc src/vrpn src/vrpn/quat src/vrpn/build $(BESRCDIR) $(CLISRCDIR) $(FESRCDIR)
 LIBS= -lpthread -lbluetooth -lvrpn -lquat -Lsrc/vrpn/build -Lsrc/vrpn/build/quat 
diff --git a/groundStation/README.md b/groundStation/README.md
index c7ee059c939ef9d4b414452817818937b48996ea..a54b1f43611542c3792549e51f1509bc187a5428 100644
--- a/groundStation/README.md
+++ b/groundStation/README.md
@@ -23,3 +23,41 @@ If you wish to change the way the backend communicates to the quad and vice vers
 
 ## Modifying
 See MODIFYING for the software architecture/organization and how to add new functionality.
+
+## Using
+First, the backend daemon must be running. Run the backend with ./BackEnd. Note
+the environment variables in config.h, especially the backend socket path. The backend
+requires root for bluetooth, but can run as a normal user with TCP, as long as the
+socket path is writable by the user.
+
+Once the backend is running, various CLI tools can be used to view the state of the
+quad and send commands. Each of these tools is given as the first argument
+to the CLI program, for example, to monitor the quad, use `cli monitor`. Note that
+the backend socket environment variable must be set to the same value as it
+was for the backend. The CLI program also supports busybox-style symbolic links.
+For example, if there is a symlink named `monitor` that points to the `cli` binary,
+running the `monitor` program will effectively run `cli monitor`.
+
+The names of the binaries is subject to change.
+
+### Example
+In one terminal or screen, run the backend:
+
+`UCART_SOCKET=./ucart.socket ./BackEnd`
+
+This will activate the quad and the backend, and the backend will be available for
+connections from the frontend tools. One useful tool is the monitor. In another
+terminal window, run the monitor forever:
+
+`UCART_SOCKET=./ucart.socket ./cli monitor -f`
+
+This will begin a periodic monitoring that updates 10 times per second.
+
+Finally, in a third window, export the socket path:
+
+`export UCART_SOCKET=./ucart.socket`
+
+and then run any other tools to modify the quad, for example modifying PID constants:
+
+`./cli setpid --pitch -p 1.000`
+
diff --git a/groundStation/src/backend/backend.c b/groundStation/src/backend/backend.c
index 6cb684e0bb3a9e97f4802ba449fef244e236f44a..8b523c2749b0b9c929242b74af45c912a1cfa3d0 100644
--- a/groundStation/src/backend/backend.c
+++ b/groundStation/src/backend/backend.c
@@ -40,6 +40,9 @@
 #define CMD_MAX_LENGTH 1024
 #define MAX_HASH_SIZE 50
 
+/* Backend-internal command magics */
+#define TD_MAGIC "TRACKERDATA"
+
 // function prototypes
 void readAndPrint(void);
 void sendVrpnPacket(struct ucart_vrpn_TrackerData *);
@@ -267,6 +270,7 @@ int main(int argc, char **argv)
 							}
 						}
 					} else if (get_client_index(fd) > -1) {
+						/* It is a socket to a frontend */
 						client_recv(fd);
 					}
 				}
@@ -625,7 +629,40 @@ static void client_recv(int fd) {
 		printf("Client(%d) : '%s'\n",fd, buffer);
 		unsigned char * packet;
 		if(formatCommand(buffer, &packet) == -1) {
-			printf("Could not recognize command '%s'\n", buffer);
+			/* buffer was not a quad command, handling internally to
+			 * backend instead of forwarding to quad
+			 */
+			if (strncmp(buffer, TD_MAGIC, strlen(TD_MAGIC)) == 0) {
+				/* Request for tracker data */
+				struct ucart_vrpn_TrackerData td;
+				if (tracker == NULL) {
+					char * dummy = TD_MAGIC " 1.0 2.0 3.0 4.0 5.0 6.0\n";
+					write(fd, dummy, strlen(dummy));
+				}else if (ucart_vrpn_tracker_getData(tracker, &td)) {
+					write(fd, TD_MAGIC " ERROR\n", strlen(TD_MAGIC " ERROR\n"));
+				} else { 
+					/* more than sufficient buffer */
+					char buffer[2048];
+					/* Map VRPN XYZ to Height Lat Long (right now it's
+					 * a guess). Format is Height Lat Long P R Y */
+					if (snprintf(buffer,
+							2048,
+							TD_MAGIC " %lf %lf %lf %lf %lf %lf\n",
+							td.z,
+							td.y,
+							td.x,
+							td.pitch,
+							td.roll,
+							td.yaw) >= 2048) {
+
+						/* Output longer than buffer */
+						warnx("Increase format buffer size, output was too long!");
+						write(fd, TD_MAGIC " ERROR\n", strlen(TD_MAGIC " ERROR\n"));
+					}
+					write(fd, buffer, strlen(buffer));
+				}
+			}
+
 		} else {
 			if(clientAddPendResponses(fd, packet) == -1) {
 				warnx("Ran out of room! Consider increasing CLIENT_MAX_PENDING_RESPONSES!");
diff --git a/groundStation/src/cli/cli.h b/groundStation/src/cli/cli.h
index 2951fd8d4c648038ab5fb94f7d261ad6e73ecfba..f4c2fe3f4783b9b4a4dd1e3482cdf3034cbaf269 100644
--- a/groundStation/src/cli/cli.h
+++ b/groundStation/src/cli/cli.h
@@ -2,29 +2,29 @@
 #define __CLI_H
 
 #include "cli_monitor.h"
-// #include "cli_setpid.h"
+#include "cli_setpid.h"
 #include "cli_getpid.h"
 // #include "cli_getimu.h"
 enum CommandNameIds{
 	CMD_MONITOR,
-	CMD_SETPID,
 	CMD_GETPID,
+	CMD_SETPID,
 	CMD_GETIMU,
 	MAX_COMMANDS
 };
 
 typedef int (*cli_function_ptr)(struct backend_conn *, int, char **);
-static cli_function_ptr cli_functions[2] = {
+static cli_function_ptr cli_functions[] = {
 	&cli_monitor,
-	&cli_getpid
-	// &cli_setpid,
-	// &cli_getimu
+	&cli_getpid,
+	&cli_setpid
+	//&cli_getimu
 };
 
 static char* commandNames[MAX_COMMANDS] = {
 	"monitor",
-	"getPid",
-	"setPid",
+	"getpid",
+	"setpid",
 	"getImu"
 };
 
diff --git a/groundStation/src/cli/cli_getpid.c b/groundStation/src/cli/cli_getpid.c
index bcf135870f4653ea0fecaf4a2c51b71772f93694..bb887ca24242fb05f4a22710becf248cdb6f8f62 100644
--- a/groundStation/src/cli/cli_getpid.c
+++ b/groundStation/src/cli/cli_getpid.c
@@ -7,12 +7,20 @@
 int cli_getpid(struct backend_conn * conn,	int argc, char **argv) {
 	int c;
 	static int getRoll = 0, getPitch = 0, getYaw = 0, getAll = 0;
+	static int getRollV = 0, getPitchV = 0, getYawV = 0;
+	static int getHeight = 0, getLat = 0, getLong = 0;
 	struct frontend_pid_data pid_data;
 	static struct option long_options[] = {
  		/* These options don’t set a flag. We distinguish them by their indices. */
  		{"roll",	no_argument,	&getRoll,	1},
  		{"pitch",   no_argument,   	&getPitch, 	1},
  		{"yaw",   no_argument,   	&getYaw, 	1},
+ 		{"rollv",   no_argument,   	&getYawV, 	1},
+ 		{"pitchv",   no_argument,   	&getYawV, 	1},
+ 		{"yawv",   no_argument,   	&getYawV, 	1},
+ 		{"height",   no_argument,   	&getHeight,	1},
+ 		{"lat",   no_argument,   	&getLat, 	1},
+ 		{"long",   no_argument,   	&getLong, 	1},
  		{0, 0, 0, 0}
  	};
 
diff --git a/groundStation/src/cli/cli_monitor.c b/groundStation/src/cli/cli_monitor.c
index 7ce0d3314e65609c5d016d0922ef577917a4879e..4494e65b08320fb4831a733ff83d2bc53e803ae0 100644
--- a/groundStation/src/cli/cli_monitor.c
+++ b/groundStation/src/cli/cli_monitor.c
@@ -5,49 +5,62 @@
 #include <getopt.h>
 #include <time.h>
 #include <unistd.h>
+#include <err.h>
 
 #include "cli_monitor.h"
-
-static void timespec_diff(struct timespec *start,  struct timespec *result);
+#include "frontend_tracker.h"
 
 int cli_monitor(struct backend_conn * conn,	int argc, char **argv) {
 	int c, result;
-	int timeFlag = 0;
+	int countFlag = 0;
+
+	int count, rate = 10;
+	int forever = 0;
 
-	static struct timespec startTime;
-	static struct timespec elapsedTime;
-	static struct timespec lastChecked;
-	static int nsecs, rate = 10;
 
- 	while ((c = getopt(argc, argv, "t:r:")) != -1) {
+ 	while ((c = getopt(argc, argv, "fc:r:")) != -1) {
 		switch(c) {
-			case 't' :
-				nsecs = atoi(optarg);
-				timeFlag = 1;
+			case 'c' :
+				count = atoi(optarg);
+				countFlag = 1;
 				break;
 			case 'r' :
 				rate = atoi(optarg) + 1;
 				break;
+			case 'f' :
+				forever = 1;
+				break;
 			default :
 				break;
 		}
 	}
 
-	if(timeFlag) {
-		clock_gettime(CLOCK_REALTIME, &startTime);
-		clock_gettime(CLOCK_REALTIME, &lastChecked);
-		while((result = monitor(conn)) == 0) {
-			timespec_diff(&startTime, &elapsedTime);
-			if(elapsedTime.tv_sec > nsecs) {
-				break;
+	if (forever) {
+		for (;;) {
+			struct timespec req;
+			if (rate == 1) {
+				req.tv_sec = 1;
+				req.tv_nsec = 0;
+			} else { 
+				req.tv_sec = 0;
+				req.tv_nsec = 1000000000 / rate;
 			}
-			while(1) {
-				timespec_diff(&lastChecked, &elapsedTime);
-				if(elapsedTime.tv_nsec >= (long) ((SECOND_IN_NANO * 2) / rate)) {
-					clock_gettime(CLOCK_REALTIME, &lastChecked);
-					break;
-				}
+			nanosleep(&req, NULL);
+			monitor(conn);
+		}
+	} else if (countFlag) {
+		for (int i = 0; i < count; i++) {
+			result = monitor(conn);
+
+			struct timespec req;
+			if (rate == 1) {
+				req.tv_sec = 1;
+				req.tv_nsec = 0;
+			} else { 
+				req.tv_sec = 0;
+				req.tv_nsec = 1000000000 / rate;
 			}
+			nanosleep(&req, NULL);
 		}
 	} else {
 		return monitor(conn);
@@ -57,29 +70,33 @@ int cli_monitor(struct backend_conn * conn,	int argc, char **argv) {
 }
 
 int monitor(struct backend_conn * conn) {
-	static char * line = "monitor\n";
-	printf("monitoring\n");
-	int size;
-	if((size = ucart_backendWrite(conn, line)) < 0 ) {
-		return 1;
+	/* Get tracker data */
+	struct frontend_tracker_data td;
+	if (frontend_track(conn, &td)) {
+		errx(1, "Error reading tracker data");
 	}
 
-	//TODO : HANDLE RETURN DATA
+	/* TODO: Get PID constants and status */
+	/* It might be a good idea to only read the pid constants
+	 * every few seconds, so count iterations and only do it if 
+	 * this is every (rate * 2 or 3) pass through the loop
+	 */
+
+	/* Print stuff on screen */
+	/* Assuming a tab width of 8 columns */
+	printf("\033[2J");
+	printf("STATUS: NA\n");
+	printf("CTRLR :\tP\tR\tY\tP_V\tR_V\tY_V\tH\tLAT\tLON\n");
+	printf("  P   :\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\n",
+			0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+	printf("  I   :\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\n",
+			0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+	printf("  D   :\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\n",
+			0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+	printf("PosAtt:\tH\tLAT\tLON\tP\tR\tY\n");
+	printf("      :\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\t%6.3lf\n",
+			td.height, td.lateral, td.longitudinal,
+			td.pitch, td.roll, td.yaw);
 
 	return 0;
 }
-
-static void timespec_diff(struct timespec *start, struct timespec *result)
-{
-	struct timespec stop;
-	clock_gettime(CLOCK_REALTIME, &stop);
-    if ((stop.tv_nsec - start->tv_nsec) < 0) {
-        result->tv_sec = stop.tv_sec - start->tv_sec - 1;
-        result->tv_nsec = stop.tv_nsec - start->tv_nsec + 1000000000;
-    } else {
-        result->tv_sec = stop.tv_sec - start->tv_sec;
-        result->tv_nsec = stop.tv_nsec - start->tv_nsec;
-    }
-
-    return;
-}
\ No newline at end of file
diff --git a/groundStation/src/cli/cli_setpid.h b/groundStation/src/cli/cli_setpid.h
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..87fb0a4f40e91ed704972bd17e4859991d91641b 100644
--- a/groundStation/src/cli/cli_setpid.h
+++ b/groundStation/src/cli/cli_setpid.h
@@ -0,0 +1,8 @@
+#ifndef _CLI_SETPID_H
+#define _CLI_SETPID_H
+
+#include "frontend_setpid.h"
+
+int cli_setpid(struct backend_conn * conn, int argc, char ** argv);
+
+#endif
diff --git a/groundStation/src/frontend/frontend_setpid.c b/groundStation/src/frontend/frontend_setpid.c
new file mode 100644
index 0000000000000000000000000000000000000000..0a25d8e3c068ebcd8d121dac7469f86cc6d8a8c6
--- /dev/null
+++ b/groundStation/src/frontend/frontend_setpid.c
@@ -0,0 +1,65 @@
+#include <err.h>
+#include <stdio.h>
+
+#include "frontend_setpid.h"
+#include "pid_common.h"
+#include "frontend_common.h"
+
+int frontend_setpid(
+		struct backend_conn * conn,
+		struct frontend_pid_data * pid_data,
+		int mask)
+{
+	if (conn == NULL) {
+		return -1;
+	}
+
+	char * controller;
+	switch (pid_data->controller) {
+		case PID_PITCH:
+			controller = "pitch";
+			break;
+		case PID_ROLL:
+			controller = "roll";
+			break;
+		case PID_YAW:
+			controller = "yaw";
+			break;
+			/* What is the "throttle" pid constant? */
+		default:
+			warnx("Unsupported PID constant");
+			return -1;
+	}
+
+	char buffer[2048];
+	/* Set the P, I, and D */
+	if (mask & SET_P) {
+		if (snprintf(buffer, 2048,
+					"set%sp %f\n", 
+					controller, 
+					pid_data->p) >= 2048) {
+			errx(0, "Buffer to small to format!");
+		}
+		ucart_backendWrite(conn, buffer);
+	}
+	if (mask & SET_I) {
+		if (snprintf(buffer, 2048,
+					"set%si %f\n", 
+					controller, 
+					pid_data->i) >= 2048) {
+			errx(0, "Buffer to small to format!");
+		}
+		ucart_backendWrite(conn, buffer);
+	}
+	if (mask & SET_D) {
+		if (snprintf(buffer, 2048,
+					"set%sd %f\n", 
+					controller, 
+					pid_data->d) >= 2048) {
+			errx(0, "Buffer to small to format!");
+		}
+		ucart_backendWrite(conn, buffer);
+	}
+
+	return 0;
+}
diff --git a/groundStation/src/frontend/frontend_setpid.h b/groundStation/src/frontend/frontend_setpid.h
new file mode 100644
index 0000000000000000000000000000000000000000..f1deb5d3d91568939d5bd44ffab07f082a290233
--- /dev/null
+++ b/groundStation/src/frontend/frontend_setpid.h
@@ -0,0 +1,17 @@
+#ifndef _FRONTEND_SETPID_H
+#define _FRONTEND_SETPID_H
+
+#include "pid_common.h"
+#include "frontend_common.h"
+
+int frontend_setpid(
+		struct backend_conn * conn,
+		struct frontend_pid_data * pid_data,
+		int mask);
+
+#define SET_P 0x01
+#define SET_I 0x02
+#define SET_D 0x04
+#define SET_ALL (SET_P | SET_I | SET_D)
+
+#endif
diff --git a/groundStation/src/frontend/frontend_tracker.c b/groundStation/src/frontend/frontend_tracker.c
index 31ae0636350f9f86b67dac9f94a042a133c4fc48..94597b63c66d96c4d5197dd94edf138b38a956a2 100644
--- a/groundStation/src/frontend/frontend_tracker.c
+++ b/groundStation/src/frontend/frontend_tracker.c
@@ -1,4 +1,42 @@
+#include <err.h>
+#include <string.h>
+#include <stdio.h>
+
 #include "frontend_tracker.h"
 
-int frontend_track(struct backend_conn * conn,
-		struct frontend_tracker_data * data);
+#define MAGIC "TRACKERDATA"
+
+int frontend_track(
+		struct backend_conn * conn,
+		struct frontend_tracker_data * data)
+{
+	ucart_backendWrite(conn, MAGIC "\n");
+
+	char * line;
+	for (;;) {
+		line = ucart_backendGetline(conn);
+		if (line == NULL) {
+			warnx("Line not returned from backend");
+			return 1;
+		}
+
+		if (strncmp(line, MAGIC, strlen(MAGIC)) == 0) {
+			break;
+		}
+	}
+
+	if (strncmp(line, MAGIC " ERROR", strlen(MAGIC " ERROR")) == 0) {
+		warnx("Backend returned an error: %s", strstr(line, "ERROR"));
+		return 1;
+	}
+
+	/* Line format: Height Lat Long Pitch Roll Yaw */
+	sscanf(line, MAGIC " %lf %lf %lf %lf %lf %lf ",
+			&data->height,
+			&data->lateral,
+			&data->longitudinal,
+			&data->pitch,
+			&data->roll,
+			&data->yaw);
+	return 0;
+}