diff --git a/quad/scripts/tests/test_safety_checks.rb b/quad/scripts/tests/test_safety_checks.rb
index 922d6439f77b4c245ce1742dbd786f2fcbd81a06..9e7d693e6ee8459bedf24cc503a6265dcd8e6db0 100644
--- a/quad/scripts/tests/test_safety_checks.rb
+++ b/quad/scripts/tests/test_safety_checks.rb
@@ -34,34 +34,36 @@ Timeout::timeout(30) {
 
     puts("Beginning tests...")
 
-    # Set gravity
+    # Set gravity and gear
     File.write(I2C_MPU_ACCEL_Z, -1 * GRAVITY)
+    File.write(GEAR, GEAR_OFF)
 
     puts("Check that motors are off at startup")
-    check_motors_are_off
+    check_motors_are_off "Motors weren't off at startup! How dangerous!"
 
     puts("Check that LED is off at startup")
-    check_led(0)
+    check_led(0, "LED was on at startup! It should be off so that we can verify when the quad is ready.")
 
     puts("Check that increasing the throttle does nothing to motors")
     # (because gear is still off)
-    for i in (THROTTLE_MIN..THROTTLE_MAX).step(1000)
+    for i in (THROTTLE_MIN..THROTTLE_MAX).step(0.01)
       File.write(THROTTLE, i)
-      check_motors_are_off
+      check_motors_are_off "Was able to turn on motors with GEAR off! Yikes!"
+      check_led(0, "LED turned on while GEAR was off!")
       sleep 0.005
     end
 
     puts("Check that flipping gear to 1 while throttle is high does nothing")
     # (motors should still be off, LED should still be off)
     File.write(GEAR, GEAR_ON)
-    sleep 0.015
-    check_motors_are_off
+    sleep 0.5
+    check_motors_are_off "Motors turned on by gear while rc throttle was high! How dangerous!"
     i = THROTTLE_MAX
     while i > THROTTLE_MID
-      i -= 1000
+      i -= 0.01
       File.write(THROTTLE, i)
-      check_motors_are_off
-      check_led 0
+      check_motors_are_off "Motors turned on while GEAR was off. Yikes!"
+      check_led(0, "LED turned on while GEAR was off!")
       sleep 0.005
     end
 
@@ -73,8 +75,8 @@ Timeout::timeout(30) {
     # (motors should still be off because our throttle is low)
     File.write(GEAR, GEAR_ON)
     sleep 0.5
-    check_motors_are_off
-    check_led 1
+    check_motors_are_off "Motors turned on while throttle was low! Yikes!"
+    check_led(1, "LED didn't turn on when GEAR was switched on!")
 
     puts("Check that motors turn on")
     File.write(THROTTLE, THROTTLE_MID)
@@ -87,7 +89,7 @@ Timeout::timeout(30) {
     # (and that light goes off)
     File.write(GEAR, GEAR_OFF)
     sleep 0.5
-    check_motors_are_off
+    check_motors_are_off "Motors didn't turn off when GEAR was switched off! How dangerous!"
     #check_led 0
 
     # (Bring the RC throttle back down)
diff --git a/quad/scripts/tests/testing_library.rb b/quad/scripts/tests/testing_library.rb
index 4deefed674f2cf205b4ad9b0bc6649a5dd882557..5324eacdd4dd8f9ad1d73aa79263a37f3b1a30e8 100644
--- a/quad/scripts/tests/testing_library.rb
+++ b/quad/scripts/tests/testing_library.rb
@@ -1,23 +1,23 @@
-THROTTLE_MIN = 110200
-THROTTLE_MAX = 191900
+THROTTLE_MIN = 0.10200
+THROTTLE_MAX = 0.91900
 THROTTLE_MID = (THROTTLE_MAX + THROTTLE_MIN)/2
 THROTTLE_3_4 = (THROTTLE_MAX + THROTTLE_MID)/2
 THROTTLE_QUAR = (THROTTLE_MID + THROTTLE_MIN)/2
 THROTTLE_EIGHTH = (THROTTLE_QUAR + THROTTLE_MIN)/2
 THROTTLE_16 = (THROTTLE_EIGHTH + THROTTLE_MIN)/2
-MOTOR_MIN = 100000
-MOTOR_MAX = 200000
-GEAR_ON = 170800
-GEAR_OFF = 118300
+MOTOR_MIN = 0.0
+MOTOR_MAX = 1.0
+GEAR_ON = 0.70800
+GEAR_OFF = 0.18300
 GRAVITY = 4096
 
-MOTOR1 = "virt-quad-fifos/pwm-output-motor1"
-MOTOR2 = "virt-quad-fifos/pwm-output-motor2"
-MOTOR3 = "virt-quad-fifos/pwm-output-motor3"
-MOTOR4 = "virt-quad-fifos/pwm-output-motor4"
+MOTOR1 = "virt-quad-fifos/motor1"
+MOTOR2 = "virt-quad-fifos/motor2"
+MOTOR3 = "virt-quad-fifos/motor3"
+MOTOR4 = "virt-quad-fifos/motor4"
 
-GEAR = "virt-quad-fifos/pwm-input-gear"
-THROTTLE = "virt-quad-fifos/pwm-input-throttle"
+GEAR = "virt-quad-fifos/rc-gear"
+THROTTLE = "virt-quad-fifos/rc-throttle"
 
 LED = "virt-quad-fifos/mio7-led"
 
@@ -43,15 +43,15 @@ def read_fifo_num(f)
 end
 
 # Utility functions
-def check_motors_are_off
+def check_motors_are_off(msg)
   motor1 = read_fifo_num(MOTOR1)
   motor2 = read_fifo_num(MOTOR2)
   motor3 = read_fifo_num(MOTOR3)
   motor4 = read_fifo_num(MOTOR4)
-  assert_operator motor1, :<=, THROTTLE_MIN
-  assert_operator motor2, :<=, THROTTLE_MIN
-  assert_operator motor3, :<=, THROTTLE_MIN
-  assert_operator motor4, :<=, THROTTLE_MIN
+  assert_operator(motor1, :<=, THROTTLE_MIN, msg)
+  assert_operator(motor2, :<=, THROTTLE_MIN, msg)
+  assert_operator(motor3, :<=, THROTTLE_MIN, msg)
+  assert_operator(motor4, :<=, THROTTLE_MIN, msg)
 end
 
 def get_motor_averages
@@ -71,9 +71,9 @@ def get_motor_averages
   average
 end
 
-def check_led(is_on)
+def check_led(is_on, msg)
   led = read_fifo_num(LED)
-  assert_equal(is_on, led)
+  assert_equal(is_on, led, msg)
 end
 
 def delay_spin_cursor(delay)
diff --git a/quad/src/graph_blocks/node_mixer.c b/quad/src/graph_blocks/node_mixer.c
index 40972ad15521e1ce2d2755eac66afeaf18a0ae35..046f133eefde61de324f61d805f5dbc97616c664 100644
--- a/quad/src/graph_blocks/node_mixer.c
+++ b/quad/src/graph_blocks/node_mixer.c
@@ -1,30 +1,30 @@
 #include "node_mixer.h"
 #include <stdlib.h>
 
-static int pwm_min = 100000;
-static int pwm_max = 200000;
+static int motor_min = 0.00000;
+static int motor_max = 1.00000;
 
-static int pwm_clamp(int val) {
-	if (val < pwm_min) {val = pwm_min;}
-	if (val > pwm_max) {val = pwm_max;}
+static double motor_clamp(double val) {
+	if (val < motor_min) {val = motor_min;}
+	if (val > motor_max) {val = motor_max;}
 	return val;
 }
 
 static void mixer_computation(void *state, const double* params, const double *inputs, double *outputs) {
-	int pwm0 = inputs[MIXER_THROTTLE] - inputs[MIXER_PITCH] - inputs[MIXER_ROLL] - inputs[MIXER_YAW];
-	int pwm1 = inputs[MIXER_THROTTLE] + inputs[MIXER_PITCH] - inputs[MIXER_ROLL] + inputs[MIXER_YAW];
-	int pwm2 = inputs[MIXER_THROTTLE] - inputs[MIXER_PITCH] + inputs[MIXER_ROLL] + inputs[MIXER_YAW];
-	int pwm3 = inputs[MIXER_THROTTLE] + inputs[MIXER_PITCH] + inputs[MIXER_ROLL] - inputs[MIXER_YAW];
-	outputs[MIXER_PWM0] = pwm_clamp(pwm0);
-	outputs[MIXER_PWM1] = pwm_clamp(pwm1);
-	outputs[MIXER_PWM2] = pwm_clamp(pwm2);
-	outputs[MIXER_PWM3] = pwm_clamp(pwm3);
+	double motor0 = inputs[MIXER_THROTTLE] - inputs[MIXER_PITCH] - inputs[MIXER_ROLL] - inputs[MIXER_YAW];
+	double motor1 = inputs[MIXER_THROTTLE] + inputs[MIXER_PITCH] - inputs[MIXER_ROLL] + inputs[MIXER_YAW];
+	double motor2 = inputs[MIXER_THROTTLE] - inputs[MIXER_PITCH] + inputs[MIXER_ROLL] + inputs[MIXER_YAW];
+	double motor3 = inputs[MIXER_THROTTLE] + inputs[MIXER_PITCH] + inputs[MIXER_ROLL] - inputs[MIXER_YAW];
+	outputs[MIXER_MOTOR0] = motor_clamp(motor0);
+	outputs[MIXER_MOTOR1] = motor_clamp(motor1);
+	outputs[MIXER_MOTOR2] = motor_clamp(motor2);
+	outputs[MIXER_MOTOR3] = motor_clamp(motor3);
 }
 
 static void reset_mixer(void *state) {}
 
 static const char* const in_names[4] = {"Throttle", "Pitch", "Roll", "Yaw"};
-static const char* const out_names[4] = {"PWM 0", "PWM 1", "PWM 2", "PWM 3"};
+static const char* const out_names[4] = {"MOTOR 0", "MOTOR 1", "MOTOR 2", "MOTOR 3"};
 static const char* const param_names[1] = {"You shouldnt see this"};
 const struct graph_node_type node_mixer_type = {
         .input_names = in_names,
diff --git a/quad/src/graph_blocks/node_mixer.h b/quad/src/graph_blocks/node_mixer.h
index 374a88be39e409806c6c7a43d95cb5e5b35e7849..c2805fe8dc078c225b41dce8ef3be771be506e09 100644
--- a/quad/src/graph_blocks/node_mixer.h
+++ b/quad/src/graph_blocks/node_mixer.h
@@ -13,10 +13,10 @@ enum graph_node_mixer_inputs {
 };
 
 enum graph_node_mixer_outputs {
-    MIXER_PWM0,
-    MIXER_PWM1,
-    MIXER_PWM2,
-    MIXER_PWM3,
+    MIXER_MOTOR0,
+    MIXER_MOTOR1,
+    MIXER_MOTOR2,
+    MIXER_MOTOR3,
 };
 
 #endif // __NODE_MIXER_H__
diff --git a/quad/src/quad_app/PID.h b/quad/src/quad_app/PID.h
index faf5579f090e7bfe424725ce65a762e7fa9a8e9b..9188e097192f6cf6a515482d8a235fdbae593ebb 100644
--- a/quad/src/quad_app/PID.h
+++ b/quad/src/quad_app/PID.h
@@ -15,7 +15,7 @@
 
 // Yaw constants
 // when using units of radians
-#define YAW_ANGULAR_VELOCITY_KP 29700//200.0f * 2292.0f
+#define YAW_ANGULAR_VELOCITY_KP 0.297
 #define YAW_ANGULAR_VELOCITY_KI 0.0f
 #define YAW_ANGULAR_VELOCITY_KD 0.0f
 #define YAW_ANGLE_KP 2.6f
@@ -25,9 +25,9 @@
 
 
 // when using units of radians
-#define ROLL_ANGULAR_VELOCITY_KP 3000
+#define ROLL_ANGULAR_VELOCITY_KP 0.03
 #define ROLL_ANGULAR_VELOCITY_KI 0.0f
-#define ROLL_ANGULAR_VELOCITY_KD 500
+#define ROLL_ANGULAR_VELOCITY_KD 0.005
 #define ROLL_ANGULAR_VELOCITY_ALPHA 0.88
 #define ROLL_ANGLE_KP 35
 #define ROLL_ANGLE_KI 0.0f
@@ -44,9 +44,9 @@
 
 //Pitch constants
 // when using units of radians
-#define PITCH_ANGULAR_VELOCITY_KP 3000
+#define PITCH_ANGULAR_VELOCITY_KP 0.03
 #define PITCH_ANGULAR_VELOCITY_KI 0.0f
-#define PITCH_ANGULAR_VELOCITY_KD 500
+#define PITCH_ANGULAR_VELOCITY_KD 0.005
 #define PITCH_ANGULAR_VELOCITY_ALPHA 0.88
 #define PITCH_ANGLE_KP 35
 #define PITCH_ANGLE_KI 0.0f
@@ -62,9 +62,9 @@
 
 
 //Throttle constants
-#define ALT_ZPOS_KP -9804.0f
-#define ALT_ZPOS_KI -817.0f
-#define ALT_ZPOS_KD -7353.0f
+#define ALT_ZPOS_KP -0.09804f
+#define ALT_ZPOS_KI -0.00817f
+#define ALT_ZPOS_KD -0.07353f
 #define ALT_ZPOS_ALPHA 0.88
 
 #endif /* PID_H_ */
diff --git a/quad/src/quad_app/actuator_command_processing.c b/quad/src/quad_app/actuator_command_processing.c
deleted file mode 100644
index e27dbf434d1aba16341a67fc3115f3ea2d88725f..0000000000000000000000000000000000000000
--- a/quad/src/quad_app/actuator_command_processing.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * actuator_command_processing.c
- *
- *  Created on: Feb 20, 2016
- *      Author: ucart
- */
- 
-#include "actuator_command_processing.h"
-#include "sensor_processing.h"
-#include "controllers.h"
-
-int actuator_command_processing(log_t* log_struct, user_input_t * user_input_struct, raw_actuator_t* raw_actuator_struct, actuator_command_t* actuator_command_struct)
-{
-
-	Aero_to_PWMS(actuator_command_struct->pwms, raw_actuator_struct->controller_corrected_motor_commands);
-//	old_Aero_to_PWMS(actuator_command_struct->pwms, raw_actuator_struct->controller_corrected_motor_commands);
-
-    return 0;
-}
-
-/**
- * Converts Aero 4 channel signals to PWM signals
- * Aero channels are defined above
- */
-void Aero_to_PWMS(int* PWMs, int* aero)
-{
-	int motor0_bias = 0, motor1_bias = 0, motor2_bias = 0, motor3_bias = 0;
-	int pwm0 = 0, pwm1 = 0, pwm2 = 0, pwm3 = 0;
-
-	pwm0 = aero[THROTTLE] - aero[PITCH] - aero[ROLL] - aero[YAW] + motor0_bias;
-	pwm1 = aero[THROTTLE] + aero[PITCH] - aero[ROLL] + aero[YAW] + motor1_bias;
-	pwm2 = aero[THROTTLE] - aero[PITCH] + aero[ROLL] + aero[YAW] + motor2_bias;
-	pwm3 = aero[THROTTLE] + aero[PITCH] + aero[ROLL] - aero[YAW] + motor3_bias;
-
-//	printf("pwm0: %d\tpwm1: %d\tpwm2: %d\tpwm3: %d\n", pwm0, pwm1, pwm2, pwm3);
-
-	/**
-	 * Boundary checks:
-	 *
-	 *  #define min 100000
-	 *	#define max 200000
-	 */
-
-	if(pwm0 < min)
-		pwm0 = min;
-	else if(pwm0 > max)
-		pwm0 = max;
-
-	if(pwm1 < min)
-		pwm1 = min;
-	else if(pwm1 > max)
-		pwm1 = max;
-
-	if(pwm2 < min)
-		pwm2 = min;
-	else if(pwm2 > max)
-		pwm2 = max;
-
-	if(pwm3 < min)
-		pwm3 = min;
-	else if(pwm3 > max)
-		pwm3 = max;
-
-	PWMs[0] = pwm0;
-	PWMs[1] = pwm1;
-	PWMs[2] = pwm2;
-	PWMs[3] = pwm3;
-
-	// the array PWMs is then written directly to the PWM hardware registers
-	// the PWMs are in units of clock cycles, not percentage duty cycle
-	// use pwm/222,222 to get the duty cycle. the freq is 450 Hz on a 100MHz clock
-}
-
-/**
- * Converts Aero 4 channel signals to PWM signals
- * Aero channels are defined above
- *
- * *deprecated
- */
-void old_Aero_to_PWMS(int* PWMs, int* aero) {
-
-	int motor0_bias = -9900, motor1_bias = -200, motor2_bias = -10200, motor3_bias = 250;
-//	int motor0_bias = -5000, motor1_bias = 0, motor2_bias = -5000, motor3_bias = 0;
-
-	// Throttle, pitch, roll, yaw as a percentage of their max - Range 0.0 - 100.0
-	float throttle_100 = (aero[THROTTLE] - THROTTLE_MIN) / (THROTTLE_RANGE*1.0);
-	float pitch_100    = (aero[PITCH]    - PITCH_MIN)    / (PITCH_RANGE*1.0);
-	float roll_100     = (aero[ROLL]     - ROLL_MIN)     / (ROLL_RANGE*1.0);
-	float yaw_100      = (aero[YAW]      - YAW_MIN)      / (YAW_RANGE*1.0);
-
-	// This adds a +/- 300 ms range bias for the throttle
-	int throttle_base = BASE + (int) 60000 * (throttle_100 - .5);
-	// This adds a +/- 200 ms range bias for the pitch
-	int pitch_base    =        (int) 60000 * (pitch_100    - .5);
-	// This adds a +/- 200 ms range bias for the roll
-	int roll_base     =        (int) 60000 * (roll_100     - .5);
-	// This adds a +/- 75 ms range bias for the yaw
-	int yaw_base      =        (int) 15000 * (yaw_100      - .5);
-
-	int pwm0, pwm1, pwm2, pwm3;
-
-	pwm1 = throttle_base + pitch_base/2 - roll_base/2 + yaw_base + motor1_bias;
-	pwm3 = throttle_base + pitch_base/2 + roll_base/2 - yaw_base + motor3_bias;
-	pwm0 = throttle_base - pitch_base/2 - roll_base/2 - yaw_base + motor0_bias;
-	pwm2 = throttle_base - pitch_base/2 + roll_base/2 + yaw_base + motor2_bias;
-
-	/**
-	 * Boundary checks:
-	 *
-	 *  #define min 100000
-	 *	#define max 200000
-	 */
-
-	if(pwm0 < min)
-		pwm0 = min;
-	else if(pwm0 > max)
-		pwm0 = max;
-
-	if(pwm1 < min)
-		pwm1 = min;
-	else if(pwm1 > max)
-		pwm1 = max;
-
-	if(pwm2 < min)
-		pwm2 = min;
-	else if(pwm2 > max)
-		pwm2 = max;
-
-	if(pwm3 < min)
-		pwm3 = min;
-	else if(pwm3 > max)
-		pwm3 = max;
-
-	PWMs[0] = pwm0;
-	PWMs[1] = pwm1;
-	PWMs[2] = pwm2;
-	PWMs[3] = pwm3;
-
-	// the array PWMs is then written directly to the PWM hardware registers
-	// the PWMs are in units of clock cycles, not percentage duty cycle
-	// use pwm/222,222 to get the duty cycle. the freq is 450 Hz on a 100MHz clock
-
-}
diff --git a/quad/src/quad_app/actuator_command_processing.h b/quad/src/quad_app/actuator_command_processing.h
deleted file mode 100644
index 12110d5513130b90b4b60f30ffe555bcb370a07e..0000000000000000000000000000000000000000
--- a/quad/src/quad_app/actuator_command_processing.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * actuator_command_processing.h
- *
- *  Created on: Feb 20, 2016
- *      Author: ucart
- */
-
-#ifndef ACTUATOR_COMMAND_PROCESSING_H_
-#define ACTUATOR_COMMAND_PROCESSING_H_
- 
-#include <stdio.h>
-
-#include "log_data.h"
-#include "control_algorithm.h"
-
-/**
- * @brief
- *      Processes the commands to the actuators.
- *
- * @param log_struct
- *      structure of the data to be logged
- *
- * @param raw_actuator_struct
- *      structure of the commmands outputted to go to the actuators
- *
- * @param actuator_command_struct
- *      structure of the commmands to go to the actuators
- *
- * @return 
- *      error message
- *
- */
-int actuator_command_processing(log_t* log_struct, user_input_t * user_input_struct, raw_actuator_t* raw_actuator_struct, actuator_command_t* actuator_command_struct);
-
-void old_Aero_to_PWMS(int* PWMs, int* aero);
-void Aero_to_PWMS(int* PWMs, int* aero);
-
-#endif /* ACTUATOR_COMMAND_PROCESSING_H_ */
diff --git a/quad/src/quad_app/control_algorithm.c b/quad/src/quad_app/control_algorithm.c
index 7d867cbfc2d498e769cccd1463f1d441710cc3e7..845c584334bdd8b83083ed1215398fb2ca7e0237 100644
--- a/quad/src/quad_app/control_algorithm.c
+++ b/quad/src/quad_app/control_algorithm.c
@@ -376,22 +376,22 @@ int control_algorithm_init(parameter_t * ps)
 
 	// don't use the PID corrections if the throttle is less than about 10% of its range
     // unless we are in autonomous
-	if((user_input_struct->rc_commands[THROTTLE] > 118000) ||
+	if((user_input_struct->rc_commands[THROTTLE] > 0.18000) ||
         user_defined_struct->flight_mode == AUTO_FLIGHT_MODE)
 	{
 			//THROTTLE
 
-			actuator_struct->pwms[0] = graph_get_output(graph, ps->mixer, MIXER_PWM0);
-			actuator_struct->pwms[1] = graph_get_output(graph, ps->mixer, MIXER_PWM1);
-			actuator_struct->pwms[2] = graph_get_output(graph, ps->mixer, MIXER_PWM2);
-			actuator_struct->pwms[3] = graph_get_output(graph, ps->mixer, MIXER_PWM3);
+			actuator_struct->motor_magnitudes[0] = graph_get_output(graph, ps->mixer, MIXER_MOTOR0);
+			actuator_struct->motor_magnitudes[1] = graph_get_output(graph, ps->mixer, MIXER_MOTOR1);
+			actuator_struct->motor_magnitudes[2] = graph_get_output(graph, ps->mixer, MIXER_MOTOR2);
+			actuator_struct->motor_magnitudes[3] = graph_get_output(graph, ps->mixer, MIXER_MOTOR3);
 	}
 	else
 	{
-		actuator_struct->pwms[0] = user_input_struct->rc_commands[THROTTLE];
-		actuator_struct->pwms[1] = user_input_struct->rc_commands[THROTTLE];
-		actuator_struct->pwms[2] = user_input_struct->rc_commands[THROTTLE];
-		actuator_struct->pwms[3] = user_input_struct->rc_commands[THROTTLE];
+		actuator_struct->motor_magnitudes[0] = user_input_struct->rc_commands[THROTTLE];
+		actuator_struct->motor_magnitudes[1] = user_input_struct->rc_commands[THROTTLE];
+		actuator_struct->motor_magnitudes[2] = user_input_struct->rc_commands[THROTTLE];
+		actuator_struct->motor_magnitudes[3] = user_input_struct->rc_commands[THROTTLE];
 	}
 
 	last_fm_switch = cur_fm_switch;
diff --git a/quad/src/quad_app/controllers.h b/quad/src/quad_app/controllers.h
index 1e12c7590e5fe661b81a1bca31b7398da3e457d3..40c7832601fd0509a002cb2f5c3c29fa80c304ff 100644
--- a/quad/src/quad_app/controllers.h
+++ b/quad/src/quad_app/controllers.h
@@ -71,39 +71,41 @@
 /**
  * Signals from the Rx mins, maxes and ranges
  */
-#define THROTTLE_MAX  191900
-#define THROTTLE_MIN  110200
+#define THROTTLE_MAX  0.91900
+#define THROTTLE_MIN  0.10200
 #define THROTTLE_RANGE THROTTLE_MAX - THROTTLE_MIN
 
-#define ROLL_MAX      170200
-#define ROLL_MIN      129400
-#define ROLL_CENTER   149800
+#define ROLL_MAX      0.70200
+#define ROLL_MIN      0.29400
+#define ROLL_CENTER   0.49800
 #define ROLL_RANGE    ROLL_MAX - ROLL_MIN
 
-#define PITCH_MAX     169900
-#define PITCH_MIN     129500
-#define PITCH_CENTER  149700
+#define PITCH_MAX     0.69900
+#define PITCH_MIN     0.29500
+#define PITCH_CENTER  0.49700
 #define PITCH_RANGE   PITCH_MAX - PITCH_MIN
 
-#define YAW_MAX       169400
-#define YAW_MIN       129300
-#define YAW_CENTER   149800
+#define YAW_MAX       0.69400
+#define YAW_MIN       0.29300
+#define YAW_CENTER    0.49800
 #define YAW_RANGE     YAW_MAX - YAW_MIN
 
-#define GEAR_1	170800
-#define GEAR_0	118300
+#define GEAR_1	      0.70800
+#define GEAR_0	      0.18300
+#define GEAR_MID (GEAR_0 + GEAR_1)/2.0
 
-#define FLAP_1		192000
-#define FLAP_0		107600
+#define FLAP_1	      0.92000
+#define FLAP_0        0.07600
+#define FLAP_MID (FLAP_0 + FLAP_1)/2.0
 
 #define GEAR_KILL     GEAR_0 // The kill point for the program
-#define BASE          150000
+#define BASE          0.50000
 
-#define min 100000
-#define max 200000
+#define min 0.00000
+#define max 1.00000
 
-#define MOTOR_MIN 100000
-#define MOTOR_MAX 200000
+#define MOTOR_MIN 0.00000
+#define MOTOR_MAX 1.00000
 
 void filter_PWMs(int* mixer);
 void PWMS_to_Aero(int* PWMs, int* aero); // <= javey: unused
diff --git a/quad/src/quad_app/hw_iface.h b/quad/src/quad_app/hw_iface.h
index 48b3d0cf7f3cf26a0931c79e2b9c656dabc608ce..ca787b9fc6dde55ce2cddb69d8c77036aee41cd1 100644
--- a/quad/src/quad_app/hw_iface.h
+++ b/quad/src/quad_app/hw_iface.h
@@ -28,16 +28,16 @@ struct I2CDriver {
               unsigned int length);
 };
 
-struct PWMOutputDriver {
+struct RCReceiverDriver {
   void *state;
-  int (*reset)(struct PWMOutputDriver *self);
-  int (*write)(struct PWMOutputDriver *self, unsigned int channel, unsigned long pulse_width_us);
+  int (*reset)(struct RCReceiverDriver *self);
+  int (*read)(struct RCReceiverDriver *self, unsigned int channel, float *magnitude);
 };
 
-struct PWMInputDriver {
+struct MotorDriver {
   void *state;
-  int (*reset)(struct PWMInputDriver *self);
-  int (*read)(struct PWMInputDriver *self, unsigned int channel, unsigned long *pulse_width_us);
+  int (*reset)(struct MotorDriver *self);
+  int (*write)(struct MotorDriver *self, unsigned int channel, float magnitude);
 };
 
 struct UARTDriver {
diff --git a/quad/src/quad_app/initialize_components.c b/quad/src/quad_app/initialize_components.c
index e476fd633eb9ecce40eb77af6570eac63462833a..5cd49342dcfffdaeb24649d18ca1555219200438 100644
--- a/quad/src/quad_app/initialize_components.c
+++ b/quad/src/quad_app/initialize_components.c
@@ -17,18 +17,18 @@ extern int Xil_AssertWait;
 
 int protection_loops(modular_structs_t *structs)
 {
-	u32 rc_commands[6]; // 6 "receiver_input" elements: Throttle, Pitch, Roll, Yaw, Gear, and Flap
+	float rc_commands[6]; // 6 "receiver_input" elements: Throttle, Pitch, Roll, Yaw, Gear, and Flap
 	
-	struct PWMInputDriver *pwm_inputs = &structs->hardware_struct.pwm_inputs;
-	read_rec_all(pwm_inputs, rc_commands);
+	struct RCReceiverDriver *rc_receiver = &structs->hardware_struct.rc_receiver;
+	read_rec_all(rc_receiver, rc_commands);
 	
-	while(rc_commands[THROTTLE] < 75000 || // wait for RC receiver to connect to transmitter
-        rc_commands[THROTTLE] > 125000 || // Wait until throttle is low
+	while(rc_commands[THROTTLE] < 0.075 || // wait for RC receiver to connect to transmitter
+        rc_commands[THROTTLE] > 0.125 || // Wait until throttle is low
         read_kill(rc_commands[GEAR]) || // Wait until gear switch is engaged (so you don't immediately break out of the main loop below)
         !read_flap(rc_commands[FLAP])) // Wait for the flight mode to be set to manual
     {
 		process_received(structs);
-		read_rec_all(pwm_inputs, rc_commands);
+		read_rec_all(rc_receiver, rc_commands);
 	}
 
 	// let the pilot/observers know that the quad is now active
@@ -77,15 +77,15 @@ int init_structs(modular_structs_t *structs) {
   iic_set_globals(i2c, sys);
 
   // Initialize PWM Recorders and Motor outputs
-  struct PWMInputDriver *pwm_inputs = &structs->hardware_struct.pwm_inputs;
-  if (pwm_inputs->reset(pwm_inputs)) return -1;
-  struct PWMOutputDriver *pwm_outputs = &structs->hardware_struct.pwm_outputs;
-  if (pwm_outputs->reset(pwm_outputs)) return -1;
+  struct RCReceiverDriver *rc_receiver = &structs->hardware_struct.rc_receiver;
+  if (rc_receiver->reset(rc_receiver)) return -1;
+  struct MotorDriver *motors = &structs->hardware_struct.motors;
+  if (motors->reset(motors)) return -1;
 
   // Set motor outputs to off
   int i;
   for (i = 0; i < 4; i += 1) {
-    pwm_outputs->write(pwm_outputs, i, MOTOR_MIN);
+    motors->write(motors, i, MOTOR_MIN);
   }
 
   // Initialize sensors
diff --git a/quad/src/quad_app/log_data.c b/quad/src/quad_app/log_data.c
index 5714d32a2e3c41e2ca1dbd7db5bf2217a190132a..bdc38f0eeb05714f73d334ea492ee8c6311abf21 100644
--- a/quad/src/quad_app/log_data.c
+++ b/quad/src/quad_app/log_data.c
@@ -117,10 +117,10 @@ void initialize_logging(log_t* log_struct, parameter_t* ps) {
 	addOutputToLog(log_struct, ps->x_set, CONST_VAL, m);
 	addOutputToLog(log_struct, ps->y_set, CONST_VAL, m);
 	addOutputToLog(log_struct, ps->alt_set, CONST_VAL, m);
-	addOutputToLog(log_struct, ps->mixer, MIXER_PWM0, pwm_val);
-	addOutputToLog(log_struct, ps->mixer, MIXER_PWM1, pwm_val);
-	addOutputToLog(log_struct, ps->mixer, MIXER_PWM2, pwm_val);
-	addOutputToLog(log_struct, ps->mixer, MIXER_PWM3, pwm_val);
+	addOutputToLog(log_struct, ps->mixer, MIXER_MOTOR0, pwm_val);
+	addOutputToLog(log_struct, ps->mixer, MIXER_MOTOR1, pwm_val);
+	addOutputToLog(log_struct, ps->mixer, MIXER_MOTOR2, pwm_val);
+	addOutputToLog(log_struct, ps->mixer, MIXER_MOTOR3, pwm_val);
 	addOutputToLog(log_struct, ps->rc_throttle, PID_CORRECTION, pwm_val);
 	addOutputToLog(log_struct, ps->rc_pitch, PID_CORRECTION, pwm_val);
 	addOutputToLog(log_struct, ps->rc_roll, PID_CORRECTION, pwm_val);
diff --git a/quad/src/quad_app/quad_app.c b/quad/src/quad_app/quad_app.c
index 01eabe9017f733685ae8f9737398099e657a0bf0..f83cc8698f58c41a42ae255808f1c749b442bdbb 100644
--- a/quad/src/quad_app/quad_app.c
+++ b/quad/src/quad_app/quad_app.c
@@ -12,7 +12,6 @@
 #include "sensor.h"
 #include "sensor_processing.h"
 #include "control_algorithm.h"
-#include "actuator_command_processing.h"
 #include "send_actuator_commands.h"
 #include "update_gui.h"
 #include "communication.h"
@@ -67,10 +66,10 @@ int quad_main(int (*setup_hardware)(hardware_t *hardware_struct))
 					&(structs.parameter_struct), &(structs.user_defined_struct), &(structs.actuator_command_struct), &structs);
 
 			// send the actuator commands
-			send_actuator_commands(&(structs.hardware_struct.pwm_outputs), &(structs.log_struct), &(structs.actuator_command_struct));
+			send_actuator_commands(&(structs.hardware_struct.motors), &(structs.log_struct), &(structs.actuator_command_struct));
 		}
 		else {
-			kill_motors(&(structs.hardware_struct.pwm_outputs));
+			kill_motors(&(structs.hardware_struct.motors));
 		}
 		// update the GUI
 		update_GUI(&(structs.log_struct));
@@ -115,7 +114,7 @@ int quad_main(int (*setup_hardware)(hardware_t *hardware_struct))
 		timer_end_loop(&(structs.log_struct));
 	}
 
-	kill_motors(&(structs.hardware_struct.pwm_outputs));
+	kill_motors(&(structs.hardware_struct.motors));
 
 	flash_MIO_7_led(10, 100);
 
diff --git a/quad/src/quad_app/send_actuator_commands.c b/quad/src/quad_app/send_actuator_commands.c
index c361e74db2146e44b80881fec18dde14efef44d3..8120224d0dd07f72cf0382ab5f11a86a352851c6 100644
--- a/quad/src/quad_app/send_actuator_commands.c
+++ b/quad/src/quad_app/send_actuator_commands.c
@@ -8,12 +8,12 @@
 #include "send_actuator_commands.h"
 #include "util.h"
  
-int send_actuator_commands(struct PWMOutputDriver *pwm_outputs, log_t* log_struct, actuator_command_t* actuator_command_struct) {
+int send_actuator_commands(struct MotorDriver *motors, log_t* log_struct, actuator_command_t* actuator_command_struct) {
   int i;
   // write the PWMs to the motors
 
   for (i = 0; i < 4; i++) {
-    pwm_outputs->write(pwm_outputs, i, actuator_command_struct->pwms[i]);
+    motors->write(motors, i, actuator_command_struct->motor_magnitudes[i]);
   }
 
   return 0;
diff --git a/quad/src/quad_app/send_actuator_commands.h b/quad/src/quad_app/send_actuator_commands.h
index 3f6fb0fc833e3dc87d291ca6a357eed115d17e94..747ba0479ef15d08ed18e1a8c4f8c73694f893e6 100644
--- a/quad/src/quad_app/send_actuator_commands.h
+++ b/quad/src/quad_app/send_actuator_commands.h
@@ -11,7 +11,6 @@
 #include <stdio.h>
 
 #include "log_data.h"
-#include "actuator_command_processing.h"
 
 /**
  * @brief 
@@ -27,6 +26,6 @@
  *      error message
  *
  */
-int send_actuator_commands(struct PWMOutputDriver *pwm_outputs, log_t* log_struct, actuator_command_t* actuator_command_struct);
+int send_actuator_commands(struct MotorDriver *motors, log_t* log_struct, actuator_command_t* actuator_command_struct);
 
 #endif /* SEND_ACTUATOR_COMMANDS_H_ */
diff --git a/quad/src/quad_app/sensor.c b/quad/src/quad_app/sensor.c
index 2d9396de9cf254be598bd2d2cbea42bf47528c31..b2f7592c88f667ca9ed9f897ea65dd4b22293ecc 100644
--- a/quad/src/quad_app/sensor.c
+++ b/quad/src/quad_app/sensor.c
@@ -12,9 +12,9 @@
 
 int sensor_init(raw_sensor_t * raw_sensor_struct, sensor_t * sensor_struct)
 {
-	if (iic0_lidarlite_init()) { // init LiDAR
-		return -1;
-	}
+//	if (iic0_lidarlite_init()) { // init LiDAR
+//		return -1;
+//	}
 
 	if(iic0_mpu9150_start() == -1) {
 		return -1;
@@ -74,9 +74,9 @@ int get_sensors(log_t* log_struct, user_input_t* user_input_struct, raw_sensor_t
 
 	log_struct->gam = raw_sensor_struct->gam;
 
-	static lidar_t lidar_val;
-	iic0_lidarlite_read_distance(&lidar_val);
-	raw_sensor_struct->lidar_distance_m = lidar_val.distance_m;
+//	static lidar_t lidar_val;
+//	iic0_lidarlite_read_distance(&lidar_val);
+//	raw_sensor_struct->lidar_distance_m = lidar_val.distance_m;
 
     return 0;
 }
diff --git a/quad/src/quad_app/sensor_processing.h b/quad/src/quad_app/sensor_processing.h
index 52b626eafa173ac5c806ad29d52ca03138017060..d340e34583c2a4e77fe7cad13e256c4f02eea955 100644
--- a/quad/src/quad_app/sensor_processing.h
+++ b/quad/src/quad_app/sensor_processing.h
@@ -19,45 +19,6 @@
 #define GEAR 	 4
 #define FLAP 	 5
 
-/**
- * Signals from the Rx mins, maxes and ranges
- */
-//#define THROTTLE_MAX  191900
-//#define THROTTLE_MIN  110200
-//#define THROTTLE_RANGE THROTTLE_MAX - THROTTLE_MIN
-//
-//#define ROLL_MAX      170200
-////#define ROLL_MAX      167664
-////#define ROLL_CENTER   148532
-//#define ROLL_MIN      129400
-//#define ROLL_CENTER   149800
-//#define ROLL_RANGE    ROLL_MAX - ROLL_MIN
-//
-////#define PITCH_MAX     190800
-//#define PITCH_MAX     169900
-////#define PITCH_MIN     135760
-//#define PITCH_MIN     129500
-////#define PITCH_CENTER  152830
-//#define PITCH_CENTER  149700
-//#define PITCH_RANGE   PITCH_MAX - PITCH_MIN
-//
-//#define YAW_MAX       169400
-//#define YAW_MIN       129300
-//#define YAW_CENTER   149800
-//#define YAW_RANGE     YAW_MAX - YAW_MIN
-//
-//#define GEAR_1	170800
-//#define GEAR_0	118300
-//
-//#define FLAP_1		192000
-//#define FLAP_0		107600
-//
-//#define GEAR_KILL     GEAR_0 // The kill point for the program
-//#define BASE          150000
-//
-//#define min 100000
-//#define max 200000
-
 /**
  * @brief 
  *      Processes the data from the sensors.
diff --git a/quad/src/quad_app/type_def.h b/quad/src/quad_app/type_def.h
index b7e398b6bb4cd2222f384c00b2fc05df9f6504a4..e2e40c1aac046af72fe499ef9b1f7f583bf27be5 100644
--- a/quad/src/quad_app/type_def.h
+++ b/quad/src/quad_app/type_def.h
@@ -148,7 +148,7 @@ typedef struct PID_values{
  *
  */
 typedef struct user_input_t {
-	u32 rc_commands[6]; 	// Commands from the RC transmitter
+	float rc_commands[6]; 	// Commands from the RC transmitter
 
 
 //	float cam_x_pos;	// Current x position from the camera system
@@ -390,7 +390,7 @@ typedef struct user_defined_t {
  */
 typedef struct raw_actuator_t {
 
-	int controller_corrected_motor_commands[6];
+	float controller_corrected_motor_commands[6];
 
 } raw_actuator_t;
 
@@ -400,7 +400,7 @@ typedef struct raw_actuator_t {
  *
  */
 typedef struct actuator_command_t {
-	int pwms[4];
+	float motor_magnitudes[4];
 } actuator_command_t;
 
 enum PWMChannels {
@@ -418,8 +418,8 @@ enum PWMChannels {
 
 typedef struct hardware_t {
   struct I2CDriver i2c;
-  struct PWMInputDriver pwm_inputs;
-  struct PWMOutputDriver pwm_outputs;
+  struct RCReceiverDriver rc_receiver;
+  struct MotorDriver motors;
   struct UARTDriver uart;
   struct TimerDriver global_timer;
   struct TimerDriver axi_timer;
diff --git a/quad/src/quad_app/user_input.c b/quad/src/quad_app/user_input.c
index bcb7478bf3ce6b7d9b5e6457e82bdafdce02d915..824910a1b95842ff9947558ee86270e832abd100 100644
--- a/quad/src/quad_app/user_input.c
+++ b/quad/src/quad_app/user_input.c
@@ -10,8 +10,8 @@
 int get_user_input(hardware_t *hardware_struct, log_t* log_struct, user_input_t* user_input_struct)
 {
   // Read in values from RC Receiver
-  struct PWMInputDriver *pwm_inputs = &hardware_struct->pwm_inputs;
-  read_rec_all(pwm_inputs, user_input_struct->rc_commands);
+  struct RCReceiverDriver *rc_receiver = &hardware_struct->rc_receiver;
+  read_rec_all(rc_receiver, user_input_struct->rc_commands);
 
   //create setpoints for manual flight
   // currently in units of radians
@@ -44,10 +44,10 @@ int kill_condition(user_input_t* user_input_struct)
  * 										       -
  *
  */
-float convert_from_receiver_cmd(int receiver_cmd, int max_receiver_cmd, int center_receiver_cmd, int min_receiver_cmd, float max_target, float min_target)
+float convert_from_receiver_cmd(float receiver_cmd, float max_receiver_cmd, float center_receiver_cmd, float min_receiver_cmd, float max_target, float min_target)
 {
 	// centers the receiver command by subtracting the given center value. This means that if receiver_cmd == center then receiver_cmd_centered should be 0.
-	int receiver_cmd_centered = receiver_cmd - center_receiver_cmd;
+	float receiver_cmd_centered = receiver_cmd - center_receiver_cmd;
 
 	if(receiver_cmd_centered <= 0) {
 		float ret = ((float)(receiver_cmd_centered * min_target)) / ((float) (min_receiver_cmd - center_receiver_cmd));
diff --git a/quad/src/quad_app/user_input.h b/quad/src/quad_app/user_input.h
index c289e99c96e437dcfed2398a6711bcf9ecadb786..674f66e6ea2fdf820f7272ee520c4d84a34d0515 100644
--- a/quad/src/quad_app/user_input.h
+++ b/quad/src/quad_app/user_input.h
@@ -35,36 +35,6 @@
 #define PITCH_DEG_TARGET 12.0f
 #define PITCH_RAD_TARGET ((float) ((PITCH_DEG_TARGET * 3.141592) / ((float) 180)))
 
-/////// Signals from the Rx mins, maxes and ranges
-
-//#define THROTTLE_MAX  191900
-//#define THROTTLE_MIN  110200
-//#define THROTTLE_RANGE THROTTLE_MAX - THROTTLE_MIN
-//
-//#define ROLL_MAX      170200
-//#define ROLL_MIN      129400
-//#define ROLL_CENTER   149800
-//#define ROLL_RANGE    ROLL_MAX - ROLL_MIN
-//
-//#define PITCH_MAX     169900
-//#define PITCH_MIN     129500
-//#define PITCH_CENTER  149700
-//#define PITCH_RANGE   PITCH_MAX - PITCH_MIN
-//
-//#define YAW_MAX       169400
-//#define YAW_MIN       129300
-//#define YAW_CENTER   (YAW_MIN + YAW_MAX)/2 //149800
-//#define YAW_RANGE     YAW_MAX - YAW_MIN
-//
-//#define GEAR_1	170800
-//#define GEAR_0	118300
-//
-//#define FLAP_1		192000
-//#define FLAP_0		107600
-//
-//#define GEAR_KILL     GEAR_0 // The kill point for the program
-//#define BASE          150000
-
 /**
  * @brief 
  *      Receives user input to the system.
@@ -81,7 +51,7 @@
  */
 int get_user_input(hardware_t *hardware_struct, log_t* log_struct,  user_input_t* user_input_struct);
 int kill_condition(user_input_t* user_input_struct);
-float convert_from_receiver_cmd(int receiver_cmd, int max_receiver_cmd, int center_receiver_cmd, int min_receiver_cmd, float max_target, float min_target);
+float convert_from_receiver_cmd(float receiver_cmd, float max_receiver_cmd, float center_receiver_cmd, float min_receiver_cmd, float max_target, float min_target);
 
 
 #endif /* USER_INPUT_H_ */
diff --git a/quad/src/quad_app/util.c b/quad/src/quad_app/util.c
index 2f1512a0e407385648f442083b2e5152b3fa8dac..e982432eafb4b624990b3da5b95846cc672abc50 100644
--- a/quad/src/quad_app/util.c
+++ b/quad/src/quad_app/util.c
@@ -13,10 +13,10 @@ extern int motor0_bias, motor1_bias, motor2_bias, motor3_bias;
 /**
  * Reads all 6 receiver channels at once
  */
-void read_rec_all(struct PWMInputDriver *pwm_input, u32 *mixer){
+void read_rec_all(struct RCReceiverDriver *rc_receiver, float *mixer){
   int i;
   for(i = 0; i < 6; i++){
-    pwm_input->read(pwm_input, i, &mixer[i]);
+    rc_receiver->read(rc_receiver, i, &mixer[i]);
   }
 }
 
@@ -48,30 +48,37 @@ int hexStrToInt(char *buf, int startIdx, int endIdx) {
  * If the message from the receiver is 0 - gear, kill the system by sending a 1
  * Otherwise, do nothing
  */
-int read_kill(int gear){
-	if(gear > 115000 && gear < 125000)
+int read_kill(float gear) {
+	if(gear < GEAR_MID)
 		return 1;
 	return 0;
 }
 
-int read_flap(int flap)
-{
-	// flap '0' is 108,000 CC (Up)
-	// flap '1' is 192,000 CC (Down)
-	// here we say if the reading is greater than 150,000 than its '1'; '0' otherwise
-	if(flap > 150000)
+int read_flap(float flap) {
+	if(flap > FLAP_MID)
 		return 1;
 	return 0;
 }
 
+/**
+ * Return true if the transmitter is on. This is mostly a failsafe to be sure we don't
+ * drop out of the air if the receiver cuts out momentarily. If the receiver
+ * cuts out, we expect the rc values will flatline at 0. So if we get a float zero,
+ * then assume the transmitter is disconnected.
+ */
+int is_transmitter_on(float gear) {
+	if (gear < 0.00001) return 0;
+	else return 1;
+}
+
 /**
  * Turns off the motors
  */
-void kill_motors(struct PWMOutputDriver *pwm_outputs) {
-  pwm_outputs->write(pwm_outputs, 0, MOTOR_MIN);
-  pwm_outputs->write(pwm_outputs, 1, MOTOR_MIN);
-  pwm_outputs->write(pwm_outputs, 2, MOTOR_MIN);
-  pwm_outputs->write(pwm_outputs, 3, MOTOR_MIN);
+void kill_motors(struct MotorDriver *motors) {
+  motors->write(motors, 0, MOTOR_MIN);
+  motors->write(motors, 1, MOTOR_MIN);
+  motors->write(motors, 2, MOTOR_MIN);
+  motors->write(motors, 3, MOTOR_MIN);
 }
 
 int build_int(u8 *buff) {
diff --git a/quad/src/quad_app/util.h b/quad/src/quad_app/util.h
index 643498afc53753720c8f4295fc88918ad5eae4db..390bafd9d5121af93ebef8e0a16c1340bea1fead 100644
--- a/quad/src/quad_app/util.h
+++ b/quad/src/quad_app/util.h
@@ -11,10 +11,10 @@
 #include "controllers.h"
 #include "hw_iface.h"
 
-void read_rec_all(struct PWMInputDriver *pwm_input, u32 *mixer);
-int read_kill(int gear);
-int read_flap(int flap);
-void kill_motors(struct PWMOutputDriver *pwm_outputs);
+void read_rec_all(struct RCReceiverDriver *rc_receiver, float *mixer);
+int read_kill(float gear);
+int read_flap(float flap);
+void kill_motors(struct MotorDriver *motors);
 
 int build_int(u8 *buff);
 float build_float(u8 *buff);
diff --git a/quad/src/virt_quad/hw_impl_unix.c b/quad/src/virt_quad/hw_impl_unix.c
index fea231c35e963f5321b35665e4c3c2feac961383..bbd8e8775df179f41c36e3f96152f634bf1e0d97 100644
--- a/quad/src/virt_quad/hw_impl_unix.c
+++ b/quad/src/virt_quad/hw_impl_unix.c
@@ -9,20 +9,20 @@ struct UARTDriver create_unix_uart() {
   return uart;
 }
 
-struct PWMOutputDriver create_unix_pwm_outputs() {
-  struct PWMOutputDriver pwm_outputs;
-  pwm_outputs.state = NULL;
-  pwm_outputs.reset = unix_pwm_output_reset;
-  pwm_outputs.write = unix_pwm_output_write;
-  return pwm_outputs;
+struct MotorDriver create_unix_motors() {
+  struct MotorDriver motors;
+  motors.state = NULL;
+  motors.reset = unix_motor_reset;
+  motors.write = unix_motor_write;
+  return motors;
 }
 
-struct PWMInputDriver create_unix_pwm_inputs() {
-  struct PWMInputDriver pwm_inputs;
-  pwm_inputs.state = NULL;
-  pwm_inputs.reset = unix_pwm_input_reset;
-  pwm_inputs.read = unix_pwm_input_read;
-  return pwm_inputs;
+struct RCReceiverDriver create_unix_rc_receiver() {
+  struct RCReceiverDriver rc_receivers;
+  rc_receivers.state = NULL;
+  rc_receivers.reset = unix_rc_receiver_reset;
+  rc_receivers.read = unix_rc_receiver_read;
+  return rc_receivers;
 }
 
 struct I2CDriver create_unix_i2c() {
diff --git a/quad/src/virt_quad/hw_impl_unix.h b/quad/src/virt_quad/hw_impl_unix.h
index 38745899342bb3a8c81734bead570d1d876f4cff..85e223f2896a317fd5f1c1fa79f6fc60cb7a8772 100644
--- a/quad/src/virt_quad/hw_impl_unix.h
+++ b/quad/src/virt_quad/hw_impl_unix.h
@@ -16,11 +16,11 @@ int unix_uart_reset(struct UARTDriver *self);
 int unix_uart_write(struct UARTDriver *self, unsigned char c);
 int unix_uart_read(struct UARTDriver *self, unsigned char *c);
 
-int unix_pwm_output_reset(struct PWMOutputDriver *self);
-int unix_pwm_output_write(struct PWMOutputDriver *self, unsigned int channel, unsigned long pulse_width_us);
+int unix_motor_reset(struct MotorDriver *self);
+int unix_motor_write(struct MotorDriver *self, unsigned int channel, float magnitude);
 
-int unix_pwm_input_reset(struct PWMInputDriver *self);
-int unix_pwm_input_read(struct PWMInputDriver *self, unsigned int channel, unsigned long *pulse_width_us);
+int unix_rc_receiver_reset(struct RCReceiverDriver *self);
+int unix_rc_receiver_read(struct RCReceiverDriver *self, unsigned int channel, float *magnitude);
 
 int unix_i2c_reset(struct I2CDriver *self);
 int unix_i2c_write(struct I2CDriver *self,
@@ -48,8 +48,8 @@ int unix_system_reset(struct SystemDriver *self);
 int unix_system_sleep(struct SystemDriver *self, unsigned long us);
 
 struct UARTDriver create_unix_uart();
-struct PWMOutputDriver create_unix_pwm_outputs();
-struct PWMInputDriver create_unix_pwm_inputs();
+struct MotorDriver create_unix_motors();
+struct RCReceiverDriver create_unix_rc_receiver();
 struct I2CDriver create_unix_i2c();
 struct TimerDriver create_unix_global_timer();
 struct TimerDriver create_unix_axi_timer();
@@ -58,6 +58,6 @@ struct SystemDriver create_unix_system();
 
 int test_unix_i2c();
 int test_unix_mio7_led_and_system();
-int test_unix_pwm_inputs();
+int test_unix_rc_receivers();
 
 #endif
diff --git a/quad/src/virt_quad/hw_impl_unix_pwm_output.c b/quad/src/virt_quad/hw_impl_unix_motor.c
similarity index 62%
rename from quad/src/virt_quad/hw_impl_unix_pwm_output.c
rename to quad/src/virt_quad/hw_impl_unix_motor.c
index e58d5cf5ae496a5fb6d6d4d76332d78097f98a9f..3ad271b526aff0b45047988280157e1aa5e12b25 100644
--- a/quad/src/virt_quad/hw_impl_unix_pwm_output.c
+++ b/quad/src/virt_quad/hw_impl_unix_motor.c
@@ -9,19 +9,20 @@
 void * output_cache();
 
 static char *output_pwms[4];
-static unsigned long cache[4];
+static float cache[4];
 pthread_t worker;
+static void float_equals(float a, float b);
 
 static int zero = 0;
 static int one = 1;
 static int two = 2;
 static int three = 3;
 
-int unix_pwm_output_reset(struct PWMOutputDriver *self) {
-  output_pwms[0] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor1";
-  output_pwms[1] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor2";
-  output_pwms[2] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor3";
-  output_pwms[3] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor4";
+int unix_motor_reset(struct MotorDriver *self) {
+  output_pwms[0] = VIRT_QUAD_FIFOS_DIR "/motor1";
+  output_pwms[1] = VIRT_QUAD_FIFOS_DIR "/motor2";
+  output_pwms[2] = VIRT_QUAD_FIFOS_DIR "/motor3";
+  output_pwms[3] = VIRT_QUAD_FIFOS_DIR "/motor4";
 
   mkdir(VIRT_QUAD_FIFOS_DIR, 0777);
 
@@ -34,13 +35,13 @@ int unix_pwm_output_reset(struct PWMOutputDriver *self) {
   return 0;
 }
 
-int unix_pwm_output_write(struct PWMOutputDriver *self,
+int unix_motor_write(struct MotorDriver *self,
                           unsigned int channel,
-                          unsigned long pulse_width_us) {
-  if (cache[channel] != pulse_width_us) {
-    printf("%s: %ld\n", output_pwms[channel], pulse_width_us);
+                          float magnitude) {
+  if (cache[channel] != magnitude) {
+    printf("%s: %.2f\n", output_pwms[channel], magnitude);
   }
-  cache[channel] = pulse_width_us;
+  cache[channel] = magnitude;
   return 0;
 }
 
@@ -56,10 +57,14 @@ void * output_cache(void *arg) {
   // Block while waiting for someone to listen
   while (1) {
     int fifo = open(output_pwms[i], O_WRONLY);
-    sprintf(buff, "%ld\n", cache[i]);
+    sprintf(buff, "%.2f\n", cache[i]);
     write(fifo, buff, strlen(buff));
     close(fifo);
     pthread_yield();
   }
   return NULL;
 }
+
+static void float_equals(float a, float b) {
+  return fabs(a - b) < 0.00001;
+}
diff --git a/quad/src/virt_quad/hw_impl_unix_pwm_input.c b/quad/src/virt_quad/hw_impl_unix_rc_receiver.c
similarity index 65%
rename from quad/src/virt_quad/hw_impl_unix_pwm_input.c
rename to quad/src/virt_quad/hw_impl_unix_rc_receiver.c
index df1aaf5f9b43811a4af9b5ed73aebe5e0ca24a86..229a019cd041d0aaed0636c3805121868eb68835 100644
--- a/quad/src/virt_quad/hw_impl_unix_pwm_input.c
+++ b/quad/src/virt_quad/hw_impl_unix_rc_receiver.c
@@ -9,17 +9,17 @@ void * update_input_cache();
 
 static char *input_names[6];
 static int fifos[6];
-static unsigned long cache[6];
+static float cache[6];
 static pthread_t workers[6];
 static int nums[] = {0, 1, 2, 3, 4, 5};
 
-int unix_pwm_input_reset(struct PWMInputDriver *self) {
-  input_names[0] = "pwm-input-throttle";
-  input_names[1] = "pwm-input-roll";
-  input_names[2] = "pwm-input-pitch";
-  input_names[3] = "pwm-input-yaw";
-  input_names[4] = "pwm-input-gear";
-  input_names[5] = "pwm-input-flap";
+int unix_rc_receiver_reset(struct RCReceiverDriver *self) {
+  input_names[0] = "rc-throttle";
+  input_names[1] = "rc-roll";
+  input_names[2] = "rc-pitch";
+  input_names[3] = "rc-yaw";
+  input_names[4] = "rc-gear";
+  input_names[5] = "rc-flap";
 
   mkdir(VIRT_QUAD_FIFOS_DIR, 0777);
 
@@ -38,17 +38,17 @@ int unix_pwm_input_reset(struct PWMInputDriver *self) {
   cache[5] = FLAP_1;
 
   for (i = 0; i < 6; i += 1) {
-    printf("%s: %lu\n", input_names[i], cache[i]);
+    printf("%s: %.2f\n", input_names[i], cache[i]);
   }
 
   return 0;
 }
 
-int unix_pwm_input_read(struct PWMInputDriver *self,
+int unix_rc_receiver_read(struct RCReceiverDriver *self,
                         unsigned int channel,
-                        unsigned long *pulse_width_us) {
+                        float *magnitude) {
 
-  *pulse_width_us = cache[channel];
+  *magnitude = cache[channel];
   return 0;
 }
 
@@ -69,13 +69,13 @@ void * update_input_cache(void *arg) {
     int bytes_read = read(fifos[i], buff, 15);
     if (bytes_read > 0) {
       buff[bytes_read] = '\0';
-      unsigned long val = strtoll(buff, NULL, 10);
-      if (val < max && val > min) {
+      float val = strtof(buff, NULL);
+      if (val <= 1 && val >= 0) {
 	cache[i] = val;
-	printf("%s: %lu\n", input_names[i], val);
+	printf("%s: %.2f\n", input_names[i], val);
       }
       else {
-	printf("%s: Bad value - input not received\n", input_names[i]);
+	printf("%s: Bad value (%f) - input not received\n", input_names[i], val);
       }
     }
     pthread_yield();
diff --git a/quad/src/virt_quad/main.c b/quad/src/virt_quad/main.c
index f703f6ab77943a760ce7db7a1604ec672edb4e7b..5f6aaf8dbc9fda7e1adfc1c21fe0ecafa8065e5b 100644
--- a/quad/src/virt_quad/main.c
+++ b/quad/src/virt_quad/main.c
@@ -6,8 +6,8 @@
 
 int setup_hardware(hardware_t *hardware) {
   hardware->i2c = create_unix_i2c();
-  hardware->pwm_inputs = create_unix_pwm_inputs();
-  hardware->pwm_outputs = create_unix_pwm_outputs();
+  hardware->rc_receiver = create_unix_rc_receiver();
+  hardware->motors = create_unix_motors();
   hardware->uart = create_unix_uart();
   hardware->global_timer = create_unix_global_timer();
   hardware->axi_timer = create_unix_axi_timer();
diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo.c b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo.c
index e8fceffa661ca92e0e1581d291a6f2b07d635819..3a6348f9b9a8f8090b2769f17201aeda88f36b93 100644
--- a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo.c
+++ b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo.c
@@ -9,20 +9,20 @@ struct UARTDriver create_zybo_uart() {
   return uart;
 }
 
-struct PWMOutputDriver create_zybo_pwm_outputs() {
-  struct PWMOutputDriver pwm_outputs;
-  pwm_outputs.state = NULL;
-  pwm_outputs.reset = zybo_pwm_output_reset;
-  pwm_outputs.write = zybo_pwm_output_write;
-  return pwm_outputs;
+struct MotorDriver create_zybo_motors() {
+  struct MotorDriver motors;
+  motors.state = NULL;
+  motors.reset = zybo_motor_reset;
+  motors.write = zybo_motor_write;
+  return motors;
 }
 
-struct PWMInputDriver create_zybo_pwm_inputs() {
-  struct PWMInputDriver pwm_inputs;
-  pwm_inputs.state = NULL;
-  pwm_inputs.reset = zybo_pwm_input_reset;
-  pwm_inputs.read = zybo_pwm_input_read;
-  return pwm_inputs;
+struct RCReceiverDriver create_zybo_rc_receiver() {
+  struct RCReceiverDriver rc_receiver;
+  rc_receiver.state = NULL;
+  rc_receiver.reset = zybo_rc_receiver_reset;
+  rc_receiver.read = zybo_rc_receiver_read;
+  return rc_receiver;
 }
 
 struct I2CDriver create_zybo_i2c() {
diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo.h b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo.h
index c721307bc08674e414683630564a2f7adf0dd2da..29d0ff8f388e0780f59aeefa63515ca0e8031522 100644
--- a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo.h
+++ b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo.h
@@ -22,11 +22,11 @@ int zybo_uart_reset(struct UARTDriver *self);
 int zybo_uart_write(struct UARTDriver *self, unsigned char c);
 int zybo_uart_read(struct UARTDriver *self, unsigned char *c);
 
-int zybo_pwm_output_reset(struct PWMOutputDriver *self);
-int zybo_pwm_output_write(struct PWMOutputDriver *self, unsigned int channel, unsigned long pulse_width_us);
+int zybo_motor_reset(struct MotorDriver *self);
+int zybo_motor_write(struct MotorDriver *self, unsigned int channel, float magnitude);
 
-int zybo_pwm_input_reset(struct PWMInputDriver *self);
-int zybo_pwm_input_read(struct PWMInputDriver *self, unsigned int channel, unsigned long *pulse_width_us);
+int zybo_rc_receiver_reset(struct RCReceiverDriver *self);
+int zybo_rc_receiver_read(struct RCReceiverDriver *self, unsigned int channel, float *magnitude);
 
 int zybo_i2c_reset(struct I2CDriver *self);
 int zybo_i2c_write(struct I2CDriver *self,
@@ -54,8 +54,8 @@ int zybo_system_reset(struct SystemDriver *self);
 int zybo_system_sleep(struct SystemDriver *self, unsigned long us);
 
 struct UARTDriver create_zybo_uart();
-struct PWMOutputDriver create_zybo_pwm_outputs();
-struct PWMInputDriver create_zybo_pwm_inputs();
+struct MotorDriver create_zybo_motors();
+struct RCReceiverDriver create_zybo_rc_receiver();
 struct I2CDriver create_zybo_i2c();
 struct TimerDriver create_zybo_global_timer();
 struct TimerDriver create_zybo_axi_timer();
@@ -64,6 +64,6 @@ struct SystemDriver create_zybo_system();
 
 int test_zybo_i2c();
 int test_zybo_mio7_led_and_system();
-int test_zybo_pwm_inputs();
+int test_zybo_rc_receivers();
 
 #endif
diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_motor.c b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_motor.c
new file mode 100644
index 0000000000000000000000000000000000000000..576c1ecaf353bf3caf7f0f63999ac500b8353a84
--- /dev/null
+++ b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_motor.c
@@ -0,0 +1,55 @@
+#include "hw_impl_zybo.h"
+
+#define SYS_CLOCK_RATE 100000000 // ticks per second
+#define FREQUENCY 450
+#define PERIOD_WIDTH SYS_CLOCK_RATE/FREQUENCY
+#define PULSE_WIDTH_LOW SYS_CLOCK_RATE/1000 // 1 ms
+#define PULSE_WIDTH_HIGH SYS_CLOCK_RATE/500 // 2 ms
+#define PULSE_WIDTH_ADDR_OFFSET 1
+
+struct MotorDriverState {
+  int *outputs[4];
+};
+
+int zybo_motor_reset(struct MotorDriver *self) {
+  if (self->state == NULL) {
+    self->state = malloc(sizeof(struct MotorDriverState));
+    if (self->state == NULL) {
+      return -1;
+    }
+  }
+  struct MotorDriverState *state = self->state;
+
+  state->outputs[0] = (int *) XPAR_PWM_SIGNAL_OUT_WKILLSWITCH_0_BASEADDR;
+  state->outputs[1] = (int *) XPAR_PWM_SIGNAL_OUT_WKILLSWITCH_1_BASEADDR;
+  state->outputs[2] = (int *) XPAR_PWM_SIGNAL_OUT_WKILLSWITCH_2_BASEADDR;
+  state->outputs[3] = (int *) XPAR_PWM_SIGNAL_OUT_WKILLSWITCH_3_BASEADDR;
+
+  // Set period width of PWM pulse
+  *(state->outputs[0]) = PERIOD_WIDTH;
+  *(state->outputs[1]) = PERIOD_WIDTH;
+  *(state->outputs[2]) = PERIOD_WIDTH;
+  *(state->outputs[3]) = PERIOD_WIDTH;
+
+  // Set a low pulse (1 ms) so that outputs are off
+  *(state->outputs[0] + PULSE_WIDTH_ADDR_OFFSET) = PULSE_WIDTH_LOW;
+  *(state->outputs[1] + PULSE_WIDTH_ADDR_OFFSET) = PULSE_WIDTH_LOW;
+  *(state->outputs[2] + PULSE_WIDTH_ADDR_OFFSET) = PULSE_WIDTH_LOW;
+  *(state->outputs[3] + PULSE_WIDTH_ADDR_OFFSET) = PULSE_WIDTH_LOW;
+
+  usleep(1000000);
+  return 0;
+}
+
+int zybo_motor_write(struct MotorDriver *self,
+                          unsigned int channel,
+                          float magnitude) {
+  if (magnitude > 1)
+    magnitude = 1;
+  if (magnitude < 0)
+    magnitude = 0;
+  struct MotorDriverState *state = self->state;
+  unsigned long pulse_width_ticks = (unsigned long) (magnitude * (float) (PULSE_WIDTH_HIGH - PULSE_WIDTH_LOW)) + PULSE_WIDTH_LOW;
+  *(state->outputs[channel] + PULSE_WIDTH_ADDR_OFFSET) = pulse_width_ticks;
+  return 0;
+}
diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_pwm_input.c b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_pwm_input.c
deleted file mode 100644
index b0c3cd98ef90a33fc0a416f2f02a1ed6b92f57cf..0000000000000000000000000000000000000000
--- a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_pwm_input.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "hw_impl_zybo.h"
-
-struct PWMInputDriverState {
-  int *channels[6];
-};
-
-int zybo_pwm_input_reset(struct PWMInputDriver *self) {
-  if (self->state == NULL) {
-    self->state = malloc(sizeof(struct PWMInputDriverState));
-    if (self->state == NULL) {
-      return -1;
-    }
-  }
-
-  // Save the addresses of the input PWM recorders
-  struct PWMInputDriverState *state = self->state;
-  state->channels[0] = (int *) XPAR_PWM_RECORDER_0_BASEADDR;
-  state->channels[1] = (int *) XPAR_PWM_RECORDER_1_BASEADDR;
-  state->channels[2] = (int *) XPAR_PWM_RECORDER_2_BASEADDR;
-  state->channels[3] = (int *) XPAR_PWM_RECORDER_3_BASEADDR;
-  state->channels[4] = (int *) XPAR_PWM_RECORDER_4_BASEADDR;
-  state->channels[5] = (int *) XPAR_PWM_RECORDER_5_BASEADDR;
-  return 0;
-}
-
-int zybo_pwm_input_read(struct PWMInputDriver *self,
-                        unsigned int channel,
-                        unsigned long *pulse_width_us) {
-  struct PWMInputDriverState *state = self->state;
-  *pulse_width_us = (long) *((int *) state->channels[channel]);
-  return 0;
-}
diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_pwm_output.c b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_pwm_output.c
deleted file mode 100644
index 3dd09e54379432529a3ce05614dedf648dffb3e2..0000000000000000000000000000000000000000
--- a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_pwm_output.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "hw_impl_zybo.h"
-
-#define SYS_CLOCK_RATE 100000000 // ticks per second
-#define FREQUENCY 450
-#define PERIOD_WIDTH SYS_CLOCK_RATE/FREQUENCY
-#define THROTTLE_PULSE_WIDTH_LOW SYS_CLOCK_RATE/1000 // 1 ms
-#define THROTTLE_PULSE_WIDTH_HIGH SYS_CLOCK_RATE/500 // 2 ms
-#define PULSE_WIDTH_ADDR_OFFSET 1
-
-struct PWMOutputDriverState {
-  int *outputs[4];
-};
-
-int zybo_pwm_output_reset(struct PWMOutputDriver *self) {
-  if (self->state == NULL) {
-    self->state = malloc(sizeof(struct PWMOutputDriverState));
-    if (self->state == NULL) {
-      return -1;
-    }
-  }
-  struct PWMOutputDriverState *state = self->state;
-
-  state->outputs[0] = (int *) XPAR_PWM_SIGNAL_OUT_WKILLSWITCH_0_BASEADDR;
-  state->outputs[1] = (int *) XPAR_PWM_SIGNAL_OUT_WKILLSWITCH_1_BASEADDR;
-  state->outputs[2] = (int *) XPAR_PWM_SIGNAL_OUT_WKILLSWITCH_2_BASEADDR;
-  state->outputs[3] = (int *) XPAR_PWM_SIGNAL_OUT_WKILLSWITCH_3_BASEADDR;
-
-  // Set period width of PWM pulse
-  *(state->outputs[0]) = PERIOD_WIDTH;
-  *(state->outputs[1]) = PERIOD_WIDTH;
-  *(state->outputs[2]) = PERIOD_WIDTH;
-  *(state->outputs[3]) = PERIOD_WIDTH;
-
-  // Set a low pulse (1 ms) so that outputs are off
-  *(state->outputs[0] + PULSE_WIDTH_ADDR_OFFSET) = THROTTLE_PULSE_WIDTH_LOW;
-  *(state->outputs[1] + PULSE_WIDTH_ADDR_OFFSET) = THROTTLE_PULSE_WIDTH_LOW;
-  *(state->outputs[2] + PULSE_WIDTH_ADDR_OFFSET) = THROTTLE_PULSE_WIDTH_LOW;
-  *(state->outputs[3] + PULSE_WIDTH_ADDR_OFFSET) = THROTTLE_PULSE_WIDTH_LOW;
-
-  usleep(1000000);
-  return 0;
-}
-
-int zybo_pwm_output_write(struct PWMOutputDriver *self,
-                          unsigned int channel,
-                          unsigned long pulse_width_us) {
-  if (pulse_width_us > THROTTLE_PULSE_WIDTH_HIGH)
-    pulse_width_us = THROTTLE_PULSE_WIDTH_HIGH;
-  if (pulse_width_us < THROTTLE_PULSE_WIDTH_LOW)
-    pulse_width_us = THROTTLE_PULSE_WIDTH_LOW;
-  struct PWMOutputDriverState *state = self->state;
-  *(state->outputs[channel] + PULSE_WIDTH_ADDR_OFFSET) = pulse_width_us;
-  return 0;
-}
diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_rc_receiver.c b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_rc_receiver.c
new file mode 100644
index 0000000000000000000000000000000000000000..63d6ab525b330789670b251008bbcbc7d863b0ad
--- /dev/null
+++ b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_rc_receiver.c
@@ -0,0 +1,40 @@
+#include "hw_impl_zybo.h"
+
+#define SYS_CLOCK_RATE 100000000 // ticks per second
+#define FREQUENCY 450
+#define PERIOD_WIDTH SYS_CLOCK_RATE/FREQUENCY
+#define PULSE_WIDTH_LOW SYS_CLOCK_RATE/1000 // 1 ms
+#define PULSE_WIDTH_HIGH SYS_CLOCK_RATE/500 // 2 ms
+#define PULSE_WIDTH_ADDR_OFFSET 1
+
+struct RCReceiverDriverState {
+  int *channels[6];
+};
+
+int zybo_rc_receiver_reset(struct RCReceiverDriver *self) {
+  if (self->state == NULL) {
+    self->state = malloc(sizeof(struct RCReceiverDriverState));
+    if (self->state == NULL) {
+      return -1;
+    }
+  }
+
+  // Save the addresses of the input PWM recorders
+  struct RCReceiverDriverState *state = self->state;
+  state->channels[0] = (int *) XPAR_PWM_RECORDER_0_BASEADDR;
+  state->channels[1] = (int *) XPAR_PWM_RECORDER_1_BASEADDR;
+  state->channels[2] = (int *) XPAR_PWM_RECORDER_2_BASEADDR;
+  state->channels[3] = (int *) XPAR_PWM_RECORDER_3_BASEADDR;
+  state->channels[4] = (int *) XPAR_PWM_RECORDER_4_BASEADDR;
+  state->channels[5] = (int *) XPAR_PWM_RECORDER_5_BASEADDR;
+  return 0;
+}
+
+int zybo_rc_receiver_read(struct RCReceiverDriver *self,
+                        unsigned int channel,
+                        float *magnitude) {
+  struct RCReceiverDriverState *state = self->state;
+  unsigned long pulse_width_ticks = (long) *((int *) state->channels[channel]);
+  *magnitude = (float) (pulse_width_ticks - PULSE_WIDTH_LOW) / (float) (PULSE_WIDTH_HIGH - PULSE_WIDTH_LOW);
+  return 0;
+}
diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_tests.c b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_tests.c
index 2a4a32c8063c34b5c4bf2f56651e7ee9de57b7d7..5971d023b9f4026040217b8368e6ee5d7967ce4a 100644
--- a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_tests.c
+++ b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_tests.c
@@ -159,18 +159,18 @@ int test_zybo_i2c_all() {
  * 4) Set the RUN_TESTS macro in main.c
  * 5) Uncomment only this test in main.c
  * 6) Debug main.
- * 7) Observe the values of pwm_inputs in debugger chaning as you use the
+ * 7) Observe the values of pwm_inputs in debugger changing as you use the
  *    Spektrum RC controller.
  */
-int test_zybo_pwm_inputs() {
-  struct PWMInputDriver pwm_inputs = create_zybo_pwm_inputs();
-  pwm_inputs.reset(&pwm_inputs);
+int test_zybo_rc_receiver() {
+  struct RCReceiverDriver rc_receiver = create_zybo_rc_receiver();
+  rc_receiver.reset(&rc_receiver);
 
-  unsigned long pwms[6];
+  float pwms[6];
   while (1) {
     int i;
     for (i = 0; i < 6; i += 1) {
-      pwm_inputs.read(&pwm_inputs, i, &pwms[i]);
+      rc_receiver.read(&rc_receiver, i, &pwms[i]);
     }
     continue;
   }
@@ -188,22 +188,21 @@ int test_zybo_pwm_inputs() {
  * 6) Run main.
  * 7) Observe the PWM width of those PMOD pins changing with time
  */
-int test_zybo_pwm_outputs() {
-  struct PWMOutputDriver pwm_outputs = create_zybo_pwm_outputs();
-  pwm_outputs.reset(&pwm_outputs);
+int test_zybo_motors() {
+  struct MotorDriver motors = create_zybo_motors();
+  motors.reset(&motors);
   struct SystemDriver sys = create_zybo_system();
   sys.reset(&sys);
 
+  double j = 0;
   while (1) {
-    int j;
-    for (j = 100000; j < 200000; j += 1) {
-      int i;
+    for (j = 0; j < 1.0; j += 0.01) {
+      int i = 0;
       for (i = 0; i < 4; i += 1) {
-        pwm_outputs.write(&pwm_outputs, i, j);
-        sys.sleep(&sys, 50);
+        motors.write(&motors, i, j);
+        sys.sleep(&sys, 50000);
       }
     }
-    continue;
   }
   return 0;
 }
diff --git a/quad/xsdk_workspace/real_quad/src/main.c b/quad/xsdk_workspace/real_quad/src/main.c
index ef3971feb9c63c531073afa30651d7cb9f3e9959..5892393e53137ad97d0c735c77d768c8f3a70d23 100644
--- a/quad/xsdk_workspace/real_quad/src/main.c
+++ b/quad/xsdk_workspace/real_quad/src/main.c
@@ -8,8 +8,8 @@
 
 int setup_hardware(hardware_t *hardware) {
   hardware->i2c = create_zybo_i2c();
-  hardware->pwm_inputs = create_zybo_pwm_inputs();
-  hardware->pwm_outputs = create_zybo_pwm_outputs();
+  hardware->rc_receiver = create_zybo_rc_receiver();
+  hardware->motors = create_zybo_motors();
   hardware->uart = create_zybo_uart();
   hardware->global_timer = create_zybo_global_timer();
   hardware->axi_timer = create_zybo_axi_timer();
@@ -29,8 +29,8 @@ int main()
   //test_zybo_i2c_imu();
   //test_zybo_i2c_px4flow();
   //test_zybo_i2c_all();
-  //test_zybo_pwm_inputs();
-  //test_zybo_pwm_outputs();
+  //test_zybo_rc_receiver();
+  test_zybo_motors();
   //test_zybo_uart();
   //test_zybo_axi_timer();
   //test_zybo_uart();