diff --git a/wpilibc/simulation/src/AnalogInput.cpp b/wpilibc/simulation/src/AnalogInput.cpp
new file mode 100644
index 0000000..71c48c5
--- /dev/null
+++ b/wpilibc/simulation/src/AnalogInput.cpp
@@ -0,0 +1,92 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "AnalogInput.h"
+#include "WPIErrors.h"
+#include "LiveWindow/LiveWindow.h"
+
+/**
+ * Construct an analog input.
+ * 
+ * @param channel The channel number to represent.
+ */
+AnalogInput::AnalogInput(uint32_t channel)
+{
+	m_channel = channel;
+	char buffer[50];
+	int n = sprintf(buffer, "analog/%d", channel);
+	m_impl = new SimFloatInput(buffer);
+
+	LiveWindow::GetInstance()->AddSensor("AnalogInput", channel, this);
+}
+
+/**
+ * Get a scaled sample straight from this channel.
+ * The value is scaled to units of Volts using the calibrated scaling data from GetLSBWeight() and GetOffset().
+ * @return A scaled sample straight from this channel.
+ */
+float AnalogInput::GetVoltage() const
+{
+    return m_impl->Get();
+}
+
+/**
+ * Get a scaled sample from the output of the oversample and average engine for this channel.
+ * The value is scaled to units of Volts using the calibrated scaling data from GetLSBWeight() and GetOffset().
+ * Using oversampling will cause this value to be higher resolution, but it will update more slowly.
+ * Using averaging will cause this value to be more stable, but it will update more slowly.
+ * @return A scaled sample from the output of the oversample and average engine for this channel.
+ */
+float AnalogInput::GetAverageVoltage() const
+{
+    return m_impl->Get();
+}
+
+/**
+ * Get the channel number.
+ * @return The channel number.
+ */
+uint32_t AnalogInput::GetChannel() const
+{
+	return m_channel;
+}
+
+/**
+ * Get the Average value for the PID Source base object.
+ * 
+ * @return The average voltage.
+ */
+double AnalogInput::PIDGet()
+{
+	return GetAverageVoltage();
+}
+
+void AnalogInput::UpdateTable() {
+	if (m_table != nullptr) {
+		m_table->PutNumber("Value", GetAverageVoltage());
+	}
+}
+
+void AnalogInput::StartLiveWindowMode() {
+	
+}
+
+void AnalogInput::StopLiveWindowMode() {
+	
+}
+
+std::string AnalogInput::GetSmartDashboardType() const {
+	return "Analog Input";
+}
+
+void AnalogInput::InitTable(std::shared_ptr<ITable> subTable) {
+	m_table = subTable;
+	UpdateTable();
+}
+
+std::shared_ptr<ITable> AnalogInput::GetTable() const {
+	return m_table;
+}
diff --git a/wpilibc/simulation/src/AnalogPotentiometer.cpp b/wpilibc/simulation/src/AnalogPotentiometer.cpp
new file mode 100644
index 0000000..fa312c1
--- /dev/null
+++ b/wpilibc/simulation/src/AnalogPotentiometer.cpp
@@ -0,0 +1,77 @@
+
+#include "AnalogPotentiometer.h"
+
+/**
+ * Common initialization code called by all constructors.
+ */
+void AnalogPotentiometer::initPot(AnalogInput *input, double scale, double offset) {
+    m_scale = scale;
+    m_offset = offset;
+    m_analog_input = input;
+}
+
+AnalogPotentiometer::AnalogPotentiometer(int channel, double scale, double offset) {
+    m_init_analog_input = true;
+    initPot(new AnalogInput(channel), scale, offset);
+}
+
+AnalogPotentiometer::AnalogPotentiometer(AnalogInput *input, double scale, double offset) {
+    m_init_analog_input = false;
+    initPot(input, scale, offset);
+}
+
+AnalogPotentiometer::AnalogPotentiometer(AnalogInput &input, double scale, double offset) {
+    m_init_analog_input = false;
+    initPot(&input, scale, offset);
+}
+
+AnalogPotentiometer::~AnalogPotentiometer() {
+  if(m_init_analog_input){
+    delete m_analog_input;
+    m_init_analog_input = false;
+  }
+}
+
+/**
+ * Get the current reading of the potentiomere.
+ *
+ * @return The current position of the potentiometer.
+ */
+double AnalogPotentiometer::Get() const {
+    return m_analog_input->GetVoltage() * m_scale + m_offset;
+}
+
+/**
+ * Implement the PIDSource interface.
+ *
+ * @return The current reading.
+ */
+double AnalogPotentiometer::PIDGet() {
+    return Get();
+}
+
+
+/**
+ * @return the Smart Dashboard Type
+ */
+std::string AnalogPotentiometer::GetSmartDashboardType() const {
+    return "Analog Input";
+}
+
+/**
+ * Live Window code, only does anything if live window is activated.
+ */
+void AnalogPotentiometer::InitTable(std::shared_ptr<ITable> subtable) {
+    m_table = subtable;
+    UpdateTable();
+}
+
+void AnalogPotentiometer::UpdateTable() {
+    if (m_table != nullptr) {
+        m_table->PutNumber("Value", Get());
+    }
+}
+
+std::shared_ptr<ITable> AnalogPotentiometer::GetTable() const {
+    return m_table;
+}
diff --git a/wpilibc/simulation/src/DigitalInput.cpp b/wpilibc/simulation/src/DigitalInput.cpp
new file mode 100644
index 0000000..e7ae36d
--- /dev/null
+++ b/wpilibc/simulation/src/DigitalInput.cpp
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "DigitalInput.h"
+#include "WPIErrors.h"
+
+/**
+ * Create an instance of a Digital Input class.
+ * Creates a digital input given a channel and uses the default module.
+ *
+ * @param channel The digital channel (1..14).
+ */
+DigitalInput::DigitalInput(uint32_t channel)
+{
+	char buf[64];
+	m_channel = channel;
+	int n = sprintf(buf, "dio/%d", channel);
+	m_impl = new SimDigitalInput(buf);
+}
+
+/*
+ * Get the value from a digital input channel.
+ * Retrieve the value of a single digital input channel from the FPGA.
+ */
+uint32_t DigitalInput::Get() const
+{
+	return m_impl->Get();
+}
+
+/**
+ * @return The GPIO channel number that this object represents.
+ */
+uint32_t DigitalInput::GetChannel() const
+{
+	return m_channel;
+}
+
+void DigitalInput::UpdateTable() {
+	if (m_table != nullptr) {
+		m_table->PutBoolean("Value", Get());
+	}
+}
+
+void DigitalInput::StartLiveWindowMode() {
+
+}
+
+void DigitalInput::StopLiveWindowMode() {
+
+}
+
+std::string DigitalInput::GetSmartDashboardType() const {
+	return "DigitalInput";
+}
+
+void DigitalInput::InitTable(std::shared_ptr<ITable> subTable) {
+	m_table = subTable;
+	UpdateTable();
+}
+
+std::shared_ptr<ITable> DigitalInput::GetTable() const {
+	return m_table;
+}
diff --git a/wpilibc/simulation/src/DoubleSolenoid.cpp b/wpilibc/simulation/src/DoubleSolenoid.cpp
new file mode 100644
index 0000000..d1d0917
--- /dev/null
+++ b/wpilibc/simulation/src/DoubleSolenoid.cpp
@@ -0,0 +1,125 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "DoubleSolenoid.h"
+#include "WPIErrors.h"
+#include <string.h>
+#include "LiveWindow/LiveWindow.h"
+
+/**
+ * Constructor.
+ *
+ * @param forwardChannel The forward channel on the module to control.
+ * @param reverseChannel The reverse channel on the module to control.
+ */
+DoubleSolenoid::DoubleSolenoid(uint32_t forwardChannel, uint32_t reverseChannel)
+  : DoubleSolenoid(1, forwardChannel, reverseChannel) {}
+
+/**
+ * Constructor.
+ *
+ * @param moduleNumber The solenoid module (1 or 2).
+ * @param forwardChannel The forward channel on the module to control.
+ * @param reverseChannel The reverse channel on the module to control.
+ */
+DoubleSolenoid::DoubleSolenoid(uint8_t moduleNumber, uint32_t forwardChannel, uint32_t reverseChannel)
+{
+    m_reversed = false;
+    if (reverseChannel < forwardChannel) { // Swap ports to get the right address
+        int channel = reverseChannel;
+        reverseChannel = forwardChannel;
+        forwardChannel = channel;
+        m_reversed = true;
+    }
+    char buffer[50];
+    int n = sprintf(buffer, "pneumatic/%d/%d/%d/%d", moduleNumber,
+                    forwardChannel, moduleNumber, reverseChannel);
+    m_impl = new SimContinuousOutput(buffer);  
+  
+	LiveWindow::GetInstance()->AddActuator("DoubleSolenoid", moduleNumber,
+                                           forwardChannel, this);
+}
+
+DoubleSolenoid::~DoubleSolenoid() {
+	if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
+/**
+ * Set the value of a solenoid.
+ *
+ * @param value Move the solenoid to forward, reverse, or don't move it.
+ */
+void DoubleSolenoid::Set(Value value)
+{
+    m_value = value;
+	switch(value)
+	{
+	case kOff:
+        m_impl->Set(0);
+        break;
+	case kForward:
+        m_impl->Set(m_reversed ? -1 : 1);
+		break;
+	case kReverse:
+        m_impl->Set(m_reversed ? 1 : -1);
+		break;
+	}
+}
+
+/**
+ * Read the current value of the solenoid.
+ *
+ * @return The current value of the solenoid.
+ */
+DoubleSolenoid::Value DoubleSolenoid::Get() const
+{
+	return m_value;
+}
+
+void DoubleSolenoid::ValueChanged(ITable *source, llvm::StringRef key,
+                                  std::shared_ptr<nt::Value> value,
+                                  bool isNew) {
+  if (!value->IsString()) return;
+  Value lvalue = kOff;
+	if (value->GetString() == "Forward")
+		lvalue = kForward;
+	else if (value->GetString() == "Reverse")
+		lvalue = kReverse;
+	Set(lvalue);
+}
+
+void DoubleSolenoid::UpdateTable() {
+	if (m_table != nullptr) {
+		m_table->PutString("Value", (Get() == kForward ? "Forward" : (Get() == kReverse ? "Reverse" : "Off")));
+	}
+}
+
+void DoubleSolenoid::StartLiveWindowMode() {
+	Set(kOff);
+	if (m_table != nullptr) {
+		m_table->AddTableListener("Value", this, true);
+	}
+}
+
+void DoubleSolenoid::StopLiveWindowMode() {
+	Set(kOff);
+	if (m_table != nullptr) {
+		m_table->RemoveTableListener(this);
+	}
+}
+
+std::string DoubleSolenoid::GetSmartDashboardType() const {
+	return "Double Solenoid";
+}
+
+void DoubleSolenoid::InitTable(std::shared_ptr<ITable> subTable) {
+	m_table = subTable;
+	UpdateTable();
+}
+
+std::shared_ptr<ITable> DoubleSolenoid::GetTable() const {
+	return m_table;
+}
diff --git a/wpilibc/simulation/src/DriverStation.cpp b/wpilibc/simulation/src/DriverStation.cpp
new file mode 100644
index 0000000..39802ab
--- /dev/null
+++ b/wpilibc/simulation/src/DriverStation.cpp
@@ -0,0 +1,518 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.
+ */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "DriverStation.h"
+#include "AnalogInput.h"
+#include "Timer.h"
+#include "NetworkCommunication/FRCComm.h"
+#include "MotorSafetyHelper.h"
+#include "Utility.h"
+#include "WPIErrors.h"
+#include <string.h>
+#include "Log.hpp"
+
+// set the logging level
+TLogLevel dsLogLevel = logDEBUG;
+const double JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL = 1.0;
+
+#define DS_LOG(level) \
+  if (level > dsLogLevel) ; \
+  else Log().Get(level)
+
+const uint32_t DriverStation::kJoystickPorts;
+
+/**
+ * DriverStation constructor.
+ *
+ * This is only called once the first time GetInstance() is called
+ */
+DriverStation::DriverStation() {
+  // All joysticks should default to having zero axes, povs and buttons, so
+  // uninitialized memory doesn't get sent to speed controllers.
+  for (unsigned int i = 0; i < kJoystickPorts; i++) {
+    m_joystickAxes[i].count = 0;
+    m_joystickPOVs[i].count = 0;
+    m_joystickButtons[i].count = 0;
+    m_joystickDescriptor[i].isXbox = 0;
+    m_joystickDescriptor[i].type = -1;
+    m_joystickDescriptor[i].name[0] = '\0';
+  }
+  // Register that semaphore with the network communications task.
+  // It will signal when new packet data is available.
+  HALSetNewDataSem(m_packetDataAvailableCond.native_handle());
+
+  AddToSingletonList();
+
+}
+
+void DriverStation::Run() {
+  int period = 0;
+  while (true) {
+    {
+      std::unique_lock<priority_mutex> lock(m_packetDataAvailableMutex);
+      m_packetDataAvailableCond.wait(lock);
+    }
+    GetData();
+    m_waitForDataCond.notify_all();
+
+    if (++period >= 4) {
+      MotorSafetyHelper::CheckMotors();
+      period = 0;
+    }
+    if (m_userInDisabled) HALNetworkCommunicationObserveUserProgramDisabled();
+    if (m_userInAutonomous) HALNetworkCommunicationObserveUserProgramAutonomous();
+    if (m_userInTeleop) HALNetworkCommunicationObserveUserProgramTeleop();
+    if (m_userInTest) HALNetworkCommunicationObserveUserProgramTest();
+  }
+}
+
+/**
+ * Return a reference to the singleton DriverStation.
+ * @return Pointer to the DS instance
+ */
+DriverStation &DriverStation::GetInstance() {
+  static DriverStation instance;
+  return instance;
+}
+
+/**
+ * Copy data from the DS task for the user.
+ * If no new data exists, it will just be returned, otherwise
+ * the data will be copied from the DS polling loop.
+ */
+void DriverStation::GetData() {
+  // Get the status of all of the joysticks
+  for (uint8_t stick = 0; stick < kJoystickPorts; stick++) {
+    HALGetJoystickAxes(stick, &m_joystickAxes[stick]);
+    HALGetJoystickPOVs(stick, &m_joystickPOVs[stick]);
+    HALGetJoystickButtons(stick, &m_joystickButtons[stick]);
+    HALGetJoystickDescriptor(stick, &m_joystickDescriptor[stick]);
+  }
+  m_newControlData.give();
+}
+
+/**
+ * Read the battery voltage.
+ *
+ * @return The battery voltage in Volts.
+ */
+float DriverStation::GetBatteryVoltage() const {
+  int32_t status = 0;
+  float voltage = getVinVoltage(&status);
+  wpi_setErrorWithContext(status, "getVinVoltage");
+
+  return voltage;
+}
+
+/**
+ * Reports errors related to unplugged joysticks
+ * Throttles the errors so that they don't overwhelm the DS
+ */
+void DriverStation::ReportJoystickUnpluggedError(std::string message) {
+  double currentTime = Timer::GetFPGATimestamp();
+  if (currentTime > m_nextMessageTime) {
+    ReportError(message);
+    m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL;
+  }
+}
+
+/**
+ * Returns the number of axes on a given joystick port
+ *
+ * @param stick The joystick port number
+ * @return The number of axes on the indicated joystick
+ */
+int DriverStation::GetStickAxisCount(uint32_t stick) const {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return 0;
+  }
+  HALJoystickAxes joystickAxes;
+  HALGetJoystickAxes(stick, &joystickAxes);
+  return joystickAxes.count;
+}
+
+/**
+ * Returns the name of the joystick at the given port
+ *
+ * @param stick The joystick port number
+ * @return The name of the joystick at the given port
+ */
+std::string DriverStation::GetJoystickName(uint32_t stick) const {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+  }
+  std::string retVal(m_joystickDescriptor[0].name);
+  return retVal;
+}
+
+/**
+ * Returns the type of joystick at a given port
+ *
+ * @param stick The joystick port number
+ * @return The HID type of joystick at the given port
+ */
+int DriverStation::GetJoystickType(uint32_t stick) const {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return -1;
+  }
+  return (int)m_joystickDescriptor[stick].type;
+}
+
+/**
+ * Returns a boolean indicating if the controller is an xbox controller.
+ *
+ * @param stick The joystick port number
+ * @return A boolean that is true if the controller is an xbox controller.
+ */
+bool DriverStation::GetJoystickIsXbox(uint32_t stick) const {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return false;
+  }
+  return (bool)m_joystickDescriptor[stick].isXbox;
+}
+
+/**
+ * Returns the types of Axes on a given joystick port
+ *
+ * @param stick The joystick port number and the target axis
+ * @return What type of axis the axis is reporting to be
+ */
+int DriverStation::GetJoystickAxisType(uint32_t stick, uint8_t axis) const {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return -1;
+  }
+  return m_joystickDescriptor[stick].axisTypes[axis];
+}
+
+/**
+ * Returns the number of POVs on a given joystick port
+ *
+ * @param stick The joystick port number
+ * @return The number of POVs on the indicated joystick
+ */
+int DriverStation::GetStickPOVCount(uint32_t stick) const {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return 0;
+  }
+  HALJoystickPOVs joystickPOVs;
+  HALGetJoystickPOVs(stick, &joystickPOVs);
+  return joystickPOVs.count;
+}
+
+/**
+ * Returns the number of buttons on a given joystick port
+ *
+ * @param stick The joystick port number
+ * @return The number of buttons on the indicated joystick
+ */
+int DriverStation::GetStickButtonCount(uint32_t stick) const {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return 0;
+  }
+  HALJoystickButtons joystickButtons;
+  HALGetJoystickButtons(stick, &joystickButtons);
+  return joystickButtons.count;
+}
+
+/**
+ * Get the value of the axis on a joystick.
+ * This depends on the mapping of the joystick connected to the specified port.
+ *
+ * @param stick The joystick to read.
+ * @param axis The analog axis value to read from the joystick.
+ * @return The value of the axis on the joystick.
+ */
+float DriverStation::GetStickAxis(uint32_t stick, uint32_t axis) {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return 0;
+  }
+
+  if (axis >= m_joystickAxes[stick].count) {
+    if (axis >= kMaxJoystickAxes) {
+      wpi_setWPIError(BadJoystickAxis);
+    }
+    else {
+      ReportJoystickUnpluggedError(
+          "WARNING: Joystick Axis missing, check if all controllers are "
+          "plugged in\n");
+    }
+    return 0.0f;
+  }
+
+  int8_t value = m_joystickAxes[stick].axes[axis];
+
+  if (value < 0) {
+    return value / 128.0f;
+  } else {
+    return value / 127.0f;
+  }
+}
+
+/**
+ * Get the state of a POV on the joystick.
+ *
+ * @return the angle of the POV in degrees, or -1 if the POV is not pressed.
+ */
+int DriverStation::GetStickPOV(uint32_t stick, uint32_t pov) {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return -1;
+  }
+
+  if (pov >= m_joystickPOVs[stick].count) {
+    if (pov >= kMaxJoystickPOVs) {
+      wpi_setWPIError(BadJoystickAxis);
+    }
+    else {
+      ReportJoystickUnpluggedError(
+          "WARNING: Joystick POV missing, check if all controllers are plugged "
+          "in\n");
+    }
+    return -1;
+  }
+
+  return m_joystickPOVs[stick].povs[pov];
+}
+
+/**
+ * The state of the buttons on the joystick.
+ *
+ * @param stick The joystick to read.
+ * @return The state of the buttons on the joystick.
+ */
+uint32_t DriverStation::GetStickButtons(uint32_t stick) const {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return 0;
+  }
+
+  return m_joystickButtons[stick].buttons;
+}
+
+/**
+ * The state of one joystick button. Button indexes begin at 1.
+ *
+ * @param stick The joystick to read.
+ * @param button The button index, beginning at 1.
+ * @return The state of the joystick button.
+ */
+bool DriverStation::GetStickButton(uint32_t stick, uint8_t button) {
+  if (stick >= kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+    return false;
+  }
+
+  if (button > m_joystickButtons[stick].count) {
+    ReportJoystickUnpluggedError(
+        "WARNING: Joystick Button missing, check if all controllers are "
+        "plugged in\n");
+    return false;
+  }
+  if (button == 0) {
+    ReportJoystickUnpluggedError(
+        "ERROR: Button indexes begin at 1 in WPILib for C++ and Java");
+    return false;
+  }
+  return ((0x1 << (button - 1)) & m_joystickButtons[stick].buttons) != 0;
+}
+
+/**
+ * Check if the DS has enabled the robot
+ * @return True if the robot is enabled and the DS is connected
+ */
+bool DriverStation::IsEnabled() const {
+  HALControlWord controlWord;
+  memset(&controlWord, 0, sizeof(controlWord));
+  HALGetControlWord(&controlWord);
+  return controlWord.enabled && controlWord.dsAttached;
+}
+
+/**
+ * Check if the robot is disabled
+ * @return True if the robot is explicitly disabled or the DS is not connected
+ */
+bool DriverStation::IsDisabled() const {
+  HALControlWord controlWord;
+  memset(&controlWord, 0, sizeof(controlWord));
+  HALGetControlWord(&controlWord);
+  return !(controlWord.enabled && controlWord.dsAttached);
+}
+
+/**
+ * Check if the DS is commanding autonomous mode
+ * @return True if the robot is being commanded to be in autonomous mode
+ */
+bool DriverStation::IsAutonomous() const {
+  HALControlWord controlWord;
+  memset(&controlWord, 0, sizeof(controlWord));
+  HALGetControlWord(&controlWord);
+  return controlWord.autonomous;
+}
+
+/**
+ * Check if the DS is commanding teleop mode
+ * @return True if the robot is being commanded to be in teleop mode
+ */
+bool DriverStation::IsOperatorControl() const {
+  HALControlWord controlWord;
+  memset(&controlWord, 0, sizeof(controlWord));
+  HALGetControlWord(&controlWord);
+  return !(controlWord.autonomous || controlWord.test);
+}
+
+/**
+ * Check if the DS is commanding test mode
+ * @return True if the robot is being commanded to be in test mode
+ */
+bool DriverStation::IsTest() const {
+  HALControlWord controlWord;
+  HALGetControlWord(&controlWord);
+  return controlWord.test;
+}
+
+/**
+ * Check if the DS is attached
+ * @return True if the DS is connected to the robot
+ */
+bool DriverStation::IsDSAttached() const {
+  HALControlWord controlWord;
+  memset(&controlWord, 0, sizeof(controlWord));
+  HALGetControlWord(&controlWord);
+  return controlWord.dsAttached;
+}
+
+/**
+ * @return always true in simulation
+ */
+bool DriverStation::IsSysActive() const {
+  return true;
+}
+
+/**
+ * @return always false in simulation
+ */
+bool DriverStation::IsSysBrownedOut() const {
+  return false;
+}
+
+/**
+ * Has a new control packet from the driver station arrived since the last time
+ * this function was called?
+ * Warning: If you call this function from more than one place at the same time,
+ * you will not get the get the intended behaviour.
+ * @return True if the control data has been updated since the last call.
+ */
+bool DriverStation::IsNewControlData() const {
+  return m_newControlData.tryTake() == false;
+}
+
+/**
+ * Is the driver station attached to a Field Management System?
+ * @return True if the robot is competing on a field being controlled by a Field
+ * Management System
+ */
+bool DriverStation::IsFMSAttached() const {
+  HALControlWord controlWord;
+  HALGetControlWord(&controlWord);
+  return controlWord.fmsAttached;
+}
+
+/**
+ * Return the alliance that the driver station says it is on.
+ * This could return kRed or kBlue
+ * @return The Alliance enum (kRed, kBlue or kInvalid)
+ */
+DriverStation::Alliance DriverStation::GetAlliance() const {
+  HALAllianceStationID allianceStationID;
+  HALGetAllianceStation(&allianceStationID);
+  switch (allianceStationID) {
+    case kHALAllianceStationID_red1:
+    case kHALAllianceStationID_red2:
+    case kHALAllianceStationID_red3:
+      return kRed;
+    case kHALAllianceStationID_blue1:
+    case kHALAllianceStationID_blue2:
+    case kHALAllianceStationID_blue3:
+      return kBlue;
+    default:
+      return kInvalid;
+  }
+}
+
+/**
+ * Return the driver station location on the field
+ * This could return 1, 2, or 3
+ * @return The location of the driver station (1-3, 0 for invalid)
+ */
+uint32_t DriverStation::GetLocation() const {
+  HALAllianceStationID allianceStationID;
+  HALGetAllianceStation(&allianceStationID);
+  switch (allianceStationID) {
+    case kHALAllianceStationID_red1:
+    case kHALAllianceStationID_blue1:
+      return 1;
+    case kHALAllianceStationID_red2:
+    case kHALAllianceStationID_blue2:
+      return 2;
+    case kHALAllianceStationID_red3:
+    case kHALAllianceStationID_blue3:
+      return 3;
+    default:
+      return 0;
+  }
+}
+
+/**
+ * Wait until a new packet comes from the driver station
+ * This blocks on a semaphore, so the waiting is efficient.
+ * This is a good way to delay processing until there is new driver station data
+ * to act on
+ */
+void DriverStation::WaitForData() {
+  std::unique_lock<priority_mutex> lock(m_waitForDataMutex);
+  m_waitForDataCond.wait(lock);
+}
+
+/**
+ * Return the approximate match time
+ * The FMS does not send an official match time to the robots, but does send an
+ * approximate match time.
+ * The value will count down the time remaining in the current period (auto or
+ * teleop).
+ * Warning: This is not an official time (so it cannot be used to dispute ref
+ * calls or guarantee that a function
+ * will trigger before the match ends)
+ * The Practice Match function of the DS approximates the behaviour seen on the
+ * field.
+ * @return Time remaining in current match period (auto or teleop)
+ */
+double DriverStation::GetMatchTime() const {
+  float matchTime;
+  HALGetMatchTime(&matchTime);
+  return (double)matchTime;
+}
+
+/**
+ * Report an error to the DriverStation messages window.
+ * The error is also printed to the program console.
+ */
+void DriverStation::ReportError(std::string error) {
+  std::cout << error << std::endl;
+
+  HALControlWord controlWord;
+  HALGetControlWord(&controlWord);
+  if (controlWord.dsAttached) {
+    HALSetErrorData(error.c_str(), error.size(), 0);
+  }
+}
diff --git a/wpilibc/simulation/src/Encoder.cpp b/wpilibc/simulation/src/Encoder.cpp
new file mode 100644
index 0000000..790868e
--- /dev/null
+++ b/wpilibc/simulation/src/Encoder.cpp
@@ -0,0 +1,364 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Encoder.h"
+#include "Resource.h"
+#include "WPIErrors.h"
+#include "LiveWindow/LiveWindow.h"
+
+/**
+ * Common initialization code for Encoders.
+ * This code allocates resources for Encoders and is common to all constructors.
+ *
+ * The counter will start counting immediately.
+ *
+ * @param reverseDirection If true, counts down instead of up (this is all relative)
+ * @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
+ * selected, then an encoder FPGA object is used and the returned counts will be 4x the encoder
+ * spec'd value since all rising and falling edges are counted. If 1X or 2X are selected then
+ * a counter object will be used and the returned value will either exactly match the spec'd count
+ * or be double (2x) the spec'd count.
+ */
+void Encoder::InitEncoder(int channelA, int channelB, bool reverseDirection, EncodingType encodingType)
+{
+	m_table = nullptr;
+	this->channelA = channelA;
+	this->channelB = channelB;
+	m_encodingType = encodingType;
+	m_encodingScale = encodingType == k4X ? 4
+		: encodingType == k2X ? 2
+		: 1;
+
+	int32_t index = 0;
+	m_distancePerPulse = 1.0;
+
+	LiveWindow::GetInstance()->AddSensor("Encoder", channelA, this);
+
+	if (channelB < channelA) { // Swap ports
+		int channel = channelB;
+		channelB = channelA;
+		channelA = channel;
+		m_reverseDirection = !reverseDirection;
+	} else {
+		m_reverseDirection = reverseDirection;
+	}
+	char buffer[50];
+	int n = sprintf(buffer, "dio/%d/%d", channelA, channelB);
+	impl = new SimEncoder(buffer);
+	impl->Start();
+}
+
+/**
+ * Encoder constructor.
+ * Construct a Encoder given a and b channels.
+ *
+ * The counter will start counting immediately.
+ *
+ * @param aChannel The a channel digital input channel.
+ * @param bChannel The b channel digital input channel.
+ * @param reverseDirection represents the orientation of the encoder and inverts the output values
+ * if necessary so forward represents positive values.
+ * @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
+ * selected, then an encoder FPGA object is used and the returned counts will be 4x the encoder
+ * spec'd value since all rising and falling edges are counted. If 1X or 2X are selected then
+ * a counter object will be used and the returned value will either exactly match the spec'd count
+ * or be double (2x) the spec'd count.
+ */
+Encoder::Encoder(uint32_t aChannel, uint32_t bChannel, bool reverseDirection, EncodingType encodingType)
+{
+    InitEncoder(aChannel, bChannel, reverseDirection, encodingType);
+}
+
+/**
+ * Encoder constructor.
+ * Construct a Encoder given a and b channels as digital inputs. This is used in the case
+ * where the digital inputs are shared. The Encoder class will not allocate the digital inputs
+ * and assume that they already are counted.
+ *
+ * The counter will start counting immediately.
+ *
+ * @param aSource The source that should be used for the a channel.
+ * @param bSource the source that should be used for the b channel.
+ * @param reverseDirection represents the orientation of the encoder and inverts the output values
+ * if necessary so forward represents positive values.
+ * @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
+ * selected, then an encoder FPGA object is used and the returned counts will be 4x the encoder
+ * spec'd value since all rising and falling edges are counted. If 1X or 2X are selected then
+ * a counter object will be used and the returned value will either exactly match the spec'd count
+ * or be double (2x) the spec'd count.
+ */
+/* TODO: [Not Supported] Encoder::Encoder(DigitalSource *aSource, DigitalSource *bSource, bool reverseDirection, EncodingType encodingType) :
+	m_encoder(nullptr),
+	m_counter(nullptr)
+{
+	m_aSource = aSource;
+	m_bSource = bSource;
+	m_allocatedASource = false;
+	m_allocatedBSource = false;
+	if (m_aSource == nullptr || m_bSource == nullptr)
+		wpi_setWPIError(NullParameter);
+	else
+		InitEncoder(reverseDirection, encodingType);
+        }*/
+
+/**
+ * Encoder constructor.
+ * Construct a Encoder given a and b channels as digital inputs. This is used in the case
+ * where the digital inputs are shared. The Encoder class will not allocate the digital inputs
+ * and assume that they already are counted.
+ *
+ * The counter will start counting immediately.
+ *
+ * @param aSource The source that should be used for the a channel.
+ * @param bSource the source that should be used for the b channel.
+ * @param reverseDirection represents the orientation of the encoder and inverts the output values
+ * if necessary so forward represents positive values.
+ * @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
+ * selected, then an encoder FPGA object is used and the returned counts will be 4x the encoder
+ * spec'd value since all rising and falling edges are counted. If 1X or 2X are selected then
+ * a counter object will be used and the returned value will either exactly match the spec'd count
+ * or be double (2x) the spec'd count.
+ */
+/*// TODO: [Not Supported] Encoder::Encoder(DigitalSource &aSource, DigitalSource &bSource, bool reverseDirection, EncodingType encodingType) :
+	m_encoder(nullptr),
+	m_counter(nullptr)
+{
+	m_aSource = &aSource;
+	m_bSource = &bSource;
+	m_allocatedASource = false;
+	m_allocatedBSource = false;
+	InitEncoder(reverseDirection, encodingType);
+    }*/
+
+/**
+ * Reset the Encoder distance to zero.
+ * Resets the current count to zero on the encoder.
+ */
+void Encoder::Reset()
+{
+    impl->Reset();
+}
+
+/**
+ * Determine if the encoder is stopped.
+ * Using the MaxPeriod value, a boolean is returned that is true if the encoder is considered
+ * stopped and false if it is still moving. A stopped encoder is one where the most recent pulse
+ * width exceeds the MaxPeriod.
+ * @return True if the encoder is considered stopped.
+ */
+bool Encoder::GetStopped() const
+{
+    throw "Simulation doesn't currently support this method.";
+}
+
+/**
+ * The last direction the encoder value changed.
+ * @return The last direction the encoder value changed.
+ */
+bool Encoder::GetDirection() const
+{
+    throw "Simulation doesn't currently support this method.";
+}
+
+/**
+ * The scale needed to convert a raw counter value into a number of encoder pulses.
+ */
+double Encoder::DecodingScaleFactor() const
+{
+	switch (m_encodingType)
+	{
+	case k1X:
+		return 1.0;
+	case k2X:
+		return 0.5;
+	case k4X:
+		return 0.25;
+	default:
+		return 0.0;
+	}
+}
+
+/**
+ * The encoding scale factor 1x, 2x, or 4x, per the requested encodingType.
+ * Used to divide raw edge counts down to spec'd counts.
+ */
+int32_t Encoder::GetEncodingScale() const { return m_encodingScale; }
+
+/**
+ * Gets the raw value from the encoder.
+ * The raw value is the actual count unscaled by the 1x, 2x, or 4x scale
+ * factor.
+ * @return Current raw count from the encoder
+ */
+int32_t Encoder::GetRaw() const
+{
+	throw "Simulation doesn't currently support this method.";
+}
+
+/**
+ * Gets the current count.
+ * Returns the current count on the Encoder.
+ * This method compensates for the decoding type.
+ *
+ * @return Current count from the Encoder adjusted for the 1x, 2x, or 4x scale factor.
+ */
+int32_t Encoder::Get() const
+{
+	throw "Simulation doesn't currently support this method.";
+}
+
+/**
+ * Returns the period of the most recent pulse.
+ * Returns the period of the most recent Encoder pulse in seconds.
+ * This method compenstates for the decoding type.
+ *
+ * @deprecated Use GetRate() in favor of this method.  This returns unscaled periods and GetRate() scales using value from SetDistancePerPulse().
+ *
+ * @return Period in seconds of the most recent pulse.
+ */
+double Encoder::GetPeriod() const
+{
+	throw "Simulation doesn't currently support this method.";
+}
+
+/**
+ * Sets the maximum period for stopped detection.
+ * Sets the value that represents the maximum period of the Encoder before it will assume
+ * that the attached device is stopped. This timeout allows users to determine if the wheels or
+ * other shaft has stopped rotating.
+ * This method compensates for the decoding type.
+ *
+ * @deprecated Use SetMinRate() in favor of this method.  This takes unscaled periods and SetMinRate() scales using value from SetDistancePerPulse().
+ *
+ * @param maxPeriod The maximum time between rising and falling edges before the FPGA will
+ * report the device stopped. This is expressed in seconds.
+ */
+void Encoder::SetMaxPeriod(double maxPeriod)
+{
+	throw "Simulation doesn't currently support this method.";
+}
+
+/**
+ * Get the distance the robot has driven since the last reset.
+ *
+ * @return The distance driven since the last reset as scaled by the value from SetDistancePerPulse().
+ */
+double Encoder::GetDistance() const
+{
+    return m_distancePerPulse * impl->GetPosition();
+}
+
+/**
+ * Get the current rate of the encoder.
+ * Units are distance per second as scaled by the value from SetDistancePerPulse().
+ *
+ * @return The current rate of the encoder.
+ */
+double Encoder::GetRate() const
+{
+    return m_distancePerPulse * impl->GetVelocity();
+}
+
+/**
+ * Set the minimum rate of the device before the hardware reports it stopped.
+ *
+ * @param minRate The minimum rate.  The units are in distance per second as scaled by the value from SetDistancePerPulse().
+ */
+void Encoder::SetMinRate(double minRate)
+{
+    throw "Simulation doesn't currently support this method.";
+}
+
+/**
+ * Set the distance per pulse for this encoder.
+ * This sets the multiplier used to determine the distance driven based on the count value
+ * from the encoder.
+ * Do not include the decoding type in this scale.  The library already compensates for the decoding type.
+ * Set this value based on the encoder's rated Pulses per Revolution and
+ * factor in gearing reductions following the encoder shaft.
+ * This distance can be in any units you like, linear or angular.
+ *
+ * @param distancePerPulse The scale factor that will be used to convert pulses to useful units.
+ */
+void Encoder::SetDistancePerPulse(double distancePerPulse)
+{
+	if (m_reverseDirection) {
+		m_distancePerPulse = -distancePerPulse;
+	} else {
+		m_distancePerPulse = distancePerPulse;
+	}
+}
+
+/**
+ * Set the direction sensing for this encoder.
+ * This sets the direction sensing on the encoder so that it could count in the correct
+ * software direction regardless of the mounting.
+ * @param reverseDirection true if the encoder direction should be reversed
+ */
+void Encoder::SetReverseDirection(bool reverseDirection)
+{
+    throw "Simulation doesn't currently support this method.";
+}
+
+/**
+ * Set which parameter of the encoder you are using as a process control variable.
+ *
+ * @param pidSource An enum to select the parameter.
+ */
+void Encoder::SetPIDSourceType(PIDSourceType pidSource)
+{
+	m_pidSource = pidSource;
+}
+
+/**
+ * Implement the PIDSource interface.
+ *
+ * @return The current value of the selected source parameter.
+ */
+double Encoder::PIDGet()
+{
+	switch (m_pidSource)
+	{
+	case PIDSourceType::kDisplacement:
+		return GetDistance();
+	case PIDSourceType::kRate:
+		return GetRate();
+	default:
+		return 0.0;
+	}
+}
+
+void Encoder::UpdateTable() {
+	if (m_table != nullptr) {
+        m_table->PutNumber("Speed", GetRate());
+        m_table->PutNumber("Distance", GetDistance());
+        m_table->PutNumber("Distance per Tick", m_reverseDirection ? -m_distancePerPulse : m_distancePerPulse);
+	}
+}
+
+void Encoder::StartLiveWindowMode() {
+
+}
+
+void Encoder::StopLiveWindowMode() {
+
+}
+
+std::string Encoder::GetSmartDashboardType() const {
+	if (m_encodingType == k4X)
+		return "Quadrature Encoder";
+	else
+		return "Encoder";
+}
+
+void Encoder::InitTable(std::shared_ptr<ITable> subTable) {
+	m_table = subTable;
+	UpdateTable();
+}
+
+std::shared_ptr<ITable> Encoder::GetTable() const {
+	return m_table;
+}
diff --git a/wpilibc/simulation/src/Gyro.cpp b/wpilibc/simulation/src/Gyro.cpp
new file mode 100644
index 0000000..a28bb9b
--- /dev/null
+++ b/wpilibc/simulation/src/Gyro.cpp
@@ -0,0 +1,133 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Gyro.h"
+#include "Timer.h"
+#include "WPIErrors.h"
+#include "LiveWindow/LiveWindow.h"
+
+const uint32_t Gyro::kOversampleBits = 10;
+const uint32_t Gyro::kAverageBits = 0;
+const float Gyro::kSamplesPerSecond = 50.0;
+const float Gyro::kCalibrationSampleTime = 5.0;
+const float Gyro::kDefaultVoltsPerDegreePerSecond = 0.007;
+
+/**
+ * Initialize the gyro.
+ * Calibrate the gyro by running for a number of samples and computing the center value for this
+ * part. Then use the center value as the Accumulator center value for subsequent measurements.
+ * It's important to make sure that the robot is not moving while the centering calculations are
+ * in progress, this is typically done when the robot is first turned on while it's sitting at
+ * rest before the competition starts.
+ */
+void Gyro::InitGyro(int channel)
+{
+	SetPIDSourceType(PIDSourceType::kDisplacement);
+
+	char buffer[50];
+	int n = sprintf(buffer, "analog/%d", channel);
+	impl = new SimGyro(buffer);
+
+	LiveWindow::GetInstance()->AddSensor("Gyro", channel, this);
+}
+
+/**
+ * Gyro constructor with only a channel..
+ *
+ * @param channel The analog channel the gyro is connected to.
+ */
+Gyro::Gyro(uint32_t channel)
+{
+    InitGyro(channel);
+}
+
+/**
+ * Reset the gyro.
+ * Resets the gyro to a heading of zero. This can be used if there is significant
+ * drift in the gyro and it needs to be recalibrated after it has been running.
+ */
+void Gyro::Reset()
+{
+    impl->Reset();
+}
+
+/**
+ * Return the actual angle in degrees that the robot is currently facing.
+ *
+ * The angle is based on the current accumulator value corrected by the oversampling rate, the
+ * gyro type and the A/D calibration values.
+ * The angle is continuous, that is can go beyond 360 degrees. This make algorithms that wouldn't
+ * want to see a discontinuity in the gyro output as it sweeps past 0 on the second time around.
+ *
+ * @return the current heading of the robot in degrees. This heading is based on integration
+ * of the returned rate from the gyro.
+ */
+float Gyro::GetAngle() const
+{
+    return impl->GetAngle();
+}
+
+
+/**
+ * Return the rate of rotation of the gyro
+ *
+ * The rate is based on the most recent reading of the gyro analog value
+ *
+ * @return the current rate in degrees per second
+ */
+double Gyro::GetRate() const
+{
+    return impl->GetVelocity();
+}
+
+void Gyro::SetPIDSourceType(PIDSourceType pidSource)
+{
+    m_pidSource = pidSource;
+}
+
+/**
+ * Get the angle in degrees for the PIDSource base object.
+ *
+ * @return The angle in degrees.
+ */
+double Gyro::PIDGet()
+{
+	switch(GetPIDSourceType()){
+	case PIDSourceType::kRate:
+		return GetRate();
+	case PIDSourceType::kDisplacement:
+		return GetAngle();
+	default:
+		return 0;
+	}
+}
+
+void Gyro::UpdateTable() {
+	if (m_table != nullptr) {
+		m_table->PutNumber("Value", GetAngle());
+	}
+}
+
+void Gyro::StartLiveWindowMode() {
+
+}
+
+void Gyro::StopLiveWindowMode() {
+
+}
+
+std::string Gyro::GetSmartDashboardType() const {
+	return "Gyro";
+}
+
+void Gyro::InitTable(std::shared_ptr<ITable> subTable) {
+	m_table = subTable;
+	UpdateTable();
+}
+
+std::shared_ptr<ITable> Gyro::GetTable() const {
+	return m_table;
+}
diff --git a/wpilibc/simulation/src/IterativeRobot.cpp b/wpilibc/simulation/src/IterativeRobot.cpp
new file mode 100644
index 0000000..f2511df
--- /dev/null
+++ b/wpilibc/simulation/src/IterativeRobot.cpp
@@ -0,0 +1,312 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+#include "IterativeRobot.h"
+
+#include "DriverStation.h"
+#include "SmartDashboard/SmartDashboard.h"
+#include "LiveWindow/LiveWindow.h"
+#include "networktables/NetworkTable.h"
+
+//not sure what this is used for yet.
+#ifdef _UNIX
+	#include <unistd.h>
+#endif
+
+const double IterativeRobot::kDefaultPeriod = 0;
+
+/**
+ * Set the period for the periodic functions.
+ *
+ * @param period The period of the periodic function calls.  0.0 means sync to driver station control data.
+ */
+void IterativeRobot::SetPeriod(double period)
+{
+	if (period > 0.0)
+	{
+		// Not syncing with the DS, so start the timer for the main loop
+		m_mainLoopTimer.Reset();
+		m_mainLoopTimer.Start();
+	}
+	else
+	{
+		// Syncing with the DS, don't need the timer
+		m_mainLoopTimer.Stop();
+	}
+	m_period = period;
+}
+
+/**
+ * Get the period for the periodic functions.
+ * Returns 0.0 if configured to syncronize with DS control data packets.
+ * @return Period of the periodic function calls
+ */
+double IterativeRobot::GetPeriod()
+{
+	return m_period;
+}
+
+/**
+ * Get the number of loops per second for the IterativeRobot
+ * @return Frequency of the periodic function calls
+ */
+double IterativeRobot::GetLoopsPerSec()
+{
+	// If syncing to the driver station, we don't know the rate,
+	//   so guess something close.
+	if (m_period <= 0.0)
+		return 50.0;
+	return 1.0 / m_period;
+}
+
+/**
+ * Provide an alternate "main loop" via StartCompetition().
+ *
+ * This specific StartCompetition() implements "main loop" behavior like that of the FRC
+ * control system in 2008 and earlier, with a primary (slow) loop that is
+ * called periodically, and a "fast loop" (a.k.a. "spin loop") that is
+ * called as fast as possible with no delay between calls.
+ */
+void IterativeRobot::StartCompetition()
+{
+	LiveWindow *lw = LiveWindow::GetInstance();
+	// first and one-time initialization
+	SmartDashboard::init();
+	NetworkTable::GetTable("LiveWindow")->GetSubTable("~STATUS~")->PutBoolean("LW Enabled", false);
+	RobotInit();
+
+	// loop forever, calling the appropriate mode-dependent function
+	lw->SetEnabled(false);
+	while (true)
+	{
+		// Call the appropriate function depending upon the current robot mode
+		if (IsDisabled())
+		{
+			// call DisabledInit() if we are now just entering disabled mode from
+			// either a different mode or from power-on
+			if(!m_disabledInitialized)
+			{
+				lw->SetEnabled(false);
+				DisabledInit();
+				m_disabledInitialized = true;
+				// reset the initialization flags for the other modes
+				m_autonomousInitialized = false;
+                m_teleopInitialized = false;
+                m_testInitialized = false;
+			}
+			if (NextPeriodReady())
+			{
+				// TODO: HALNetworkCommunicationObserveUserProgramDisabled();
+				DisabledPeriodic();
+			}
+		}
+		else if (IsAutonomous())
+		{
+			// call AutonomousInit() if we are now just entering autonomous mode from
+			// either a different mode or from power-on
+			if(!m_autonomousInitialized)
+			{
+				lw->SetEnabled(false);
+				AutonomousInit();
+				m_autonomousInitialized = true;
+				// reset the initialization flags for the other modes
+				m_disabledInitialized = false;
+                m_teleopInitialized = false;
+                m_testInitialized = false;
+			}
+			if (NextPeriodReady())
+			{
+				// TODO: HALNetworkCommunicationObserveUserProgramAutonomous();
+				AutonomousPeriodic();
+			}
+		}
+        else if (IsTest())
+        {
+            // call TestInit() if we are now just entering test mode from
+            // either a different mode or from power-on
+            if(!m_testInitialized)
+            {
+            	lw->SetEnabled(true);
+                TestInit();
+                m_testInitialized = true;
+                // reset the initialization flags for the other modes
+                m_disabledInitialized = false;
+                m_autonomousInitialized = false;
+                m_teleopInitialized = false;
+            }
+            if (NextPeriodReady())
+            {
+                // TODO: HALNetworkCommunicationObserveUserProgramTest();
+                TestPeriodic();
+            }
+        }
+		else
+		{
+			// call TeleopInit() if we are now just entering teleop mode from
+			// either a different mode or from power-on
+			if(!m_teleopInitialized)
+			{
+				lw->SetEnabled(false);
+				TeleopInit();
+				m_teleopInitialized = true;
+				// reset the initialization flags for the other modes
+				m_disabledInitialized = false;
+                m_autonomousInitialized = false;
+                m_testInitialized = false;
+                Scheduler::GetInstance()->SetEnabled(true);
+			}
+			if (NextPeriodReady())
+			{
+				// TODO: HALNetworkCommunicationObserveUserProgramTeleop();
+				TeleopPeriodic();
+			}
+		}
+		// wait for driver station data so the loop doesn't hog the CPU
+		m_ds.WaitForData();
+	}
+}
+
+/**
+ * Determine if the periodic functions should be called.
+ *
+ * If m_period > 0.0, call the periodic function every m_period as compared
+ * to Timer.Get().  If m_period == 0.0, call the periodic functions whenever
+ * a packet is received from the Driver Station, or about every 20ms.
+ *
+ * @todo Decide what this should do if it slips more than one cycle.
+ */
+
+bool IterativeRobot::NextPeriodReady()
+{
+	if (m_period > 0.0)
+	{
+		return m_mainLoopTimer.HasPeriodPassed(m_period);
+	}
+	else
+	{
+		// XXX: BROKEN! return m_ds->IsNewControlData();
+	}
+    return true;
+}
+
+/**
+ * Robot-wide initialization code should go here.
+ *
+ * Users should override this method for default Robot-wide initialization which will
+ * be called when the robot is first powered on.  It will be called exactly 1 time.
+ */
+void IterativeRobot::RobotInit()
+{
+	printf("Default %s() method... Overload me!\n", __FUNCTION__);
+}
+
+/**
+ * Initialization code for disabled mode should go here.
+ *
+ * Users should override this method for initialization code which will be called each time
+ * the robot enters disabled mode.
+ */
+void IterativeRobot::DisabledInit()
+{
+	printf("Default %s() method... Overload me!\n", __FUNCTION__);
+}
+
+/**
+ * Initialization code for autonomous mode should go here.
+ *
+ * Users should override this method for initialization code which will be called each time
+ * the robot enters autonomous mode.
+ */
+void IterativeRobot::AutonomousInit()
+{
+	printf("Default %s() method... Overload me!\n", __FUNCTION__);
+}
+
+/**
+ * Initialization code for teleop mode should go here.
+ *
+ * Users should override this method for initialization code which will be called each time
+ * the robot enters teleop mode.
+ */
+void IterativeRobot::TeleopInit()
+{
+    printf("Default %s() method... Overload me!\n", __FUNCTION__);
+}
+
+/**
+ * Initialization code for test mode should go here.
+ *
+ * Users should override this method for initialization code which will be called each time
+ * the robot enters test mode.
+ */
+void IterativeRobot::TestInit()
+{
+    printf("Default %s() method... Overload me!\n", __FUNCTION__);
+}
+
+/**
+ * Periodic code for disabled mode should go here.
+ *
+ * Users should override this method for code which will be called periodically at a regular
+ * rate while the robot is in disabled mode.
+ */
+void IterativeRobot::DisabledPeriodic()
+{
+	static bool firstRun = true;
+	if (firstRun)
+	{
+		printf("Default %s() method... Overload me!\n", __FUNCTION__);
+		firstRun = false;
+	}
+}
+
+/**
+ * Periodic code for autonomous mode should go here.
+ *
+ * Users should override this method for code which will be called periodically at a regular
+ * rate while the robot is in autonomous mode.
+ */
+void IterativeRobot::AutonomousPeriodic()
+{
+	static bool firstRun = true;
+	if (firstRun)
+	{
+		printf("Default %s() method... Overload me!\n", __FUNCTION__);
+		firstRun = false;
+	}
+}
+
+/**
+ * Periodic code for teleop mode should go here.
+ *
+ * Users should override this method for code which will be called periodically at a regular
+ * rate while the robot is in teleop mode.
+ */
+void IterativeRobot::TeleopPeriodic()
+{
+	static bool firstRun = true;
+	if (firstRun)
+	{
+		printf("Default %s() method... Overload me!\n", __FUNCTION__);
+		firstRun = false;
+	}
+}
+
+/**
+ * Periodic code for test mode should go here.
+ *
+ * Users should override this method for code which will be called periodically at a regular
+ * rate while the robot is in test mode.
+ */
+void IterativeRobot::TestPeriodic()
+{
+    static bool firstRun = true;
+    if (firstRun)
+    {
+        printf("Default %s() method... Overload me!\n", __FUNCTION__);
+        firstRun = false;
+    }
+}
+
diff --git a/wpilibc/simulation/src/Jaguar.cpp b/wpilibc/simulation/src/Jaguar.cpp
new file mode 100644
index 0000000..fab109d
--- /dev/null
+++ b/wpilibc/simulation/src/Jaguar.cpp
@@ -0,0 +1,73 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+
+#include "Jaguar.h"
+//#include "NetworkCommunication/UsageReporting.h"
+#include "LiveWindow/LiveWindow.h"
+
+/**
+ * @param channel The PWM channel that the Jaguar is attached to.
+ */
+Jaguar::Jaguar(uint32_t channel) : SafePWM(channel)
+{
+	/*
+	 * Input profile defined by Luminary Micro.
+	 *
+	 * Full reverse ranges from 0.671325ms to 0.6972211ms
+	 * Proportional reverse ranges from 0.6972211ms to 1.4482078ms
+	 * Neutral ranges from 1.4482078ms to 1.5517922ms
+	 * Proportional forward ranges from 1.5517922ms to 2.3027789ms
+	 * Full forward ranges from 2.3027789ms to 2.328675ms
+	 */
+	SetBounds(2.31, 1.55, 1.507, 1.454, .697);
+	SetPeriodMultiplier(kPeriodMultiplier_1X);
+	SetRaw(m_centerPwm);
+
+	LiveWindow::GetInstance()->AddActuator("Jaguar", GetChannel(), this);
+}
+
+/**
+ * Set the PWM value.
+ *
+ * The PWM value is set using a range of -1.0 to 1.0, appropriately
+ * scaling the value for the FPGA.
+ *
+ * @param speed The speed value between -1.0 and 1.0 to set.
+ * @param syncGroup Unused interface.
+ */
+void Jaguar::Set(float speed, uint8_t syncGroup)
+{
+	SetSpeed(speed);
+}
+
+/**
+ * Get the recently set value of the PWM.
+ *
+ * @return The most recently set value for the PWM between -1.0 and 1.0.
+ */
+float Jaguar::Get() const
+{
+	return GetSpeed();
+}
+
+/**
+ * Common interface for disabling a motor.
+ */
+void Jaguar::Disable()
+{
+	SetRaw(kPwmDisabled);
+}
+
+/**
+ * Write out the PID value as seen in the PIDOutput base object.
+ *
+ * @param output Write out the PWM value as was found in the PIDController
+ */
+void Jaguar::PIDWrite(float output)
+{
+	Set(output);
+}
diff --git a/wpilibc/simulation/src/Joystick.cpp b/wpilibc/simulation/src/Joystick.cpp
new file mode 100644
index 0000000..a7a299c
--- /dev/null
+++ b/wpilibc/simulation/src/Joystick.cpp
@@ -0,0 +1,377 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.
+ */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Joystick.h"
+#include "DriverStation.h"
+//#include "NetworkCommunication/UsageReporting.h"
+#include "WPIErrors.h"
+#include <math.h>
+#include <string.h>
+
+const uint32_t Joystick::kDefaultXAxis;
+const uint32_t Joystick::kDefaultYAxis;
+const uint32_t Joystick::kDefaultZAxis;
+const uint32_t Joystick::kDefaultTwistAxis;
+const uint32_t Joystick::kDefaultThrottleAxis;
+const uint32_t Joystick::kDefaultTriggerButton;
+const uint32_t Joystick::kDefaultTopButton;
+static Joystick *joysticks[DriverStation::kJoystickPorts];
+static bool joySticksInitialized = false;
+
+/**
+ * Construct an instance of a joystick.
+ * The joystick index is the usb port on the drivers station.
+ *
+ * @param port The port on the driver station that the joystick is plugged into
+ * (0-5).
+ */
+Joystick::Joystick(uint32_t port)
+    : Joystick(port, kNumAxisTypes, kNumButtonTypes) {
+  m_axes[kXAxis] = kDefaultXAxis;
+  m_axes[kYAxis] = kDefaultYAxis;
+  m_axes[kZAxis] = kDefaultZAxis;
+  m_axes[kTwistAxis] = kDefaultTwistAxis;
+  m_axes[kThrottleAxis] = kDefaultThrottleAxis;
+
+  m_buttons[kTriggerButton] = kDefaultTriggerButton;
+  m_buttons[kTopButton] = kDefaultTopButton;
+
+  HALReport(HALUsageReporting::kResourceType_Joystick, port);
+}
+
+/**
+ * Version of the constructor to be called by sub-classes.
+ *
+ * This constructor allows the subclass to configure the number of constants
+ * for axes and buttons.
+ *
+ * @param port The port on the driver station that the joystick is plugged into.
+ * @param numAxisTypes The number of axis types in the enum.
+ * @param numButtonTypes The number of button types in the enum.
+ */
+Joystick::Joystick(uint32_t port, uint32_t numAxisTypes,
+                   uint32_t numButtonTypes)
+    : m_ds(DriverStation::GetInstance()),
+      m_port(port),
+      m_axes(numAxisTypes),
+      m_buttons(numButtonTypes) {
+  if (!joySticksInitialized) {
+    for (auto& joystick : joysticks) joystick = nullptr;
+    joySticksInitialized = true;
+  }
+  if (m_port >= DriverStation::kJoystickPorts) {
+    wpi_setWPIError(BadJoystickIndex);
+  } else {
+    joysticks[m_port] = this;
+  }
+}
+
+Joystick *Joystick::GetStickForPort(uint32_t port) {
+  Joystick *stick = joysticks[port];
+  if (stick == nullptr) {
+    stick = new Joystick(port);
+    joysticks[port] = stick;
+  }
+  return stick;
+}
+
+/**
+ * Get the X value of the joystick.
+ * This depends on the mapping of the joystick connected to the current port.
+ * @param hand This parameter is ignored for the Joystick class and is only here
+ * to complete the GenericHID interface.
+ */
+float Joystick::GetX(JoystickHand hand) const {
+  return GetRawAxis(m_axes[kXAxis]);
+}
+
+/**
+ * Get the Y value of the joystick.
+ * This depends on the mapping of the joystick connected to the current port.
+ * @param hand This parameter is ignored for the Joystick class and is only here
+ * to complete the GenericHID interface.
+ */
+float Joystick::GetY(JoystickHand hand) const {
+  return GetRawAxis(m_axes[kYAxis]);
+}
+
+/**
+ * Get the Z value of the current joystick.
+ * This depends on the mapping of the joystick connected to the current port.
+ */
+float Joystick::GetZ() const { return GetRawAxis(m_axes[kZAxis]); }
+
+/**
+ * Get the twist value of the current joystick.
+ * This depends on the mapping of the joystick connected to the current port.
+ */
+float Joystick::GetTwist() const { return GetRawAxis(m_axes[kTwistAxis]); }
+
+/**
+ * Get the throttle value of the current joystick.
+ * This depends on the mapping of the joystick connected to the current port.
+ */
+float Joystick::GetThrottle() const {
+  return GetRawAxis(m_axes[kThrottleAxis]);
+}
+
+/**
+ * Get the value of the axis.
+ *
+ * @param axis The axis to read, starting at 0.
+ * @return The value of the axis.
+ */
+float Joystick::GetRawAxis(uint32_t axis) const {
+  return m_ds.GetStickAxis(m_port, axis);
+}
+
+/**
+ * For the current joystick, return the axis determined by the argument.
+ *
+ * This is for cases where the joystick axis is returned programatically,
+ * otherwise one of the
+ * previous functions would be preferable (for example GetX()).
+ *
+ * @param axis The axis to read.
+ * @return The value of the axis.
+ */
+float Joystick::GetAxis(AxisType axis) const {
+  switch (axis) {
+    case kXAxis:
+      return this->GetX();
+    case kYAxis:
+      return this->GetY();
+    case kZAxis:
+      return this->GetZ();
+    case kTwistAxis:
+      return this->GetTwist();
+    case kThrottleAxis:
+      return this->GetThrottle();
+    default:
+      wpi_setWPIError(BadJoystickAxis);
+      return 0.0;
+  }
+}
+
+/**
+ * Read the state of the trigger on the joystick.
+ *
+ * Look up which button has been assigned to the trigger and read its state.
+ *
+ * @param hand This parameter is ignored for the Joystick class and is only here
+ * to complete the GenericHID interface.
+ * @return The state of the trigger.
+ */
+bool Joystick::GetTrigger(JoystickHand hand) const {
+  return GetRawButton(m_buttons[kTriggerButton]);
+}
+
+/**
+ * Read the state of the top button on the joystick.
+ *
+ * Look up which button has been assigned to the top and read its state.
+ *
+ * @param hand This parameter is ignored for the Joystick class and is only here
+ * to complete the GenericHID interface.
+ * @return The state of the top button.
+ */
+bool Joystick::GetTop(JoystickHand hand) const {
+  return GetRawButton(m_buttons[kTopButton]);
+}
+
+/**
+ * This is not supported for the Joystick.
+ * This method is only here to complete the GenericHID interface.
+ */
+bool Joystick::GetBumper(JoystickHand hand) const {
+  // Joysticks don't have bumpers.
+  return false;
+}
+
+/**
+ * Get the button value (starting at button 1)
+ *
+ * The buttons are returned in a single 16 bit value with one bit representing
+ * the state
+ * of each button. The appropriate button is returned as a boolean value.
+ *
+ * @param button The button number to be read (starting at 1)
+ * @return The state of the button.
+ **/
+bool Joystick::GetRawButton(uint32_t button) const {
+  return m_ds.GetStickButton(m_port, button);
+}
+
+/**
+ * Get the state of a POV on the joystick.
+ *
+ * @param pov The index of the POV to read (starting at 0)
+ * @return the angle of the POV in degrees, or -1 if the POV is not pressed.
+ */
+int Joystick::GetPOV(uint32_t pov) const {
+  return m_ds.GetStickPOV(m_port, pov);
+}
+
+/**
+ * Get buttons based on an enumerated type.
+ *
+ * The button type will be looked up in the list of buttons and then read.
+ *
+ * @param button The type of button to read.
+ * @return The state of the button.
+ */
+bool Joystick::GetButton(ButtonType button) const {
+  switch (button) {
+    case kTriggerButton:
+      return GetTrigger();
+    case kTopButton:
+      return GetTop();
+    default:
+      return false;
+  }
+}
+
+/**
+ * Get the number of axis for a joystick
+ *
+ * @return the number of axis for the current joystick
+ */
+int Joystick::GetAxisCount() const { return m_ds.GetStickAxisCount(m_port); }
+
+/**
+ * Get the value of isXbox for the joystick.
+ *
+ * @return A boolean that is true if the joystick is an xbox controller.
+ */
+bool Joystick::GetIsXbox() const { return m_ds.GetJoystickIsXbox(m_port); }
+
+/**
+ * Get the HID type of the controller.
+ *
+ * @return the HID type of the controller.
+ */
+Joystick::HIDType Joystick::GetType() const {
+  return static_cast<HIDType>(m_ds.GetJoystickType(m_port));
+}
+
+/**
+ * Get the name of the joystick.
+ *
+ * @return the name of the controller.
+ */
+std::string Joystick::GetName() const { return m_ds.GetJoystickName(m_port); }
+
+// int Joystick::GetAxisType(uint8_t axis) const
+//{
+//	return m_ds.GetJoystickAxisType(m_port, axis);
+//}
+
+/**
+  * Get the number of axis for a joystick
+  *
+* @return the number of buttons on the current joystick
+ */
+int Joystick::GetButtonCount() const {
+  return m_ds.GetStickButtonCount(m_port);
+}
+
+/**
+ * Get the number of axis for a joystick
+ *
+ * @return then umber of POVs for the current joystick
+ */
+int Joystick::GetPOVCount() const { return m_ds.GetStickPOVCount(m_port); }
+
+/**
+ * Get the channel currently associated with the specified axis.
+ *
+ * @param axis The axis to look up the channel for.
+ * @return The channel fr the axis.
+ */
+uint32_t Joystick::GetAxisChannel(AxisType axis) const { return m_axes[axis]; }
+
+/**
+ * Set the channel associated with a specified axis.
+ *
+ * @param axis The axis to set the channel for.
+ * @param channel The channel to set the axis to.
+ */
+void Joystick::SetAxisChannel(AxisType axis, uint32_t channel) {
+  m_axes[axis] = channel;
+}
+
+/**
+ * Get the magnitude of the direction vector formed by the joystick's
+ * current position relative to its origin
+ *
+ * @return The magnitude of the direction vector
+ */
+float Joystick::GetMagnitude() const {
+  return sqrt(pow(GetX(), 2) + pow(GetY(), 2));
+}
+
+/**
+ * Get the direction of the vector formed by the joystick and its origin
+ * in radians
+ *
+ * @return The direction of the vector in radians
+ */
+float Joystick::GetDirectionRadians() const { return atan2(GetX(), -GetY()); }
+
+/**
+ * Get the direction of the vector formed by the joystick and its origin
+ * in degrees
+ *
+ * uses acos(-1) to represent Pi due to absence of readily accessible Pi
+ * constant in C++
+ *
+ * @return The direction of the vector in degrees
+ */
+float Joystick::GetDirectionDegrees() const {
+  return (180 / acos(-1)) * GetDirectionRadians();
+}
+
+/**
+ * Set the rumble output for the joystick. The DS currently supports 2 rumble
+ * values,
+ * left rumble and right rumble
+ * @param type Which rumble value to set
+ * @param value The normalized value (0 to 1) to set the rumble to
+ */
+void Joystick::SetRumble(RumbleType type, float value) {
+  if (value < 0)
+    value = 0;
+  else if (value > 1)
+    value = 1;
+  if (type == kLeftRumble)
+    m_leftRumble = value * 65535;
+  else
+    m_rightRumble = value * 65535;
+  HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
+}
+
+/**
+ * Set a single HID output value for the joystick.
+ * @param outputNumber The index of the output to set (1-32)
+ * @param value The value to set the output to
+ */
+
+void Joystick::SetOutput(uint8_t outputNumber, bool value) {
+  m_outputs =
+      (m_outputs & ~(1 << (outputNumber - 1))) | (value << (outputNumber - 1));
+
+  HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
+}
+
+/**
+ * Set all HID output values for the joystick.
+ * @param value The 32 bit output value (1 bit for each output)
+ */
+void Joystick::SetOutputs(uint32_t value) {
+  m_outputs = value;
+  HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
+}
diff --git a/wpilibc/simulation/src/MotorSafetyHelper.cpp b/wpilibc/simulation/src/MotorSafetyHelper.cpp
new file mode 100644
index 0000000..87f5352
--- /dev/null
+++ b/wpilibc/simulation/src/MotorSafetyHelper.cpp
@@ -0,0 +1,140 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.
+ */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "MotorSafetyHelper.h"
+
+#include "DriverStation.h"
+#include "MotorSafety.h"
+#include "Timer.h"
+#include "WPIErrors.h"
+
+#include <stdio.h>
+#include <sstream>
+
+std::set<MotorSafetyHelper*> MotorSafetyHelper::m_helperList;
+priority_recursive_mutex MotorSafetyHelper::m_listMutex;
+
+/**
+ * The constructor for a MotorSafetyHelper object.
+ * The helper object is constructed for every object that wants to implement the
+ * Motor
+ * Safety protocol. The helper object has the code to actually do the timing and
+ * call the
+ * motors Stop() method when the timeout expires. The motor object is expected
+ * to call the
+ * Feed() method whenever the motors value is updated.
+ * @param safeObject a pointer to the motor object implementing MotorSafety.
+ * This is used
+ * to call the Stop() method on the motor.
+ */
+MotorSafetyHelper::MotorSafetyHelper(MotorSafety *safeObject)
+    : m_safeObject(safeObject) {
+  m_enabled = false;
+  m_expiration = DEFAULT_SAFETY_EXPIRATION;
+  m_stopTime = Timer::GetFPGATimestamp();
+
+  std::lock_guard<priority_recursive_mutex> sync(m_listMutex);
+  m_helperList.insert(this);
+}
+
+MotorSafetyHelper::~MotorSafetyHelper() {
+  std::lock_guard<priority_recursive_mutex> sync(m_listMutex);
+  m_helperList.erase(this);
+}
+
+/**
+ * Feed the motor safety object.
+ * Resets the timer on this object that is used to do the timeouts.
+ */
+void MotorSafetyHelper::Feed() {
+  std::lock_guard<priority_recursive_mutex> sync(m_syncMutex);
+  m_stopTime = Timer::GetFPGATimestamp() + m_expiration;
+}
+
+/**
+ * Set the expiration time for the corresponding motor safety object.
+ * @param expirationTime The timeout value in seconds.
+ */
+void MotorSafetyHelper::SetExpiration(float expirationTime) {
+  std::lock_guard<priority_recursive_mutex> sync(m_syncMutex);
+  m_expiration = expirationTime;
+}
+
+/**
+ * Retrieve the timeout value for the corresponding motor safety object.
+ * @return the timeout value in seconds.
+ */
+float MotorSafetyHelper::GetExpiration() const {
+  std::lock_guard<priority_recursive_mutex> sync(m_syncMutex);
+  return m_expiration;
+}
+
+/**
+ * Determine if the motor is still operating or has timed out.
+ * @return a true value if the motor is still operating normally and hasn't
+ * timed out.
+ */
+bool MotorSafetyHelper::IsAlive() const {
+  std::lock_guard<priority_recursive_mutex> sync(m_syncMutex);
+  return !m_enabled || m_stopTime > Timer::GetFPGATimestamp();
+}
+
+/**
+ * Check if this motor has exceeded its timeout.
+ * This method is called periodically to determine if this motor has exceeded
+ * its timeout
+ * value. If it has, the stop method is called, and the motor is shut down until
+ * its value is
+ * updated again.
+ */
+void MotorSafetyHelper::Check()
+{
+	DriverStation &ds = DriverStation::GetInstance();
+	if (!m_enabled || ds.IsDisabled() || ds.IsTest()) return;
+
+  std::lock_guard<priority_recursive_mutex> sync(m_syncMutex);
+  if (m_stopTime < Timer::GetFPGATimestamp()) {
+    std::ostringstream desc;
+    m_safeObject->GetDescription(desc);
+    desc <<  "... Output not updated often enough.";
+    wpi_setWPIErrorWithContext(Timeout, desc.str().c_str());
+    m_safeObject->StopMotor();
+  }
+}
+
+/**
+ * Enable/disable motor safety for this device
+ * Turn on and off the motor safety option for this PWM object.
+ * @param enabled True if motor safety is enforced for this object
+ */
+void MotorSafetyHelper::SetSafetyEnabled(bool enabled) {
+  std::lock_guard<priority_recursive_mutex> sync(m_syncMutex);
+  m_enabled = enabled;
+}
+
+/**
+ * Return the state of the motor safety enabled flag
+ * Return if the motor safety is currently enabled for this devicce.
+ * @return True if motor safety is enforced for this device
+ */
+bool MotorSafetyHelper::IsSafetyEnabled() const {
+  std::lock_guard<priority_recursive_mutex> sync(m_syncMutex);
+  return m_enabled;
+}
+
+/**
+ * Check the motors to see if any have timed out.
+ * This static  method is called periodically to poll all the motors and stop
+ * any that have
+ * timed out.
+ */
+void MotorSafetyHelper::CheckMotors() {
+  std::lock_guard<priority_recursive_mutex> sync(m_listMutex);
+  for (auto elem : m_helperList) {
+    elem->Check();
+  }
+}
diff --git a/wpilibc/simulation/src/Notifier.cpp b/wpilibc/simulation/src/Notifier.cpp
new file mode 100644
index 0000000..25daaf0
--- /dev/null
+++ b/wpilibc/simulation/src/Notifier.cpp
@@ -0,0 +1,261 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Notifier.h"
+#include "Timer.h"
+#include "Utility.h"
+#include "WPIErrors.h"
+
+Notifier *Notifier::timerQueueHead = nullptr;
+priority_recursive_mutex Notifier::queueMutex;
+std::atomic<int> Notifier::refcount{0};
+std::thread Notifier::m_task;
+std::atomic<bool> Notifier::m_stopped(false);
+
+/**
+ * Create a Notifier for timer event notification.
+ * @param handler The handler is called at the notification time which is set
+ * using StartSingle or StartPeriodic.
+ */
+Notifier::Notifier(TimerEventHandler handler, void *param)
+{
+	if (handler == nullptr)
+		wpi_setWPIErrorWithContext(NullParameter, "handler must not be nullptr");
+	m_handler = handler;
+	m_param = param;
+	m_periodic = false;
+	m_expirationTime = 0;
+	m_period = 0;
+	m_nextEvent = nullptr;
+	m_queued = false;
+	{
+		std::lock_guard<priority_recursive_mutex> sync(queueMutex);
+		// do the first time intialization of static variables
+		if (refcount.fetch_add(1) == 0) {
+			m_task = std::thread(Run);
+		}
+	}
+}
+
+/**
+ * Free the resources for a timer event.
+ * All resources will be freed and the timer event will be removed from the
+ * queue if necessary.
+ */
+Notifier::~Notifier()
+{
+	{
+		std::lock_guard<priority_recursive_mutex> sync(queueMutex);
+		DeleteFromQueue();
+
+		// Delete the static variables when the last one is going away
+		if (refcount.fetch_sub(1) == 1)
+		{
+      m_stopped = true;
+			m_task.join();
+		}
+	}
+
+	// Acquire the semaphore; this makes certain that the handler is
+	// not being executed by the interrupt manager.
+	std::lock_guard<priority_mutex> lock(m_handlerMutex);
+}
+
+/**
+ * Update the alarm hardware to reflect the current first element in the queue.
+ * Compute the time the next alarm should occur based on the current time and the
+ * period for the first element in the timer queue.
+ * WARNING: this method does not do synchronization! It must be called from somewhere
+ * that is taking care of synchronizing access to the queue.
+ */
+void Notifier::UpdateAlarm()
+{
+}
+
+/**
+ * ProcessQueue is called whenever there is a timer interrupt.
+ * We need to wake up and process the current top item in the timer queue as long
+ * as its scheduled time is after the current time. Then the item is removed or
+ * rescheduled (repetitive events) in the queue.
+ */
+void Notifier::ProcessQueue(uint32_t mask, void *params)
+{
+	Notifier *current;
+	while (true)				// keep processing past events until no more
+	{
+		{
+			std::lock_guard<priority_recursive_mutex> sync(queueMutex);
+			double currentTime = GetClock();
+			current = timerQueueHead;
+			if (current == nullptr || current->m_expirationTime > currentTime)
+			{
+				break;		// no more timer events to process
+			}
+			// need to process this entry
+			timerQueueHead = current->m_nextEvent;
+			if (current->m_periodic)
+			{
+				// if periodic, requeue the event
+				// compute when to put into queue
+				current->InsertInQueue(true);
+			}
+			else
+			{
+				// not periodic; removed from queue
+				current->m_queued = false;
+			}
+			// Take handler mutex while holding queue semaphore to make sure
+			//  the handler will execute to completion in case we are being deleted.
+			current->m_handlerMutex.lock();
+		}
+
+		current->m_handler(current->m_param);	// call the event handler
+		current->m_handlerMutex.unlock();
+	}
+	// reschedule the first item in the queue
+	std::lock_guard<priority_recursive_mutex> sync(queueMutex);
+	UpdateAlarm();
+}
+
+/**
+ * Insert this Notifier into the timer queue in right place.
+ * WARNING: this method does not do synchronization! It must be called from somewhere
+ * that is taking care of synchronizing access to the queue.
+ * @param reschedule If false, the scheduled alarm is based on the curent time and UpdateAlarm
+ * method is called which will enable the alarm if necessary.
+ * If true, update the time by adding the period (no drift) when rescheduled periodic from ProcessQueue.
+ * This ensures that the public methods only update the queue after finishing inserting.
+ */
+void Notifier::InsertInQueue(bool reschedule)
+{
+	if (reschedule)
+	{
+		m_expirationTime += m_period;
+	}
+	else
+	{
+		m_expirationTime = GetClock() + m_period;
+	}
+	if (timerQueueHead == nullptr || timerQueueHead->m_expirationTime >= this->m_expirationTime)
+	{
+		// the queue is empty or greater than the new entry
+		// the new entry becomes the first element
+		this->m_nextEvent = timerQueueHead;
+		timerQueueHead = this;
+		if (!reschedule)
+		{
+			// since the first element changed, update alarm, unless we already plan to
+			UpdateAlarm();
+		}
+	}
+	else
+	{
+		for (Notifier **npp = &(timerQueueHead->m_nextEvent); ; npp = &(*npp)->m_nextEvent)
+		{
+			Notifier *n = *npp;
+			if (n == nullptr || n->m_expirationTime > this->m_expirationTime)
+			{
+				*npp = this;
+				this->m_nextEvent = n;
+				break;
+			}
+		}
+	}
+	m_queued = true;
+}
+
+/**
+ * Delete this Notifier from the timer queue.
+ * WARNING: this method does not do synchronization! It must be called from somewhere
+ * that is taking care of synchronizing access to the queue.
+ * Remove this Notifier from the timer queue and adjust the next interrupt time to reflect
+ * the current top of the queue.
+ */
+void Notifier::DeleteFromQueue()
+{
+	if (m_queued)
+	{
+		m_queued = false;
+		wpi_assert(timerQueueHead != nullptr);
+		if (timerQueueHead == this)
+		{
+			// remove the first item in the list - update the alarm
+			timerQueueHead = this->m_nextEvent;
+			UpdateAlarm();
+		}
+		else
+		{
+			for (Notifier *n = timerQueueHead; n != nullptr; n = n->m_nextEvent)
+			{
+				if (n->m_nextEvent == this)
+				{
+					// this element is the next element from *n from the queue
+					n->m_nextEvent = this->m_nextEvent;	// point around this one
+				}
+			}
+		}
+	}
+}
+
+/**
+ * Register for single event notification.
+ * A timer event is queued for a single event after the specified delay.
+ * @param delay Seconds to wait before the handler is called.
+ */
+void Notifier::StartSingle(double delay)
+{
+	std::lock_guard<priority_recursive_mutex> sync(queueMutex);
+	m_periodic = false;
+	m_period = delay;
+	DeleteFromQueue();
+	InsertInQueue(false);
+}
+
+/**
+ * Register for periodic event notification.
+ * A timer event is queued for periodic event notification. Each time the interrupt
+ * occurs, the event will be immediately requeued for the same time interval.
+ * @param period Period in seconds to call the handler starting one period after the call to this method.
+ */
+void Notifier::StartPeriodic(double period)
+{
+	std::lock_guard<priority_recursive_mutex> sync(queueMutex);
+	m_periodic = true;
+	m_period = period;
+	DeleteFromQueue();
+	InsertInQueue(false);
+}
+
+/**
+ * Stop timer events from occuring.
+ * Stop any repeating timer events from occuring. This will also remove any single
+ * notification events from the queue.
+ * If a timer-based call to the registered handler is in progress, this function will
+ * block until the handler call is complete.
+ */
+void Notifier::Stop()
+{
+	{
+		std::lock_guard<priority_recursive_mutex> sync(queueMutex);
+		DeleteFromQueue();
+	}
+	// Wait for a currently executing handler to complete before returning from Stop()
+	std::lock_guard<priority_mutex> sync(m_handlerMutex);
+}
+
+void Notifier::Run() {
+    while (!m_stopped) {
+        Notifier::ProcessQueue(0, nullptr);
+        if (timerQueueHead != nullptr)
+        {
+            Wait(timerQueueHead->m_expirationTime - GetClock());
+        }
+        else
+        {
+            Wait(0.05);
+        }
+    }
+}
diff --git a/wpilibc/simulation/src/PIDController.cpp b/wpilibc/simulation/src/PIDController.cpp
new file mode 100644
index 0000000..03beb5c
--- /dev/null
+++ b/wpilibc/simulation/src/PIDController.cpp
@@ -0,0 +1,619 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "PIDController.h"
+#include "Notifier.h"
+#include "PIDSource.h"
+#include "PIDOutput.h"
+#include <math.h>
+
+static const std::string kP = "p";
+static const std::string kI = "i";
+static const std::string kD = "d";
+static const std::string kF = "f";
+static const std::string kSetpoint = "setpoint";
+static const std::string kEnabled = "enabled";
+
+
+/**
+ * Allocate a PID object with the given constants for P, I, D
+ * @param Kp the proportional coefficient
+ * @param Ki the integral coefficient
+ * @param Kd the derivative coefficient
+ * @param source The PIDSource object that is used to get values
+ * @param output The PIDOutput object that is set to the output value
+ * @param period the loop time for doing calculations. This particularly effects calculations of the
+ * integral and differental terms. The default is 50ms.
+ */
+PIDController::PIDController(float Kp, float Ki, float Kd,
+								PIDSource *source, PIDOutput *output,
+								float period)
+{
+	Initialize(Kp, Ki, Kd, 0.0f, source, output, period);
+}
+
+/**
+ * Allocate a PID object with the given constants for P, I, D
+ * @param Kp the proportional coefficient
+ * @param Ki the integral coefficient
+ * @param Kd the derivative coefficient
+ * @param source The PIDSource object that is used to get values
+ * @param output The PIDOutput object that is set to the output value
+ * @param period the loop time for doing calculations. This particularly effects calculations of the
+ * integral and differental terms. The default is 50ms.
+ */
+PIDController::PIDController(float Kp, float Ki, float Kd, float Kf,
+								PIDSource *source, PIDOutput *output,
+								float period)
+{
+	Initialize(Kp, Ki, Kd, Kf, source, output, period);
+}
+
+
+void PIDController::Initialize(float Kp, float Ki, float Kd, float Kf,
+								PIDSource *source, PIDOutput *output,
+								float period)
+{
+	m_table = nullptr;
+
+	m_P = Kp;
+	m_I = Ki;
+	m_D = Kd;
+	m_F = Kf;
+
+	m_maximumOutput = 1.0;
+	m_minimumOutput = -1.0;
+
+	m_maximumInput = 0;
+	m_minimumInput = 0;
+
+	m_continuous = false;
+	m_enabled = false;
+	m_setpoint = 0;
+
+	m_prevInput = 0;
+	m_totalError = 0;
+	m_tolerance = .05;
+
+	m_result = 0;
+
+	m_pidInput = source;
+	m_pidOutput = output;
+	m_period = period;
+
+	m_controlLoop = std::make_unique<Notifier>(PIDController::CallCalculate, this);
+	m_controlLoop->StartPeriodic(m_period);
+
+	static int32_t instances = 0;
+	instances++;
+
+	m_toleranceType = kNoTolerance;
+}
+
+PIDController::~PIDController() {
+	if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
+/**
+ * Call the Calculate method as a non-static method. This avoids having to prepend
+ * all local variables in that method with the class pointer. This way the "this"
+ * pointer will be set up and class variables can be called more easily.
+ * This method is static and called by the Notifier class.
+ * @param controller the address of the PID controller object to use in the background loop
+ */
+void PIDController::CallCalculate(void *controller)
+{
+	PIDController *control = (PIDController*) controller;
+	control->Calculate();
+}
+
+ /**
+  * Read the input, calculate the output accordingly, and write to the output.
+  * This should only be called by the Notifier indirectly through CallCalculate
+  * and is created during initialization.
+  */
+void PIDController::Calculate()
+{
+	bool enabled;
+	PIDSource *pidInput;
+
+	{
+		std::lock_guard<priority_mutex> lock(m_mutex);
+		if (m_pidInput == 0) return;
+		if (m_pidOutput == 0) return;
+		enabled = m_enabled;
+		pidInput = m_pidInput;
+	}
+
+	if (enabled)
+	{
+		float input = pidInput->PIDGet();
+		float result;
+		PIDOutput *pidOutput;
+
+		{
+			std::lock_guard<priority_mutex> sync(m_mutex);
+			m_error = m_setpoint - input;
+			if (m_continuous)
+			{
+				if (fabs(m_error) > (m_maximumInput - m_minimumInput) / 2)
+				{
+					if (m_error > 0)
+					{
+						m_error = m_error - m_maximumInput + m_minimumInput;
+					}
+					else
+					{
+						m_error = m_error + m_maximumInput - m_minimumInput;
+					}
+				}
+			}
+
+            if (m_pidInput->GetPIDSourceType() == PIDSourceType::kRate) {
+              if (m_P != 0) {
+                double potentialPGain = (m_totalError + m_error) * m_P;
+                if (potentialPGain < m_maximumOutput) {
+                  if (potentialPGain > m_minimumOutput) {
+                    m_totalError += m_error;
+                  }
+                  else {
+                    m_totalError = m_minimumOutput / m_P;
+                  }
+                }
+                else {
+                  m_totalError = m_maximumOutput / m_P;
+                }
+              }
+
+              m_result = m_D * m_error + m_P * m_totalError + m_setpoint * m_F;
+            }
+            else {
+              if (m_I != 0) {
+                double potentialIGain = (m_totalError + m_error) * m_I;
+                if (potentialIGain < m_maximumOutput) {
+                  if (potentialIGain > m_minimumOutput) {
+                    m_totalError += m_error;
+                  }
+                  else {
+                    m_totalError = m_minimumOutput / m_I;
+                  }
+                }
+                else {
+                  m_totalError = m_maximumOutput / m_I;
+                }
+              }
+
+              m_result = m_P * m_error + m_I * m_totalError + m_D * (m_prevInput - input) + m_setpoint * m_F;
+            }
+			m_prevInput = input;
+
+			if (m_result > m_maximumOutput) m_result = m_maximumOutput;
+			else if (m_result < m_minimumOutput) m_result = m_minimumOutput;
+
+			pidOutput = m_pidOutput;
+			result = m_result;
+		}
+
+		pidOutput->PIDWrite(result);
+	}
+}
+
+/**
+ * Set the PID Controller gain parameters.
+ * Set the proportional, integral, and differential coefficients.
+ * @param p Proportional coefficient
+ * @param i Integral coefficient
+ * @param d Differential coefficient
+ */
+void PIDController::SetPID(double p, double i, double d)
+{
+	{
+		std::lock_guard<priority_mutex> lock(m_mutex);
+		m_P = p;
+		m_I = i;
+		m_D = d;
+	}
+
+	if (m_table != nullptr) {
+		m_table->PutNumber("p", m_P);
+		m_table->PutNumber("i", m_I);
+		m_table->PutNumber("d", m_D);
+	}
+}
+
+/**
+ * Set the PID Controller gain parameters.
+ * Set the proportional, integral, and differential coefficients.
+ * @param p Proportional coefficient
+ * @param i Integral coefficient
+ * @param d Differential coefficient
+ * @param f Feed forward coefficient
+ */
+void PIDController::SetPID(double p, double i, double d, double f)
+{
+	{
+		std::lock_guard<priority_mutex> lock(m_mutex);
+		m_P = p;
+		m_I = i;
+		m_D = d;
+		m_F = f;
+	}
+
+	if (m_table != nullptr) {
+		m_table->PutNumber("p", m_P);
+		m_table->PutNumber("i", m_I);
+		m_table->PutNumber("d", m_D);
+		m_table->PutNumber("f", m_F);
+	}
+}
+
+/**
+ * Get the Proportional coefficient
+ * @return proportional coefficient
+ */
+double PIDController::GetP() const
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	return m_P;
+}
+
+/**
+ * Get the Integral coefficient
+ * @return integral coefficient
+ */
+double PIDController::GetI() const
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	return m_I;
+}
+
+/**
+ * Get the Differential coefficient
+ * @return differential coefficient
+ */
+double PIDController::GetD() const
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	return m_D;
+}
+
+/**
+ * Get the Feed forward coefficient
+ * @return Feed forward coefficient
+ */
+double PIDController::GetF() const
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	return m_F;
+}
+
+/**
+ * Return the current PID result
+ * This is always centered on zero and constrained the the max and min outs
+ * @return the latest calculated output
+ */
+float PIDController::Get() const
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	return m_result;
+}
+
+/**
+ *  Set the PID controller to consider the input to be continuous,
+ *  Rather then using the max and min in as constraints, it considers them to
+ *  be the same point and automatically calculates the shortest route to
+ *  the setpoint.
+ * @param continuous Set to true turns on continuous, false turns off continuous
+ */
+void PIDController::SetContinuous(bool continuous)
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	m_continuous = continuous;
+}
+
+/**
+ * Sets the maximum and minimum values expected from the input.
+ *
+ * @param minimumInput the minimum value expected from the input
+ * @param maximumInput the maximum value expected from the output
+ */
+void PIDController::SetInputRange(float minimumInput, float maximumInput)
+{
+	{
+		std::lock_guard<priority_mutex> lock(m_mutex);
+		m_minimumInput = minimumInput;
+		m_maximumInput = maximumInput;
+	}
+
+	SetSetpoint(m_setpoint);
+}
+
+/**
+ * Sets the minimum and maximum values to write.
+ *
+ * @param minimumOutput the minimum value to write to the output
+ * @param maximumOutput the maximum value to write to the output
+ */
+void PIDController::SetOutputRange(float minimumOutput, float maximumOutput)
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	m_minimumOutput = minimumOutput;
+	m_maximumOutput = maximumOutput;
+}
+
+/**
+ * Set the setpoint for the PIDController
+ * @param setpoint the desired setpoint
+ */
+void PIDController::SetSetpoint(float setpoint)
+{
+	{
+		std::lock_guard<priority_mutex> lock(m_mutex);
+		if (m_maximumInput > m_minimumInput)
+		{
+			if (setpoint > m_maximumInput)
+				m_setpoint = m_maximumInput;
+			else if (setpoint < m_minimumInput)
+				m_setpoint = m_minimumInput;
+			else
+				m_setpoint = setpoint;
+		}
+		else
+		{
+			m_setpoint = setpoint;
+		}
+	}
+
+	if (m_table != nullptr) {
+		m_table->PutNumber("setpoint", m_setpoint);
+	}
+}
+
+/**
+ * Returns the current setpoint of the PIDController
+ * @return the current setpoint
+ */
+double PIDController::GetSetpoint() const
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	return m_setpoint;
+}
+
+/**
+ * Retruns the current difference of the input from the setpoint
+ * @return the current error
+ */
+float PIDController::GetError() const
+{
+	double pidInput;
+	{
+		std::lock_guard<priority_mutex> lock(m_mutex);
+		pidInput = m_pidInput->PIDGet();
+	}
+	return GetSetpoint() - pidInput;
+}
+
+/**
+ * Sets what type of input the PID controller will use
+ */
+void PIDController::SetPIDSourceType(PIDSourceType pidSource) {
+  m_pidInput->SetPIDSourceType(pidSource);
+}
+
+/**
+ * Returns the type of input the PID controller is using
+ * @return the PID controller input type
+ */
+PIDSourceType PIDController::GetPIDSourceType() const {
+  return m_pidInput->GetPIDSourceType();
+}
+
+/**
+ * Returns the current average of the error over the past few iterations.
+ * You can specify the number of iterations to average with SetToleranceBuffer()
+ * (defaults to 1). This is the same value that is used for OnTarget().
+ * @return the average error
+ */
+float PIDController::GetAvgError() const {
+  float avgError = 0;
+  {
+    std::lock_guard<priority_mutex> sync(m_mutex);
+    // Don't divide by zero.
+    if (m_buf.size()) avgError = m_bufTotal / m_buf.size();
+  }
+  return avgError;
+}
+
+/*
+ * Set the percentage error which is considered tolerable for use with
+ * OnTarget.
+ * @param percentage error which is tolerable
+ */
+void PIDController::SetTolerance(float percent)
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	m_toleranceType = kPercentTolerance;
+	m_tolerance = percent;
+}
+
+/*
+ * Set the percentage error which is considered tolerable for use with
+ * OnTarget.
+ * @param percentage error which is tolerable
+ */
+void PIDController::SetPercentTolerance(float percent)
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	m_toleranceType = kPercentTolerance;
+	m_tolerance = percent;
+}
+
+/*
+ * Set the absolute error which is considered tolerable for use with
+ * OnTarget.
+ * @param percentage error which is tolerable
+ */
+void PIDController::SetAbsoluteTolerance(float absTolerance)
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	m_toleranceType = kAbsoluteTolerance;
+	m_tolerance = absTolerance;
+}
+
+/*
+ * Set the number of previous error samples to average for tolerancing. When
+ * determining whether a mechanism is on target, the user may want to use a
+ * rolling average of previous measurements instead of a precise position or
+ * velocity. This is useful for noisy sensors which return a few erroneous
+ * measurements when the mechanism is on target. However, the mechanism will
+ * not register as on target for at least the specified bufLength cycles.
+ * @param bufLength Number of previous cycles to average. Defaults to 1.
+ */
+void PIDController::SetToleranceBuffer(unsigned bufLength) {
+  m_bufLength = bufLength;
+
+  // Cut the buffer down to size if needed.
+  while (m_buf.size() > bufLength) {
+    m_bufTotal -= m_buf.front();
+    m_buf.pop();
+  }
+}
+
+/*
+ * Return true if the error is within the percentage of the total input range,
+ * determined by SetTolerance. This asssumes that the maximum and minimum input
+ * were set using SetInput.
+ * Currently this just reports on target as the actual value passes through the setpoint.
+ * Ideally it should be based on being within the tolerance for some period of time.
+ */
+bool PIDController::OnTarget() const
+{
+	double error = GetError();
+
+	std::lock_guard<priority_mutex> sync(m_mutex);
+	switch (m_toleranceType) {
+	case kPercentTolerance:
+		return fabs(error) < m_tolerance / 100 * (m_maximumInput - m_minimumInput);
+		break;
+	case kAbsoluteTolerance:
+		return fabs(error) < m_tolerance;
+		break;
+	case kNoTolerance: // TODO: this case needs an error
+		return false;
+	}
+	return false;
+}
+
+/**
+ * Begin running the PIDController
+ */
+void PIDController::Enable()
+{
+	{
+		std::lock_guard<priority_mutex> lock(m_mutex);
+		m_enabled = true;
+	}
+
+	if (m_table != nullptr) {
+		m_table->PutBoolean("enabled", true);
+	}
+}
+
+/**
+ * Stop running the PIDController, this sets the output to zero before stopping.
+ */
+void PIDController::Disable()
+{
+	{
+		std::lock_guard<priority_mutex> lock(m_mutex);
+		m_pidOutput->PIDWrite(0);
+		m_enabled = false;
+	}
+
+	if (m_table != nullptr) {
+		m_table->PutBoolean("enabled", false);
+	}
+}
+
+/**
+ * Return true if PIDController is enabled.
+ */
+bool PIDController::IsEnabled() const
+{
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	return m_enabled;
+}
+
+/**
+ * Reset the previous error,, the integral term, and disable the controller.
+ */
+void PIDController::Reset()
+{
+	Disable();
+
+	std::lock_guard<priority_mutex> lock(m_mutex);
+	m_prevInput = 0;
+	m_totalError = 0;
+	m_result = 0;
+}
+
+std::string PIDController::GetSmartDashboardType() const {
+	return "PIDController";
+}
+
+void PIDController::InitTable(std::shared_ptr<ITable> table){
+	if(m_table!=nullptr)
+		m_table->RemoveTableListener(this);
+	m_table = table;
+	if(m_table!=nullptr){
+		m_table->PutNumber(kP, GetP());
+		m_table->PutNumber(kI, GetI());
+		m_table->PutNumber(kD, GetD());
+		m_table->PutNumber(kF, GetF());
+		m_table->PutNumber(kSetpoint, GetSetpoint());
+		m_table->PutBoolean(kEnabled, IsEnabled());
+		m_table->AddTableListener(this, false);
+	}
+}
+
+std::shared_ptr<ITable> PIDController::GetTable() const {
+	return m_table;
+}
+
+void PIDController::ValueChanged(ITable* source, llvm::StringRef key,
+                                 std::shared_ptr<nt::Value> value, bool isNew) {
+  if (key == kP || key == kI || key == kD || key == kF) {
+    if (m_P != m_table->GetNumber(kP, 0.0) ||
+        m_I != m_table->GetNumber(kI, 0.0) ||
+        m_D != m_table->GetNumber(kD, 0.0) ||
+        m_F != m_table->GetNumber(kF, 0.0)) {
+      SetPID(m_table->GetNumber(kP, 0.0), m_table->GetNumber(kI, 0.0),
+             m_table->GetNumber(kD, 0.0), m_table->GetNumber(kF, 0.0));
+    }
+  } else if (key == kSetpoint && value->IsDouble() &&
+             m_setpoint != value->GetDouble()) {
+    SetSetpoint(value->GetDouble());
+  } else if (key == kEnabled && value->IsBoolean() &&
+             m_enabled != value->GetBoolean()) {
+    if (value->GetBoolean()) {
+      Enable();
+    } else {
+      Disable();
+    }
+  }
+}
+
+void PIDController::UpdateTable() {
+
+}
+
+void PIDController::StartLiveWindowMode() {
+	Disable();
+}
+
+void PIDController::StopLiveWindowMode() {
+
+}
diff --git a/wpilibc/simulation/src/PWM.cpp b/wpilibc/simulation/src/PWM.cpp
new file mode 100644
index 0000000..dfb8bd9
--- /dev/null
+++ b/wpilibc/simulation/src/PWM.cpp
@@ -0,0 +1,261 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "PWM.h"
+
+//#include "NetworkCommunication/UsageReporting.h"
+#include "Utility.h"
+#include "WPIErrors.h"
+
+const float PWM::kDefaultPwmPeriod = 5.05;
+const float PWM::kDefaultPwmCenter = 1.5;
+const int32_t PWM::kDefaultPwmStepsDown = 1000;
+const int32_t PWM::kPwmDisabled = 0;
+
+/**
+ * Allocate a PWM given a channel number.
+ *
+ * Checks channel value range and allocates the appropriate channel.
+ * The allocation is only done to help users ensure that they don't double
+ * assign channels.
+ * @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the MXP
+ * port
+ */
+PWM::PWM(uint32_t channel)
+{
+	char buf[64];
+
+	if (!CheckPWMChannel(channel))
+	{
+		snprintf(buf, 64, "PWM Channel %d", channel);
+		wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf);
+		return;
+	}
+
+	sprintf(buf, "pwm/%d", channel);
+	impl = new SimContinuousOutput(buf);
+	m_channel = channel;
+	m_eliminateDeadband = false;
+
+	m_centerPwm = kPwmDisabled; // In simulation, the same thing.
+}
+
+PWM::~PWM() {
+	if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
+/**
+ * Optionally eliminate the deadband from a speed controller.
+ * @param eliminateDeadband If true, set the motor curve on the Jaguar to eliminate
+ * the deadband in the middle of the range. Otherwise, keep the full range without
+ * modifying any values.
+ */
+void PWM::EnableDeadbandElimination(bool eliminateDeadband)
+{
+	m_eliminateDeadband = eliminateDeadband;
+}
+
+/**
+ * Set the bounds on the PWM values.
+ * This sets the bounds on the PWM values for a particular each type of controller. The values
+ * determine the upper and lower speeds as well as the deadband bracket.
+ * @param max The Minimum pwm value
+ * @param deadbandMax The high end of the deadband range
+ * @param center The center speed (off)
+ * @param deadbandMin The low end of the deadband range
+ * @param min The minimum pwm value
+ */
+void PWM::SetBounds(int32_t max, int32_t deadbandMax, int32_t center, int32_t deadbandMin, int32_t min)
+{
+	// Nothing to do in simulation.
+}
+
+
+/**
+ * Set the bounds on the PWM pulse widths.
+ * This sets the bounds on the PWM values for a particular type of controller. The values
+ * determine the upper and lower speeds as well as the deadband bracket.
+ * @param max The max PWM pulse width in ms
+ * @param deadbandMax The high end of the deadband range pulse width in ms
+ * @param center The center (off) pulse width in ms
+ * @param deadbandMin The low end of the deadband pulse width in ms
+ * @param min The minimum pulse width in ms
+ */
+void PWM::SetBounds(double max, double deadbandMax, double center, double deadbandMin, double min)
+{
+	// Nothing to do in simulation.
+}
+
+/**
+ * Set the PWM value based on a position.
+ *
+ * This is intended to be used by servos.
+ *
+ * @pre SetMaxPositivePwm() called.
+ * @pre SetMinNegativePwm() called.
+ *
+ * @param pos The position to set the servo between 0.0 and 1.0.
+ */
+void PWM::SetPosition(float pos)
+{
+	if (pos < 0.0)
+	{
+		pos = 0.0;
+	}
+	else if (pos > 1.0)
+	{
+		pos = 1.0;
+	}
+
+	impl->Set(pos);
+}
+
+/**
+ * Get the PWM value in terms of a position.
+ *
+ * This is intended to be used by servos.
+ *
+ * @pre SetMaxPositivePwm() called.
+ * @pre SetMinNegativePwm() called.
+ *
+ * @return The position the servo is set to between 0.0 and 1.0.
+ */
+float PWM::GetPosition() const
+{
+	float value = impl->Get();
+	if (value < 0.0)
+	{
+		return 0.0;
+	}
+	else if (value > 1.0)
+	{
+		return 1.0;
+	}
+	else
+	{
+		return value;
+	}
+}
+
+/**
+ * Set the PWM value based on a speed.
+ *
+ * This is intended to be used by speed controllers.
+ *
+ * @pre SetMaxPositivePwm() called.
+ * @pre SetMinPositivePwm() called.
+ * @pre SetCenterPwm() called.
+ * @pre SetMaxNegativePwm() called.
+ * @pre SetMinNegativePwm() called.
+ *
+ * @param speed The speed to set the speed controller between -1.0 and 1.0.
+ */
+void PWM::SetSpeed(float speed)
+{
+	// clamp speed to be in the range 1.0 >= speed >= -1.0
+	if (speed < -1.0)
+	{
+		speed = -1.0;
+	}
+	else if (speed > 1.0)
+	{
+		speed = 1.0;
+	}
+
+	impl->Set(speed);
+}
+
+/**
+ * Get the PWM value in terms of speed.
+ *
+ * This is intended to be used by speed controllers.
+ *
+ * @pre SetMaxPositivePwm() called.
+ * @pre SetMinPositivePwm() called.
+ * @pre SetMaxNegativePwm() called.
+ * @pre SetMinNegativePwm() called.
+ *
+ * @return The most recently set speed between -1.0 and 1.0.
+ */
+float PWM::GetSpeed() const
+{
+	float value = impl->Get();
+	if (value > 1.0)
+	{
+		return 1.0;
+	}
+	else if (value < -1.0)
+	{
+		return -1.0;
+	}
+	else
+	{
+		return value;
+	}
+}
+
+/**
+ * Set the PWM value directly to the hardware.
+ *
+ * Write a raw value to a PWM channel.
+ *
+ * @param value Raw PWM value.
+ */
+void PWM::SetRaw(unsigned short value)
+{
+	wpi_assert(value == kPwmDisabled);
+	impl->Set(0);
+}
+
+/**
+ * Slow down the PWM signal for old devices.
+ *
+ * @param mult The period multiplier to apply to this channel
+ */
+void PWM::SetPeriodMultiplier(PeriodMultiplier mult)
+{
+	// Do nothing in simulation.
+}
+
+
+void PWM::ValueChanged(ITable* source, llvm::StringRef key,
+                       std::shared_ptr<nt::Value> value, bool isNew) {
+  if (!value->IsDouble()) return;
+  SetSpeed(value->GetDouble());
+}
+
+void PWM::UpdateTable() {
+	if (m_table != nullptr) {
+		m_table->PutNumber("Value", GetSpeed());
+	}
+}
+
+void PWM::StartLiveWindowMode() {
+	SetSpeed(0);
+	if (m_table != nullptr) {
+		m_table->AddTableListener("Value", this, true);
+	}
+}
+
+void PWM::StopLiveWindowMode() {
+	SetSpeed(0);
+	if (m_table != nullptr) {
+		m_table->RemoveTableListener(this);
+	}
+}
+
+std::string PWM::GetSmartDashboardType() const {
+	return "Speed Controller";
+}
+
+void PWM::InitTable(std::shared_ptr<ITable> subTable) {
+	m_table = subTable;
+	UpdateTable();
+}
+
+std::shared_ptr<ITable> PWM::GetTable() const {
+	return m_table;
+}
diff --git a/wpilibc/simulation/src/Relay.cpp b/wpilibc/simulation/src/Relay.cpp
new file mode 100644
index 0000000..f35d782
--- /dev/null
+++ b/wpilibc/simulation/src/Relay.cpp
@@ -0,0 +1,249 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Relay.h"
+
+#include "MotorSafetyHelper.h"
+//#include "NetworkCommunication/UsageReporting.h"
+#include "WPIErrors.h"
+#include "LiveWindow/LiveWindow.h"
+
+/**
+ * Relay constructor given a channel.
+ *
+ * This code initializes the relay and reserves all resources that need to be
+ * locked. Initially the relay is set to both lines at 0v.
+ * @param channel The channel number (0-3).
+ * @param direction The direction that the Relay object will control.
+ */
+Relay::Relay(uint32_t channel, Relay::Direction direction)
+	: m_channel (channel)
+	, m_direction (direction)
+{
+	char buf[64];
+	if (!SensorBase::CheckRelayChannel(m_channel))
+	{
+		snprintf(buf, 64, "Relay Channel %d", m_channel);
+		wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf);
+		return;
+	}
+
+    m_safetyHelper = std::make_unique<MotorSafetyHelper>(this);
+    m_safetyHelper->SetSafetyEnabled(false);
+
+	sprintf(buf, "relay/%d", m_channel);
+	impl = new SimContinuousOutput(buf); // TODO: Allow two different relays (targetting the different halves of a relay) to be combined to control one motor.
+	LiveWindow::GetInstance()->AddActuator("Relay", 1, m_channel, this);
+	go_pos = go_neg = false;
+}
+
+/**
+ * Free the resource associated with a relay.
+ * The relay channels are set to free and the relay output is turned off.
+ */
+Relay::~Relay()
+{
+	impl->Set(0);
+	if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
+/**
+ * Set the relay state.
+ *
+ * Valid values depend on which directions of the relay are controlled by the object.
+ *
+ * When set to kBothDirections, the relay can be any of the four states:
+ *    0v-0v, 0v-12v, 12v-0v, 12v-12v
+ *
+ * When set to kForwardOnly or kReverseOnly, you can specify the constant for the
+ *    direction or you can simply specify kOff and kOn.  Using only kOff and kOn is
+ *    recommended.
+ *
+ * @param value The state to set the relay.
+ */
+void Relay::Set(Relay::Value value)
+{
+	switch (value)
+	{
+	case kOff:
+		if (m_direction == kBothDirections || m_direction == kForwardOnly)
+		{
+			go_pos = false;
+		}
+		if (m_direction == kBothDirections || m_direction == kReverseOnly)
+		{
+			go_neg = false;
+		}
+		break;
+	case kOn:
+		if (m_direction == kBothDirections || m_direction == kForwardOnly)
+		{
+			go_pos = true;
+		}
+		if (m_direction == kBothDirections || m_direction == kReverseOnly)
+		{
+			go_neg = true;
+		}
+		break;
+	case kForward:
+		if (m_direction == kReverseOnly)
+		{
+			wpi_setWPIError(IncompatibleMode);
+			break;
+		}
+		if (m_direction == kBothDirections || m_direction == kForwardOnly)
+		{
+			go_pos = true;
+		}
+		if (m_direction == kBothDirections)
+		{
+			go_neg = false;
+		}
+		break;
+	case kReverse:
+		if (m_direction == kForwardOnly)
+		{
+			wpi_setWPIError(IncompatibleMode);
+			break;
+		}
+		if (m_direction == kBothDirections)
+		{
+			go_pos = false;
+		}
+		if (m_direction == kBothDirections || m_direction == kReverseOnly)
+		{
+			go_neg = true;
+		}
+		break;
+	}
+	impl->Set((go_pos ? 1 : 0) + (go_neg ? -1 : 0));
+}
+
+/**
+ * Get the Relay State
+ *
+ * Gets the current state of the relay.
+ *
+ * When set to kForwardOnly or kReverseOnly, value is returned as kOn/kOff not
+ * kForward/kReverse (per the recommendation in Set)
+ *
+ * @return The current state of the relay as a Relay::Value
+ */
+Relay::Value Relay::Get() const {
+	// TODO: Don't assume that the go_pos and go_neg fields are correct?
+	if ((go_pos || m_direction == kReverseOnly) && (go_neg || m_direction == kForwardOnly)) {
+		return kOn;
+	} else if (go_pos) {
+		return kForward;
+	} else if (go_neg) {
+		return kReverse;
+	} else {
+		return kOff;
+	}
+}
+
+uint32_t Relay::GetChannel() const {
+  return m_channel;
+}
+
+/**
+ * Set the expiration time for the Relay object
+ * @param timeout The timeout (in seconds) for this relay object
+ */
+void Relay::SetExpiration(float timeout) {
+  m_safetyHelper->SetExpiration(timeout);
+}
+
+/**
+ * Return the expiration time for the relay object.
+ * @return The expiration time value.
+ */
+float Relay::GetExpiration() const { return m_safetyHelper->GetExpiration(); }
+
+/**
+ * Check if the relay object is currently alive or stopped due to a timeout.
+ * @returns a bool value that is true if the motor has NOT timed out and should
+ * still be running.
+ */
+bool Relay::IsAlive() const { return m_safetyHelper->IsAlive(); }
+
+/**
+ * Stop the motor associated with this PWM object.
+ * This is called by the MotorSafetyHelper object when it has a timeout for this
+ * relay and needs to stop it from running.
+ */
+void Relay::StopMotor() { Set(kOff); }
+
+/**
+ * Enable/disable motor safety for this device
+ * Turn on and off the motor safety option for this relay object.
+ * @param enabled True if motor safety is enforced for this object
+ */
+void Relay::SetSafetyEnabled(bool enabled) {
+  m_safetyHelper->SetSafetyEnabled(enabled);
+}
+
+/**
+ * Check if motor safety is enabled for this object
+ * @returns True if motor safety is enforced for this object
+ */
+bool Relay::IsSafetyEnabled() const {
+  return m_safetyHelper->IsSafetyEnabled();
+}
+
+void Relay::GetDescription(std::ostringstream& desc) const {
+  desc << "Relay " << GetChannel();
+}
+
+void Relay::ValueChanged(ITable* source, llvm::StringRef key,
+                         std::shared_ptr<nt::Value> value, bool isNew) {
+  if (!value->IsString()) return;
+  if (value->GetString() == "Off") Set(kOff);
+  else if (value->GetString() == "Forward") Set(kForward);
+  else if (value->GetString() == "Reverse") Set(kReverse);
+}
+
+void Relay::UpdateTable() {
+	if(m_table != nullptr){
+		if (Get() == kOn) {
+			m_table->PutString("Value", "On");
+		}
+		else if (Get() == kForward) {
+			m_table->PutString("Value", "Forward");
+		}
+		else if (Get() == kReverse) {
+			m_table->PutString("Value", "Reverse");
+		}
+		else {
+			m_table->PutString("Value", "Off");
+		}
+	}
+}
+
+void Relay::StartLiveWindowMode() {
+	if(m_table != nullptr){
+		m_table->AddTableListener("Value", this, true);
+	}
+}
+
+void Relay::StopLiveWindowMode() {
+	if(m_table != nullptr){
+		m_table->RemoveTableListener(this);
+	}
+}
+
+std::string Relay::GetSmartDashboardType() const {
+	return "Relay";
+}
+
+void Relay::InitTable(std::shared_ptr<ITable> subTable) {
+	m_table = subTable;
+	UpdateTable();
+}
+
+std::shared_ptr<ITable> Relay::GetTable() const {
+	return m_table;
+}
diff --git a/wpilibc/simulation/src/RobotBase.cpp b/wpilibc/simulation/src/RobotBase.cpp
new file mode 100644
index 0000000..1fa5ac7
--- /dev/null
+++ b/wpilibc/simulation/src/RobotBase.cpp
@@ -0,0 +1,99 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "RobotBase.h"
+#include "RobotState.h"
+#include "Utility.h"
+
+#include <cstring>
+
+RobotBase* RobotBase::m_instance = nullptr;
+
+void RobotBase::setInstance(RobotBase* robot)
+{
+	wpi_assert(m_instance == nullptr);
+	m_instance = robot;
+}
+
+RobotBase &RobotBase::getInstance()
+{
+	return *m_instance;
+}
+
+/**
+ * Constructor for a generic robot program.
+ * User code should be placed in the constuctor that runs before the Autonomous or Operator
+ * Control period starts. The constructor will run to completion before Autonomous is entered.
+ *
+ * This must be used to ensure that the communications code starts. In the future it would be
+ * nice to put this code into it's own task that loads on boot so ensure that it runs.
+ */
+RobotBase::RobotBase() : m_ds(DriverStation::GetInstance())
+{
+	RobotState::SetImplementation(DriverStation::GetInstance());
+	transport::SubscriberPtr time_pub = MainNode::Subscribe("time", &wpilib::internal::time_callback);
+}
+
+/**
+ * Determine if the Robot is currently enabled.
+ * @return True if the Robot is currently enabled by the field controls.
+ */
+bool RobotBase::IsEnabled() const
+{
+	return m_ds.IsEnabled();
+}
+
+/**
+ * Determine if the Robot is currently disabled.
+ * @return True if the Robot is currently disabled by the field controls.
+ */
+bool RobotBase::IsDisabled() const
+{
+	return m_ds.IsDisabled();
+}
+
+/**
+ * Determine if the robot is currently in Autnomous mode.
+ * @return True if the robot is currently operating Autonomously as determined by the field controls.
+ */
+bool RobotBase::IsAutonomous() const
+{
+	return m_ds.IsAutonomous();
+}
+
+/**
+ * Determine if the robot is currently in Operator Control mode.
+ * @return True if the robot is currently operating in Tele-Op mode as determined by the field controls.
+ */
+bool RobotBase::IsOperatorControl() const
+{
+	return m_ds.IsOperatorControl();
+}
+
+/**
+ * Determine if the robot is currently in Test mode.
+ * @return True if the robot is currently running tests as determined by the field controls.
+ */
+bool RobotBase::IsTest() const
+{
+    return m_ds.IsTest();
+}
+
+/**
+ * This class exists for the sole purpose of getting its destructor called when the module unloads.
+ * Before the module is done unloading, we need to delete the RobotBase derived singleton.  This should delete
+ * the other remaining singletons that were registered.  This should also stop all tasks that are using
+ * the Task class.
+ */
+class RobotDeleter
+{
+public:
+	~RobotDeleter()
+	{
+		delete &RobotBase::getInstance();
+	}
+};
+static RobotDeleter g_robotDeleter;
diff --git a/wpilibc/simulation/src/RobotDrive.cpp b/wpilibc/simulation/src/RobotDrive.cpp
new file mode 100644
index 0000000..852d0bf
--- /dev/null
+++ b/wpilibc/simulation/src/RobotDrive.cpp
@@ -0,0 +1,734 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "RobotDrive.h"
+
+//#include "CANJaguar.h"
+#include "GenericHID.h"
+#include "Joystick.h"
+#include "Jaguar.h"
+#include "Utility.h"
+#include "WPIErrors.h"
+#include <math.h>
+
+#undef max
+#include <algorithm>
+
+const int32_t RobotDrive::kMaxNumberOfMotors;
+
+/*
+ * Driving functions
+ * These functions provide an interface to multiple motors that is used for C programming
+ * The Drive(speed, direction) function is the main part of the set that makes it easy
+ * to set speeds and direction independently in one call.
+ */
+
+/**
+ * Common function to initialize all the robot drive constructors.
+ * Create a motor safety object (the real reason for the common code) and
+ * initialize all the motor assignments. The default timeout is set for the robot drive.
+ */
+void RobotDrive::InitRobotDrive() {
+	// FIXME: m_safetyHelper = new MotorSafetyHelper(this);
+	// FIXME: m_safetyHelper->SetSafetyEnabled(true);
+}
+
+/** Constructor for RobotDrive with 2 motors specified with channel numbers.
+ * Set up parameters for a two wheel drive system where the
+ * left and right motor pwm channels are specified in the call.
+ * This call assumes Jaguars for controlling the motors.
+ * @param leftMotorChannel The PWM channel number that drives the left motor.
+ * @param rightMotorChannel The PWM channel number that drives the right motor.
+ */
+RobotDrive::RobotDrive(uint32_t leftMotorChannel, uint32_t rightMotorChannel)
+{
+	InitRobotDrive();
+	m_rearLeftMotor = new Jaguar(leftMotorChannel);
+	m_rearRightMotor = new Jaguar(rightMotorChannel);
+	for (int32_t i=0; i < kMaxNumberOfMotors; i++)
+	{
+		m_invertedMotors[i] = 1;
+	}
+	SetLeftRightMotorOutputs(0.0, 0.0);
+	m_deleteSpeedControllers = true;
+}
+
+/**
+ * Constructor for RobotDrive with 4 motors specified with channel numbers.
+ * Set up parameters for a four wheel drive system where all four motor
+ * pwm channels are specified in the call.
+ * This call assumes Jaguars for controlling the motors.
+ * @param frontLeftMotor Front left motor channel number
+ * @param rearLeftMotor Rear Left motor channel number
+ * @param frontRightMotor Front right motor channel number
+ * @param rearRightMotor Rear Right motor channel number
+ */
+RobotDrive::RobotDrive(uint32_t frontLeftMotor, uint32_t rearLeftMotor,
+		uint32_t frontRightMotor, uint32_t rearRightMotor)
+{
+	InitRobotDrive();
+	m_rearLeftMotor = new Jaguar(rearLeftMotor);
+	m_rearRightMotor = new Jaguar(rearRightMotor);
+	m_frontLeftMotor = new Jaguar(frontLeftMotor);
+	m_frontRightMotor = new Jaguar(frontRightMotor);
+	for (int32_t i=0; i < kMaxNumberOfMotors; i++)
+	{
+		m_invertedMotors[i] = 1;
+	}
+	SetLeftRightMotorOutputs(0.0, 0.0);
+	m_deleteSpeedControllers = true;
+}
+
+/**
+ * Constructor for RobotDrive with 2 motors specified as SpeedController objects.
+ * The SpeedController version of the constructor enables programs to use the RobotDrive classes with
+ * subclasses of the SpeedController objects, for example, versions with ramping or reshaping of
+ * the curve to suit motor bias or deadband elimination.
+ * @param leftMotor The left SpeedController object used to drive the robot.
+ * @param rightMotor the right SpeedController object used to drive the robot.
+ */
+RobotDrive::RobotDrive(SpeedController *leftMotor, SpeedController *rightMotor)
+{
+	InitRobotDrive();
+	if (leftMotor == nullptr || rightMotor == nullptr)
+	{
+		wpi_setWPIError(NullParameter);
+		m_rearLeftMotor = m_rearRightMotor = nullptr;
+		return;
+	}
+	m_rearLeftMotor = leftMotor;
+	m_rearRightMotor = rightMotor;
+	for (int32_t i=0; i < kMaxNumberOfMotors; i++)
+	{
+		m_invertedMotors[i] = 1;
+	}
+	m_deleteSpeedControllers = false;
+}
+
+RobotDrive::RobotDrive(SpeedController &leftMotor, SpeedController &rightMotor)
+{
+	InitRobotDrive();
+	m_rearLeftMotor = &leftMotor;
+	m_rearRightMotor = &rightMotor;
+	for (int32_t i=0; i < kMaxNumberOfMotors; i++)
+	{
+		m_invertedMotors[i] = 1;
+	}
+	m_deleteSpeedControllers = false;
+}
+
+/**
+ * Constructor for RobotDrive with 4 motors specified as SpeedController objects.
+ * Speed controller input version of RobotDrive (see previous comments).
+ * @param rearLeftMotor The back left SpeedController object used to drive the robot.
+ * @param frontLeftMotor The front left SpeedController object used to drive the robot
+ * @param rearRightMotor The back right SpeedController object used to drive the robot.
+ * @param frontRightMotor The front right SpeedController object used to drive the robot.
+ */
+RobotDrive::RobotDrive(SpeedController *frontLeftMotor, SpeedController *rearLeftMotor,
+						SpeedController *frontRightMotor, SpeedController *rearRightMotor)
+{
+	InitRobotDrive();
+	if (frontLeftMotor == nullptr || rearLeftMotor == nullptr || frontRightMotor == nullptr || rearRightMotor == nullptr)
+	{
+		wpi_setWPIError(NullParameter);
+		return;
+	}
+	m_frontLeftMotor = frontLeftMotor;
+	m_rearLeftMotor = rearLeftMotor;
+	m_frontRightMotor = frontRightMotor;
+	m_rearRightMotor = rearRightMotor;
+	for (int32_t i=0; i < kMaxNumberOfMotors; i++)
+	{
+		m_invertedMotors[i] = 1;
+	}
+	m_deleteSpeedControllers = false;
+}
+
+RobotDrive::RobotDrive(SpeedController &frontLeftMotor, SpeedController &rearLeftMotor,
+						SpeedController &frontRightMotor, SpeedController &rearRightMotor)
+{
+	InitRobotDrive();
+	m_frontLeftMotor = &frontLeftMotor;
+	m_rearLeftMotor = &rearLeftMotor;
+	m_frontRightMotor = &frontRightMotor;
+	m_rearRightMotor = &rearRightMotor;
+	for (int32_t i=0; i < kMaxNumberOfMotors; i++)
+	{
+		m_invertedMotors[i] = 1;
+	}
+	m_deleteSpeedControllers = false;
+}
+
+/**
+ * RobotDrive destructor.
+ * Deletes motor objects that were not passed in and created internally only.
+ **/
+RobotDrive::~RobotDrive()
+{
+	if (m_deleteSpeedControllers)
+	{
+		delete m_frontLeftMotor;
+		delete m_rearLeftMotor;
+		delete m_frontRightMotor;
+		delete m_rearRightMotor;
+	}
+	// FIXME: delete m_safetyHelper;
+}
+
+/**
+ * Drive the motors at "outputMagnitude" and "curve".
+ * Both outputMagnitude and curve are -1.0 to +1.0 values, where 0.0 represents
+ * stopped and not turning. curve < 0 will turn left and curve > 0 will turn
+ * right.
+ *
+ * The algorithm for steering provides a constant turn radius for any normal
+ * speed range, both forward and backward. Increasing m_sensitivity causes
+ * sharper turns for fixed values of curve.
+ *
+ * This function will most likely be used in an autonomous routine.
+ *
+ * @param outputMagnitude The speed setting for the outside wheel in a turn,
+ *        forward or backwards, +1 to -1.
+ * @param curve The rate of turn, constant for different forward speeds. Set
+ *        curve < 0 for left turn or curve > 0 for right turn.
+ * Set curve = e^(-r/w) to get a turn radius r for wheelbase w of your robot.
+ * Conversely, turn radius r = -ln(curve)*w for a given value of curve and
+ * wheelbase w.
+ */
+void RobotDrive::Drive(float outputMagnitude, float curve)
+{
+	float leftOutput, rightOutput;
+	static bool reported = false;
+	if (!reported)
+	{
+		reported = true;
+	}
+
+	if (curve < 0)
+	{
+		float value = log(-curve);
+		float ratio = (value - m_sensitivity)/(value + m_sensitivity);
+		if (ratio == 0) ratio =.0000000001;
+		leftOutput = outputMagnitude / ratio;
+		rightOutput = outputMagnitude;
+	}
+	else if (curve > 0)
+	{
+		float value = log(curve);
+		float ratio = (value - m_sensitivity)/(value + m_sensitivity);
+		if (ratio == 0) ratio =.0000000001;
+		leftOutput = outputMagnitude;
+		rightOutput = outputMagnitude / ratio;
+	}
+	else
+	{
+		leftOutput = outputMagnitude;
+		rightOutput = outputMagnitude;
+	}
+	SetLeftRightMotorOutputs(leftOutput, rightOutput);
+}
+
+/**
+ * Provide tank steering using the stored robot configuration.
+ * Drive the robot using two joystick inputs. The Y-axis will be selected from
+ * each Joystick object.
+ * @param leftStick The joystick to control the left side of the robot.
+ * @param rightStick The joystick to control the right side of the robot.
+ */
+void RobotDrive::TankDrive(GenericHID *leftStick, GenericHID *rightStick, bool squaredInputs)
+{
+	if (leftStick == nullptr || rightStick == nullptr)
+	{
+		wpi_setWPIError(NullParameter);
+		return;
+	}
+	TankDrive(leftStick->GetY(), rightStick->GetY(), squaredInputs);
+}
+
+void RobotDrive::TankDrive(GenericHID &leftStick, GenericHID &rightStick, bool squaredInputs)
+{
+	TankDrive(leftStick.GetY(), rightStick.GetY(), squaredInputs);
+}
+
+/**
+ * Provide tank steering using the stored robot configuration.
+ * This function lets you pick the axis to be used on each Joystick object for the left
+ * and right sides of the robot.
+ * @param leftStick The Joystick object to use for the left side of the robot.
+ * @param leftAxis The axis to select on the left side Joystick object.
+ * @param rightStick The Joystick object to use for the right side of the robot.
+ * @param rightAxis The axis to select on the right side Joystick object.
+ */
+void RobotDrive::TankDrive(GenericHID *leftStick, uint32_t leftAxis,
+		GenericHID *rightStick, uint32_t rightAxis, bool squaredInputs)
+{
+	if (leftStick == nullptr || rightStick == nullptr)
+	{
+		wpi_setWPIError(NullParameter);
+		return;
+	}
+	TankDrive(leftStick->GetRawAxis(leftAxis), rightStick->GetRawAxis(rightAxis), squaredInputs);
+}
+
+void RobotDrive::TankDrive(GenericHID &leftStick, uint32_t leftAxis,
+		GenericHID &rightStick, uint32_t rightAxis, bool squaredInputs)
+{
+	TankDrive(leftStick.GetRawAxis(leftAxis), rightStick.GetRawAxis(rightAxis), squaredInputs);
+}
+
+
+/**
+ * Provide tank steering using the stored robot configuration.
+ * This function lets you directly provide joystick values from any source.
+ * @param leftValue The value of the left stick.
+ * @param rightValue The value of the right stick.
+ */
+void RobotDrive::TankDrive(float leftValue, float rightValue, bool squaredInputs)
+{
+	static bool reported = false;
+	if (!reported)
+	{
+		reported = true;
+	}
+
+	// square the inputs (while preserving the sign) to increase fine control while permitting full power
+	leftValue = Limit(leftValue);
+	rightValue = Limit(rightValue);
+	if(squaredInputs)
+	{
+		if (leftValue >= 0.0)
+		{
+			leftValue = (leftValue * leftValue);
+		}
+		else
+		{
+			leftValue = -(leftValue * leftValue);
+		}
+		if (rightValue >= 0.0)
+		{
+			rightValue = (rightValue * rightValue);
+		}
+		else
+		{
+			rightValue = -(rightValue * rightValue);
+		}
+	}
+
+	SetLeftRightMotorOutputs(leftValue, rightValue);
+}
+
+/**
+ * Arcade drive implements single stick driving.
+ * Given a single Joystick, the class assumes the Y axis for the move value and the X axis
+ * for the rotate value.
+ * (Should add more information here regarding the way that arcade drive works.)
+ * @param stick The joystick to use for Arcade single-stick driving. The Y-axis will be selected
+ * for forwards/backwards and the X-axis will be selected for rotation rate.
+ * @param squaredInputs If true, the sensitivity will be increased for small values
+ */
+void RobotDrive::ArcadeDrive(GenericHID *stick, bool squaredInputs)
+{
+	// simply call the full-featured ArcadeDrive with the appropriate values
+	ArcadeDrive(stick->GetY(), stick->GetX(), squaredInputs);
+}
+
+/**
+ * Arcade drive implements single stick driving.
+ * Given a single Joystick, the class assumes the Y axis for the move value and the X axis
+ * for the rotate value.
+ * (Should add more information here regarding the way that arcade drive works.)
+ * @param stick The joystick to use for Arcade single-stick driving. The Y-axis will be selected
+ * for forwards/backwards and the X-axis will be selected for rotation rate.
+ * @param squaredInputs If true, the sensitivity will be increased for small values
+ */
+void RobotDrive::ArcadeDrive(GenericHID &stick, bool squaredInputs)
+{
+	// simply call the full-featured ArcadeDrive with the appropriate values
+	ArcadeDrive(stick.GetY(), stick.GetX(), squaredInputs);
+}
+
+/**
+ * Arcade drive implements single stick driving.
+ * Given two joystick instances and two axis, compute the values to send to either two
+ * or four motors.
+ * @param moveStick The Joystick object that represents the forward/backward direction
+ * @param moveAxis The axis on the moveStick object to use for fowards/backwards (typically Y_AXIS)
+ * @param rotateStick The Joystick object that represents the rotation value
+ * @param rotateAxis The axis on the rotation object to use for the rotate right/left (typically X_AXIS)
+ * @param squaredInputs Setting this parameter to true increases the sensitivity at lower speeds
+ */
+void RobotDrive::ArcadeDrive(GenericHID* moveStick, uint32_t moveAxis,
+								GenericHID* rotateStick, uint32_t rotateAxis,
+								bool squaredInputs)
+{
+	float moveValue = moveStick->GetRawAxis(moveAxis);
+	float rotateValue = rotateStick->GetRawAxis(rotateAxis);
+
+	ArcadeDrive(moveValue, rotateValue, squaredInputs);
+}
+
+/**
+ * Arcade drive implements single stick driving.
+ * Given two joystick instances and two axis, compute the values to send to either two
+ * or four motors.
+ * @param moveStick The Joystick object that represents the forward/backward direction
+ * @param moveAxis The axis on the moveStick object to use for fowards/backwards (typically Y_AXIS)
+ * @param rotateStick The Joystick object that represents the rotation value
+ * @param rotateAxis The axis on the rotation object to use for the rotate right/left (typically X_AXIS)
+ * @param squaredInputs Setting this parameter to true increases the sensitivity at lower speeds
+ */
+
+void RobotDrive::ArcadeDrive(GenericHID &moveStick, uint32_t moveAxis,
+								GenericHID &rotateStick, uint32_t rotateAxis,
+								bool squaredInputs)
+{
+	float moveValue = moveStick.GetRawAxis(moveAxis);
+	float rotateValue = rotateStick.GetRawAxis(rotateAxis);
+
+	ArcadeDrive(moveValue, rotateValue, squaredInputs);
+}
+
+/**
+ * Arcade drive implements single stick driving.
+ * This function lets you directly provide joystick values from any source.
+ * @param moveValue The value to use for fowards/backwards
+ * @param rotateValue The value to use for the rotate right/left
+ * @param squaredInputs If set, increases the sensitivity at low speeds
+ */
+void RobotDrive::ArcadeDrive(float moveValue, float rotateValue, bool squaredInputs)
+{
+	static bool reported = false;
+	if (!reported)
+	{
+		reported = true;
+	}
+
+	// local variables to hold the computed PWM values for the motors
+	float leftMotorOutput;
+	float rightMotorOutput;
+
+	moveValue = Limit(moveValue);
+	rotateValue = Limit(rotateValue);
+
+	if (squaredInputs)
+	{
+		// square the inputs (while preserving the sign) to increase fine control while permitting full power
+		if (moveValue >= 0.0)
+		{
+			moveValue = (moveValue * moveValue);
+		}
+		else
+		{
+			moveValue = -(moveValue * moveValue);
+		}
+		if (rotateValue >= 0.0)
+		{
+			rotateValue = (rotateValue * rotateValue);
+		}
+		else
+		{
+			rotateValue = -(rotateValue * rotateValue);
+		}
+	}
+
+	if (moveValue > 0.0)
+	{
+		if (rotateValue > 0.0)
+		{
+			leftMotorOutput = moveValue - rotateValue;
+			rightMotorOutput = std::max(moveValue, rotateValue);
+		}
+		else
+		{
+			leftMotorOutput = std::max(moveValue, -rotateValue);
+			rightMotorOutput = moveValue + rotateValue;
+		}
+	}
+	else
+	{
+		if (rotateValue > 0.0)
+		{
+			leftMotorOutput = - std::max(-moveValue, rotateValue);
+			rightMotorOutput = moveValue + rotateValue;
+		}
+		else
+		{
+			leftMotorOutput = moveValue - rotateValue;
+			rightMotorOutput = - std::max(-moveValue, -rotateValue);
+		}
+	}
+	SetLeftRightMotorOutputs(leftMotorOutput, rightMotorOutput);
+}
+
+/**
+ * Drive method for Mecanum wheeled robots.
+ *
+ * A method for driving with Mecanum wheeled robots. There are 4 wheels
+ * on the robot, arranged so that the front and back wheels are toed in 45 degrees.
+ * When looking at the wheels from the top, the roller axles should form an X across the robot.
+ *
+ * This is designed to be directly driven by joystick axes.
+ *
+ * @param x The speed that the robot should drive in the X direction. [-1.0..1.0]
+ * @param y The speed that the robot should drive in the Y direction.
+ * This input is inverted to match the forward == -1.0 that joysticks produce. [-1.0..1.0]
+ * @param rotation The rate of rotation for the robot that is completely independent of
+ * the translation. [-1.0..1.0]
+ * @param gyroAngle The current angle reading from the gyro.  Use this to implement field-oriented controls.
+ */
+void RobotDrive::MecanumDrive_Cartesian(float x, float y, float rotation, float gyroAngle)
+{
+	static bool reported = false;
+	if (!reported)
+	{
+		reported = true;
+	}
+
+	double xIn = x;
+	double yIn = y;
+	// Negate y for the joystick.
+	yIn = -yIn;
+	// Compenstate for gyro angle.
+	RotateVector(xIn, yIn, gyroAngle);
+
+	double wheelSpeeds[kMaxNumberOfMotors];
+	wheelSpeeds[kFrontLeftMotor] = xIn + yIn + rotation;
+	wheelSpeeds[kFrontRightMotor] = -xIn + yIn - rotation;
+	wheelSpeeds[kRearLeftMotor] = -xIn + yIn + rotation;
+	wheelSpeeds[kRearRightMotor] = xIn + yIn - rotation;
+
+	Normalize(wheelSpeeds);
+
+	uint8_t syncGroup = 0x80;
+
+	m_frontLeftMotor->Set(wheelSpeeds[kFrontLeftMotor] * m_invertedMotors[kFrontLeftMotor] * m_maxOutput, syncGroup);
+	m_frontRightMotor->Set(wheelSpeeds[kFrontRightMotor] * m_invertedMotors[kFrontRightMotor] * m_maxOutput, syncGroup);
+	m_rearLeftMotor->Set(wheelSpeeds[kRearLeftMotor] * m_invertedMotors[kRearLeftMotor] * m_maxOutput, syncGroup);
+	m_rearRightMotor->Set(wheelSpeeds[kRearRightMotor] * m_invertedMotors[kRearRightMotor] * m_maxOutput, syncGroup);
+
+	// CANJaguar::UpdateSyncGroup(syncGroup);
+
+	// FIXME: m_safetyHelper->Feed();
+}
+
+/**
+ * Drive method for Mecanum wheeled robots.
+ *
+ * A method for driving with Mecanum wheeled robots. There are 4 wheels
+ * on the robot, arranged so that the front and back wheels are toed in 45 degrees.
+ * When looking at the wheels from the top, the roller axles should form an X across the robot.
+ *
+ * @param magnitude The speed that the robot should drive in a given direction. [-1.0..1.0]
+ * @param direction The direction the robot should drive in degrees. The direction and maginitute are
+ * independent of the rotation rate.
+ * @param rotation The rate of rotation for the robot that is completely independent of
+ * the magnitute or direction. [-1.0..1.0]
+ */
+void RobotDrive::MecanumDrive_Polar(float magnitude, float direction, float rotation)
+{
+	static bool reported = false;
+	if (!reported)
+	{
+		reported = true;
+	}
+
+	// Normalized for full power along the Cartesian axes.
+	magnitude = Limit(magnitude) * sqrt(2.0);
+	// The rollers are at 45 degree angles.
+	double dirInRad = (direction + 45.0) * 3.14159 / 180.0;
+	double cosD = cos(dirInRad);
+	double sinD = sin(dirInRad);
+
+	double wheelSpeeds[kMaxNumberOfMotors];
+	wheelSpeeds[kFrontLeftMotor] = sinD * magnitude + rotation;
+	wheelSpeeds[kFrontRightMotor] = cosD * magnitude - rotation;
+	wheelSpeeds[kRearLeftMotor] = cosD * magnitude + rotation;
+	wheelSpeeds[kRearRightMotor] = sinD * magnitude - rotation;
+
+	Normalize(wheelSpeeds);
+
+	uint8_t syncGroup = 0x80;
+
+	m_frontLeftMotor->Set(wheelSpeeds[kFrontLeftMotor] * m_invertedMotors[kFrontLeftMotor] * m_maxOutput, syncGroup);
+	m_frontRightMotor->Set(wheelSpeeds[kFrontRightMotor] * m_invertedMotors[kFrontRightMotor] * m_maxOutput, syncGroup);
+	m_rearLeftMotor->Set(wheelSpeeds[kRearLeftMotor] * m_invertedMotors[kRearLeftMotor] * m_maxOutput, syncGroup);
+	m_rearRightMotor->Set(wheelSpeeds[kRearRightMotor] * m_invertedMotors[kRearRightMotor] * m_maxOutput, syncGroup);
+
+	// CANJaguar::UpdateSyncGroup(syncGroup);
+
+	// FIXME: m_safetyHelper->Feed();
+}
+
+/**
+ * Holonomic Drive method for Mecanum wheeled robots.
+ *
+ * This is an alias to MecanumDrive_Polar() for backward compatability
+ *
+ * @param magnitude The speed that the robot should drive in a given direction.  [-1.0..1.0]
+ * @param direction The direction the robot should drive. The direction and maginitute are
+ * independent of the rotation rate.
+ * @param rotation The rate of rotation for the robot that is completely independent of
+ * the magnitute or direction.  [-1.0..1.0]
+ */
+void RobotDrive::HolonomicDrive(float magnitude, float direction, float rotation)
+{
+	MecanumDrive_Polar(magnitude, direction, rotation);
+}
+
+/** Set the speed of the right and left motors.
+ * This is used once an appropriate drive setup function is called such as
+ * TwoWheelDrive(). The motors are set to "leftOutput" and "rightOutput"
+ * and includes flipping the direction of one side for opposing motors.
+ * @param leftOutput The speed to send to the left side of the robot.
+ * @param rightOutput The speed to send to the right side of the robot.
+ */
+void RobotDrive::SetLeftRightMotorOutputs(float leftOutput, float rightOutput)
+{
+	wpi_assert(m_rearLeftMotor != nullptr && m_rearRightMotor != nullptr);
+
+	uint8_t syncGroup = 0x80;
+
+	if (m_frontLeftMotor != nullptr)
+		m_frontLeftMotor->Set(Limit(leftOutput) * m_invertedMotors[kFrontLeftMotor] * m_maxOutput, syncGroup);
+	m_rearLeftMotor->Set(Limit(leftOutput) * m_invertedMotors[kRearLeftMotor] * m_maxOutput, syncGroup);
+
+	if (m_frontRightMotor != nullptr)
+		m_frontRightMotor->Set(-Limit(rightOutput) * m_invertedMotors[kFrontRightMotor] * m_maxOutput, syncGroup);
+	m_rearRightMotor->Set(-Limit(rightOutput) * m_invertedMotors[kRearRightMotor] * m_maxOutput, syncGroup);
+
+	// CANJaguar::UpdateSyncGroup(syncGroup);
+
+	// FIXME: m_safetyHelper->Feed();
+}
+
+/**
+ * Limit motor values to the -1.0 to +1.0 range.
+ */
+float RobotDrive::Limit(float num)
+{
+	if (num > 1.0)
+	{
+		return 1.0;
+	}
+	if (num < -1.0)
+	{
+		return -1.0;
+	}
+	return num;
+}
+
+/**
+ * Normalize all wheel speeds if the magnitude of any wheel is greater than 1.0.
+ */
+void RobotDrive::Normalize(double *wheelSpeeds)
+{
+	double maxMagnitude = fabs(wheelSpeeds[0]);
+	int32_t i;
+	for (i=1; i<kMaxNumberOfMotors; i++)
+	{
+		double temp = fabs(wheelSpeeds[i]);
+		if (maxMagnitude < temp) maxMagnitude = temp;
+	}
+	if (maxMagnitude > 1.0)
+	{
+		for (i=0; i<kMaxNumberOfMotors; i++)
+		{
+			wheelSpeeds[i] = wheelSpeeds[i] / maxMagnitude;
+		}
+	}
+}
+
+/**
+ * Rotate a vector in Cartesian space.
+ */
+void RobotDrive::RotateVector(double &x, double &y, double angle)
+{
+	double cosA = cos(angle * (3.14159 / 180.0));
+	double sinA = sin(angle * (3.14159 / 180.0));
+	double xOut = x * cosA - y * sinA;
+	double yOut = x * sinA + y * cosA;
+	x = xOut;
+	y = yOut;
+}
+
+/*
+ * Invert a motor direction.
+ * This is used when a motor should run in the opposite direction as the drive
+ * code would normally run it. Motors that are direct drive would be inverted, the
+ * Drive code assumes that the motors are geared with one reversal.
+ * @param motor The motor index to invert.
+ * @param isInverted True if the motor should be inverted when operated.
+ */
+void RobotDrive::SetInvertedMotor(MotorType motor, bool isInverted)
+{
+	if (motor < 0 || motor > 3)
+	{
+		wpi_setWPIError(InvalidMotorIndex);
+		return;
+	}
+	m_invertedMotors[motor] = isInverted ? -1 : 1;
+}
+
+/**
+ * Set the turning sensitivity.
+ *
+ * This only impacts the Drive() entry-point.
+ * @param sensitivity Effectively sets the turning sensitivity (or turn radius for a given value)
+ */
+void RobotDrive::SetSensitivity(float sensitivity)
+{
+	m_sensitivity = sensitivity;
+}
+
+/**
+ * Configure the scaling factor for using RobotDrive with motor controllers in a mode other than PercentVbus.
+ * @param maxOutput Multiplied with the output percentage computed by the drive functions.
+ */
+void RobotDrive::SetMaxOutput(double maxOutput)
+{
+	m_maxOutput = maxOutput;
+}
+
+
+
+void RobotDrive::SetExpiration(float timeout)
+{
+	// FIXME: m_safetyHelper->SetExpiration(timeout);
+}
+
+float RobotDrive::GetExpiration() const
+{
+    return -1; // FIXME: return m_safetyHelper->GetExpiration();
+}
+
+bool RobotDrive::IsAlive() const
+{
+    return true; // FIXME: m_safetyHelper->IsAlive();
+}
+
+bool RobotDrive::IsSafetyEnabled() const
+{
+    return false; // FIXME: return m_safetyHelper->IsSafetyEnabled();
+}
+
+void RobotDrive::SetSafetyEnabled(bool enabled)
+{
+	// FIXME: m_safetyHelper->SetSafetyEnabled(enabled);
+}
+
+void RobotDrive::GetDescription(std::ostringstream& desc) const
+{
+	desc << "RobotDrive";
+}
+
+void RobotDrive::StopMotor()
+{
+	if (m_frontLeftMotor != nullptr) m_frontLeftMotor->Disable();
+	if (m_frontRightMotor != nullptr) m_frontRightMotor->Disable();
+	if (m_rearLeftMotor != nullptr) m_rearLeftMotor->Disable();
+	if (m_rearRightMotor != nullptr) m_rearRightMotor->Disable();
+}
diff --git a/wpilibc/simulation/src/SafePWM.cpp b/wpilibc/simulation/src/SafePWM.cpp
new file mode 100644
index 0000000..8ba0b68
--- /dev/null
+++ b/wpilibc/simulation/src/SafePWM.cpp
@@ -0,0 +1,93 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "SafePWM.h"
+#include <sstream>
+#include <memory>
+
+/**
+ * Constructor for a SafePWM object taking a channel number.
+ * @param channel The PWM channel number (0..19).
+ */
+SafePWM::SafePWM(uint32_t channel): PWM(channel)
+{
+	m_safetyHelper = std::make_unique<MotorSafetyHelper>(this);
+	m_safetyHelper->SetSafetyEnabled(false);
+}
+
+/*
+ * Set the expiration time for the PWM object
+ * @param timeout The timeout (in seconds) for this motor object
+ */
+void SafePWM::SetExpiration(float timeout)
+{
+	m_safetyHelper->SetExpiration(timeout);
+}
+
+/**
+ * Return the expiration time for the PWM object.
+ * @returns The expiration time value.
+ */
+float SafePWM::GetExpiration() const
+{
+	return m_safetyHelper->GetExpiration();
+}
+
+/**
+ * Check if the PWM object is currently alive or stopped due to a timeout.
+ * @returns a bool value that is true if the motor has NOT timed out and should still
+ * be running.
+ */
+bool SafePWM::IsAlive() const
+{
+	return m_safetyHelper->IsAlive();
+}
+
+/**
+ * Stop the motor associated with this PWM object.
+ * This is called by the MotorSafetyHelper object when it has a timeout for this PWM and needs to
+ * stop it from running.
+ */
+void SafePWM::StopMotor()
+{
+	SetRaw(kPwmDisabled);
+}
+
+/**
+ * Enable/disable motor safety for this device
+ * Turn on and off the motor safety option for this PWM object.
+ * @param enabled True if motor safety is enforced for this object
+ */
+void SafePWM::SetSafetyEnabled(bool enabled)
+{
+	m_safetyHelper->SetSafetyEnabled(enabled);
+}
+
+/**
+ * Check if motor safety is enabled for this object
+ * @returns True if motor safety is enforced for this object
+ */
+bool SafePWM::IsSafetyEnabled() const
+{
+	return m_safetyHelper->IsSafetyEnabled();
+}
+
+void SafePWM::GetDescription(std::ostringstream& desc) const
+{
+	desc << "PWM " << GetChannel();
+}
+
+/**
+ * Feed the MotorSafety timer when setting the speed.
+ * This method is called by the subclass motor whenever it updates its speed, thereby reseting
+ * the timeout value.
+ * @param speed Value to pass to the PWM class
+ */
+void SafePWM::SetSpeed(float speed)
+{
+	PWM::SetSpeed(speed);
+	m_safetyHelper->Feed();
+}
diff --git a/wpilibc/simulation/src/SampleRobot.cpp b/wpilibc/simulation/src/SampleRobot.cpp
new file mode 100644
index 0000000..b8f3181
--- /dev/null
+++ b/wpilibc/simulation/src/SampleRobot.cpp
@@ -0,0 +1,157 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "SampleRobot.h"
+
+#include <stdio.h>
+#include "Timer.h"
+#include "SmartDashboard/SmartDashboard.h"
+#include "LiveWindow/LiveWindow.h"
+#include "networktables/NetworkTable.h"
+
+#if defined(_UNIX)
+	#include <unistd.h>
+#elif defined(_WIN32)
+  #include <windows.h>
+  void sleep(unsigned milliseconds)
+	    {
+	        Sleep(milliseconds);
+	    }
+#endif
+
+
+SampleRobot::SampleRobot()
+	: m_robotMainOverridden (true)
+{
+}
+
+/**
+ * Robot-wide initialization code should go here.
+ *
+ * Programmers should override this method for default Robot-wide initialization which will
+ * be called each time the robot enters the disabled state.
+ */
+void SampleRobot::RobotInit()
+{
+	printf("Default %s() method... Override me!\n", __FUNCTION__);
+}
+
+/**
+ * Disabled should go here.
+ * Programmers should override this method to run code that should run while the field is
+ * disabled.
+ */
+void SampleRobot::Disabled()
+{
+	printf("Default %s() method... Override me!\n", __FUNCTION__);
+}
+
+/**
+ * Autonomous should go here.
+ * Programmers should override this method to run code that should run while the field is
+ * in the autonomous period. This will be called once each time the robot enters the
+ * autonomous state.
+ */
+void SampleRobot::Autonomous()
+{
+	printf("Default %s() method... Override me!\n", __FUNCTION__);
+}
+
+/**
+ * Operator control (tele-operated) code should go here.
+ * Programmers should override this method to run code that should run while the field is
+ * in the Operator Control (tele-operated) period. This is called once each time the robot
+ * enters the teleop state.
+ */
+void SampleRobot::OperatorControl()
+{
+	printf("Default %s() method... Override me!\n", __FUNCTION__);
+}
+
+/**
+ * Test program should go here.
+ * Programmers should override this method to run code that executes while the robot is
+ * in test mode. This will be called once whenever the robot enters test mode
+ */
+void SampleRobot::Test()
+{
+	printf("Default %s() method... Override me!\n", __FUNCTION__);
+}
+
+/**
+ * Robot main program for free-form programs.
+ *
+ * This should be overridden by user subclasses if the intent is to not use the Autonomous() and
+ * OperatorControl() methods. In that case, the program is responsible for sensing when to run
+ * the autonomous and operator control functions in their program.
+ *
+ * This method will be called immediately after the constructor is called. If it has not been
+ * overridden by a user subclass (i.e. the default version runs), then the Autonomous() and
+ * OperatorControl() methods will be called.
+ */
+void SampleRobot::RobotMain()
+{
+	m_robotMainOverridden = false;
+}
+
+/**
+ * Start a competition.
+ * This code needs to track the order of the field starting to ensure that everything happens
+ * in the right order. Repeatedly run the correct method, either Autonomous or OperatorControl
+ * or Test when the robot is enabled. After running the correct method, wait for some state to
+ * change, either the other mode starts or the robot is disabled. Then go back and wait for the
+ * robot to be enabled again.
+ */
+void SampleRobot::StartCompetition()
+{
+	LiveWindow *lw = LiveWindow::GetInstance();
+
+	SmartDashboard::init();
+	NetworkTable::GetTable("LiveWindow")->GetSubTable("~STATUS~")->PutBoolean("LW Enabled", false);
+
+	RobotMain();
+
+	if (!m_robotMainOverridden)
+	{
+		// first and one-time initialization
+		lw->SetEnabled(false);
+		RobotInit();
+
+		while (true)
+		{
+			if (IsDisabled())
+			{
+				m_ds.InDisabled(true);
+				Disabled();
+				m_ds.InDisabled(false);
+				while (IsDisabled()) sleep(1); //m_ds.WaitForData();
+			}
+			else if (IsAutonomous())
+			{
+				m_ds.InAutonomous(true);
+				Autonomous();
+				m_ds.InAutonomous(false);
+				while (IsAutonomous() && IsEnabled()) sleep(1); //m_ds.WaitForData();
+			}
+            else if (IsTest())
+            {
+              lw->SetEnabled(true);
+              m_ds.InTest(true);
+              Test();
+              m_ds.InTest(false);
+              while (IsTest() && IsEnabled()) sleep(1); //m_ds.WaitForData();
+              lw->SetEnabled(false);
+            }
+			else
+			{
+				m_ds.InOperatorControl(true);
+				OperatorControl();
+				m_ds.InOperatorControl(false);
+				while (IsOperatorControl() && IsEnabled()) sleep(1); //m_ds.WaitForData();
+			}
+		}
+	}
+}
diff --git a/wpilibc/simulation/src/SensorBase.cpp b/wpilibc/simulation/src/SensorBase.cpp
new file mode 100644
index 0000000..fa3086f
--- /dev/null
+++ b/wpilibc/simulation/src/SensorBase.cpp
@@ -0,0 +1,161 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "SensorBase.h"
+
+#include "WPIErrors.h"
+
+const uint32_t SensorBase::kDigitalChannels;
+const uint32_t SensorBase::kAnalogInputs;
+const uint32_t SensorBase::kSolenoidChannels;
+const uint32_t SensorBase::kSolenoidModules;
+const uint32_t SensorBase::kPwmChannels;
+const uint32_t SensorBase::kRelayChannels;
+const uint32_t SensorBase::kPDPChannels;
+const uint32_t SensorBase::kChassisSlots;
+SensorBase *SensorBase::m_singletonList = nullptr;
+
+/**
+ * Creates an instance of the sensor base and gets an FPGA handle
+ */
+SensorBase::SensorBase()
+{
+}
+
+/**
+ * Add sensor to the singleton list.
+ * Add this sensor to the list of singletons that need to be deleted when
+ * the robot program exits. Each of the sensors on this list are singletons,
+ * that is they aren't allocated directly with new, but instead are allocated
+ * by the static GetInstance method. As a result, they are never deleted when
+ * the program exits. Consequently these sensors may still be holding onto
+ * resources and need to have their destructors called at the end of the program.
+ */
+void SensorBase::AddToSingletonList()
+{
+	m_nextSingleton = m_singletonList;
+	m_singletonList = this;
+}
+
+/**
+ * Delete all the singleton classes on the list.
+ * All the classes that were allocated as singletons need to be deleted so
+ * their resources can be freed.
+ */
+void SensorBase::DeleteSingletons()
+{
+	for (SensorBase *next = m_singletonList; next != nullptr;)
+	{
+		SensorBase *tmp = next;
+		next = next->m_nextSingleton;
+		delete tmp;
+	}
+	m_singletonList = nullptr;
+}
+
+/**
+ * Check that the solenoid module number is valid.
+ *
+ * @return Solenoid module is valid and present
+ */
+bool SensorBase::CheckSolenoidModule(uint8_t moduleNumber)
+{
+	return 1 <= moduleNumber && moduleNumber <= 2; // TODO: Fix for Athena
+}
+
+/**
+ * Check that the digital channel number is valid.
+ * Verify that the channel number is one of the legal channel numbers. Channel numbers are
+ * 1-based.
+ *
+ * @return Digital channel is valid
+ */
+bool SensorBase::CheckDigitalChannel(uint32_t channel)
+{
+	if (channel > 0 && channel <= kDigitalChannels)
+		return true;
+	return false;
+}
+
+/**
+ * Check that the digital channel number is valid.
+ * Verify that the channel number is one of the legal channel numbers. Channel numbers are
+ * 1-based.
+ *
+ * @return Relay channel is valid
+ */
+bool SensorBase::CheckRelayChannel(uint32_t channel)
+{
+	if (channel > 0 && channel <= kRelayChannels)
+		return true;
+	return false;
+}
+
+/**
+ * Check that the digital channel number is valid.
+ * Verify that the channel number is one of the legal channel numbers. Channel numbers are
+ * 1-based.
+ *
+ * @return PWM channel is valid
+ */
+bool SensorBase::CheckPWMChannel(uint32_t channel)
+{
+	if (channel > 0 && channel <= kPwmChannels)
+		return true;
+	return false;
+}
+
+/**
+ * Check that the analog input number is valid.
+ * Verify that the analog input number is one of the legal channel numbers. Channel numbers
+ * are 1-based.
+ *
+ * @return Analog channel is valid
+ */
+bool SensorBase::CheckAnalogInput(uint32_t channel)
+{
+	if (channel > 0 && channel <= kAnalogInputs)
+		return true;
+	return false;
+}
+
+/**
+ * Check that the analog output number is valid.
+ * Verify that the analog output number is one of the legal channel numbers. Channel numbers
+ * are 1-based.
+ *
+ * @return Analog channel is valid
+ */
+bool SensorBase::CheckAnalogOutput(uint32_t channel)
+{
+    if (channel > 0 && channel <= kAnalogOutputs)
+        return true;
+    return false;
+}
+
+/**
+ * Verify that the solenoid channel number is within limits.
+ * 
+ * @return Solenoid channel is valid
+ */
+bool SensorBase::CheckSolenoidChannel(uint32_t channel)
+{
+	if (channel > 0 && channel <= kSolenoidChannels)
+		return true;
+	return false;
+}
+
+/**
+ * Verify that the power distribution channel number is within limits.
+ *
+ * @return PDP channel is valid
+ */
+bool SensorBase::CheckPDPChannel(uint32_t channel)
+{
+	if (channel > 0 && channel <= kPDPChannels)
+		return true;
+	return false;
+}
diff --git a/wpilibc/simulation/src/Solenoid.cpp b/wpilibc/simulation/src/Solenoid.cpp
new file mode 100644
index 0000000..387194d
--- /dev/null
+++ b/wpilibc/simulation/src/Solenoid.cpp
@@ -0,0 +1,98 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Solenoid.h"
+#include "WPIErrors.h"
+#include "LiveWindow/LiveWindow.h"
+#include "simulation/simTime.h"
+
+/**
+ * Constructor.
+ *
+ * @param channel The channel on the solenoid module to control (1..8).
+ */
+Solenoid::Solenoid(uint32_t channel) : Solenoid(1, channel) {}
+
+/**
+ * Constructor.
+ *
+ * @param moduleNumber The solenoid module (1 or 2).
+ * @param channel The channel on the solenoid module to control (1..8).
+ */
+Solenoid::Solenoid(uint8_t moduleNumber, uint32_t channel)
+{
+    char buffer[50];
+    int n = sprintf(buffer, "pneumatic/%d/%d", moduleNumber, channel);
+    m_impl = new SimContinuousOutput(buffer);
+  
+	LiveWindow::GetInstance()->AddActuator("Solenoid", moduleNumber, channel,
+                                           this);
+}
+
+Solenoid::~Solenoid() {
+	if (m_table != nullptr) m_table->RemoveTableListener(this);
+}
+
+/**
+ * Set the value of a solenoid.
+ *
+ * @param on Turn the solenoid output off or on.
+ */
+void Solenoid::Set(bool on)
+{
+    m_on = on;
+    m_impl->Set(on ? 1 : -1);
+}
+
+/**
+ * Read the current value of the solenoid.
+ *
+ * @return The current value of the solenoid.
+ */
+bool Solenoid::Get() const
+{
+    return m_on;
+}
+
+
+void Solenoid::ValueChanged(ITable* source, llvm::StringRef key,
+                            std::shared_ptr<nt::Value> value, bool isNew) {
+  if (!value->IsBoolean()) return;
+	Set(value->GetBoolean());
+}
+
+void Solenoid::UpdateTable() {
+	if (m_table != nullptr) {
+		m_table->PutBoolean("Value", Get());
+	}
+}
+
+void Solenoid::StartLiveWindowMode() {
+	Set(false);
+	if (m_table != nullptr) {
+		m_table->AddTableListener("Value", this, true);
+	}
+}
+
+void Solenoid::StopLiveWindowMode() {
+	Set(false);
+	if (m_table != nullptr) {
+		m_table->RemoveTableListener(this);
+	}
+}
+
+std::string Solenoid::GetSmartDashboardType() const {
+	return "Solenoid";
+}
+
+void Solenoid::InitTable(std::shared_ptr<ITable> subTable) {
+	m_table = subTable;
+	UpdateTable();
+}
+
+std::shared_ptr<ITable> Solenoid::GetTable() const {
+	return m_table;
+}
diff --git a/wpilibc/simulation/src/Talon.cpp b/wpilibc/simulation/src/Talon.cpp
new file mode 100644
index 0000000..0e9505d
--- /dev/null
+++ b/wpilibc/simulation/src/Talon.cpp
@@ -0,0 +1,77 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Talon.h"
+
+//#include "NetworkCommunication/UsageReporting.h"
+#include "LiveWindow/LiveWindow.h"
+
+/**
+ * @param channel The PWM channel that the Talon is attached to.
+ */
+Talon::Talon(uint32_t channel) : SafePWM(channel)
+{
+  /* Note that the Talon uses the following bounds for PWM values. These values
+   * should work reasonably well for most controllers, but if users experience
+   * issues such as asymmetric behavior around the deadband or inability to
+   * saturate the controller in either direction, calibration is recommended.
+   * The calibration procedure can be found in the Talon User Manual available
+   * from CTRE.
+   *
+   *   - 211 = full "forward"
+   *   - 133 = the "high end" of the deadband range
+   *   - 129 = center of the deadband range (off)
+   *   - 125 = the "low end" of the deadband range
+   *   - 49 = full "reverse"
+   */
+  SetBounds(2.037, 1.539, 1.513, 1.487, .989);
+  SetPeriodMultiplier(kPeriodMultiplier_2X);
+  SetRaw(m_centerPwm);
+
+  LiveWindow::GetInstance()->AddActuator("Talon", GetChannel(), this);
+}
+
+/**
+ * Set the PWM value.
+ *
+ * The PWM value is set using a range of -1.0 to 1.0, appropriately
+ * scaling the value for the FPGA.
+ *
+ * @param speed The speed value between -1.0 and 1.0 to set.
+ * @param syncGroup Unused interface.
+ */
+void Talon::Set(float speed, uint8_t syncGroup)
+{
+	SetSpeed(speed);
+}
+
+/**
+ * Get the recently set value of the PWM.
+ *
+ * @return The most recently set value for the PWM between -1.0 and 1.0.
+ */
+float Talon::Get() const
+{
+	return GetSpeed();
+}
+
+/**
+ * Common interface for disabling a motor.
+ */
+void Talon::Disable()
+{
+	SetRaw(kPwmDisabled);
+}
+
+/**
+ * Write out the PID value as seen in the PIDOutput base object.
+ *
+ * @param output Write out the PWM value as was found in the PIDController
+ */
+void Talon::PIDWrite(float output)
+{
+	Set(output);
+}
diff --git a/wpilibc/simulation/src/Timer.cpp b/wpilibc/simulation/src/Timer.cpp
new file mode 100644
index 0000000..b4734db
--- /dev/null
+++ b/wpilibc/simulation/src/Timer.cpp
@@ -0,0 +1,208 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Timer.h"
+
+#include <time.h>
+
+#include "simulation/simTime.h"
+#include "Utility.h"
+
+
+// Internal stuff
+#include "simulation/SimFloatInput.h"
+#include "simulation/MainNode.h"
+namespace wpilib { namespace internal {
+    double simTime = 0;
+    std::condition_variable time_wait;
+    std::mutex time_wait_mutex;
+
+    void time_callback(const msgs::ConstFloat64Ptr &msg) {
+        simTime = msg->data();
+        time_wait.notify_all();
+    }
+}}
+
+/**
+ * Pause the task for a specified time.
+ *
+ * Pause the execution of the program for a specified period of time given in seconds.
+ * Motors will continue to run at their last assigned values, and sensors will continue to
+ * update. Only the task containing the wait will pause until the wait time is expired.
+ *
+ * @param seconds Length of time to pause, in seconds.
+ */
+void Wait(double seconds)
+{
+    if (seconds < 0.0) return;
+
+    double start = wpilib::internal::simTime;
+
+	std::unique_lock<std::mutex> lock(wpilib::internal::time_wait_mutex);
+    while ((wpilib::internal::simTime - start) < seconds) {
+      wpilib::internal::time_wait.wait(lock);
+    }
+}
+
+/*
+ * Return the FPGA system clock time in seconds.
+ * This is deprecated and just forwards to Timer::GetFPGATimestamp().
+ * @returns Robot running time in seconds.
+ */
+double GetClock()
+{
+	return Timer::GetFPGATimestamp();
+}
+
+/**
+ * @brief Gives real-time clock system time with nanosecond resolution
+ * @return The time, just in case you want the robot to start autonomous at 8pm on Saturday (except in simulation).
+*/
+double GetTime()
+{
+    return Timer::GetFPGATimestamp(); // The epoch starts when Gazebo starts
+}
+
+//for compatibility with msvc12--see C2864
+const double Timer::kRolloverTime = (1ll << 32) / 1e6;
+/**
+ * Create a new timer object.
+ *
+ * Create a new timer object and reset the time to zero. The timer is initially not running and
+ * must be started.
+ */
+Timer::Timer()
+	: m_startTime (0.0)
+	, m_accumulatedTime (0.0)
+	, m_running (false)
+{
+	//Creates a semaphore to control access to critical regions.
+	//Initially 'open'
+	Reset();
+}
+
+/**
+ * Get the current time from the timer. If the clock is running it is derived from
+ * the current system clock the start time stored in the timer class. If the clock
+ * is not running, then return the time when it was last stopped.
+ *
+ * @return unsigned Current time value for this timer in seconds
+ */
+double Timer::Get() const
+{
+	double result;
+	double currentTime = GetFPGATimestamp();
+
+	std::lock_guard<priority_mutex> sync(m_mutex);
+	if(m_running)
+	{
+		// This math won't work if the timer rolled over (71 minutes after boot).
+		// TODO: Check for it and compensate.
+		result = (currentTime - m_startTime) + m_accumulatedTime;
+	}
+	else
+	{
+		result = m_accumulatedTime;
+	}
+
+	return result;
+}
+
+/**
+ * Reset the timer by setting the time to 0.
+ *
+ * Make the timer startTime the current time so new requests will be relative to now
+ */
+void Timer::Reset()
+{
+	std::lock_guard<priority_mutex> sync(m_mutex);
+	m_accumulatedTime = 0;
+	m_startTime = GetFPGATimestamp();
+}
+
+/**
+ * Start the timer running.
+ * Just set the running flag to true indicating that all time requests should be
+ * relative to the system clock.
+ */
+void Timer::Start()
+{
+	std::lock_guard<priority_mutex> sync(m_mutex);
+	if (!m_running)
+	{
+		m_startTime = GetFPGATimestamp();
+		m_running = true;
+	}
+}
+
+/**
+ * Stop the timer.
+ * This computes the time as of now and clears the running flag, causing all
+ * subsequent time requests to be read from the accumulated time rather than
+ * looking at the system clock.
+ */
+void Timer::Stop()
+{
+	double temp = Get();
+
+	std::lock_guard<priority_mutex> sync(m_mutex);
+	if (m_running)
+	{
+		m_accumulatedTime = temp;
+		m_running = false;
+	}
+}
+
+/**
+ * Check if the period specified has passed and if it has, advance the start
+ * time by that period. This is useful to decide if it's time to do periodic
+ * work without drifting later by the time it took to get around to checking.
+ *
+ * @param period The period to check for (in seconds).
+ * @return If the period has passed.
+ */
+bool Timer::HasPeriodPassed(double period)
+{
+	if (Get() > period)
+	{
+		std::lock_guard<priority_mutex> sync(m_mutex);
+		// Advance the start time by the period.
+		// Don't set it to the current time... we want to avoid drift.
+		m_startTime += period;
+		return true;
+	}
+	return false;
+}
+
+/*
+ * Return the FPGA system clock time in seconds.
+ *
+ * Return the time from the FPGA hardware clock in seconds since the FPGA
+ * started.
+ * Rolls over after 71 minutes.
+ * @returns Robot running time in seconds.
+ */
+double Timer::GetFPGATimestamp()
+{
+	// FPGA returns the timestamp in microseconds
+	// Call the helper GetFPGATime() in Utility.cpp
+	return wpilib::internal::simTime;
+}
+
+/*
+ * Not in a match.
+ */
+double Timer::GetMatchTime()
+{
+	return Timer::GetFPGATimestamp();
+}
+
+// Internal function that reads the PPC timestamp counter.
+extern "C"
+{
+	uint32_t niTimestamp32(void);
+	uint64_t niTimestamp64(void);
+}
diff --git a/wpilibc/simulation/src/Utility.cpp b/wpilibc/simulation/src/Utility.cpp
new file mode 100644
index 0000000..b0710f1
--- /dev/null
+++ b/wpilibc/simulation/src/Utility.cpp
@@ -0,0 +1,235 @@
+
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Utility.h"
+
+#include "Timer.h"
+#include "simulation/simTime.h"
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+#include <sstream>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#if defined(UNIX)
+	#include <execinfo.h>
+	#include <cxxabi.h>
+#endif
+
+static bool stackTraceEnabled = false;
+static bool suspendOnAssertEnabled = false;
+
+/**
+ * Enable Stack trace after asserts.
+ */
+void wpi_stackTraceOnAssertEnable(bool enabled)
+{
+	stackTraceEnabled = enabled;
+}
+
+/**
+ * Enable suspend on asssert.
+ * If enabled, the user task will be suspended whenever an assert fails. This
+ * will allow the user to attach to the task with the debugger and examine variables
+ * around the failure.
+ */
+void wpi_suspendOnAssertEnabled(bool enabled)
+{
+	suspendOnAssertEnabled = enabled;
+}
+
+static void wpi_handleTracing()
+{
+	// if (stackTraceEnabled)
+	// {
+	// 	printf("\n-----------<Stack Trace>----------------\n");
+	// 	printCurrentStackTrace();
+	// }
+	printf("\n");
+}
+
+/**
+ * Assert implementation.
+ * This allows breakpoints to be set on an assert.
+ * The users don't call this, but instead use the wpi_assert macros in Utility.h.
+ */
+bool wpi_assert_impl(bool conditionValue, const std::string &conditionText,
+                     const std::string &message, const std::string &fileName,
+                     uint32_t lineNumber, const std::string &funcName) {
+  if (!conditionValue) {
+    // Error string buffer
+    std::stringstream error;
+
+    // If an error message was specified, include it
+    // Build error string
+    if (message.size()) {
+      error << "Assertion failed: \"" << message << "\", \"" << conditionText
+            << "\" failed in " << funcName + "() in " << fileName << " at line "
+            << lineNumber;
+    } else {
+      error << "Assertion failed: \"" << conditionText << "\" in " << funcName
+            << "() in " << fileName << " at line " << lineNumber;
+    }
+
+    // Print to console and send to remote dashboard
+    std::cout << "\n\n>>>>" << error.str();
+
+    wpi_handleTracing();
+  }
+  return conditionValue;
+}
+
+/**
+ * Common error routines for wpi_assertEqual_impl and wpi_assertNotEqual_impl
+ * This should not be called directly; it should only be used by wpi_assertEqual_impl
+ * and wpi_assertNotEqual_impl.
+ */
+void wpi_assertEqual_common_impl(int valueA, int valueB,
+                                 const std::string &equalityType,
+                                 const std::string &message,
+                                 const std::string &fileName,
+                                 uint32_t lineNumber,
+                                 const std::string &funcName) {
+  // Error string buffer
+  std::stringstream error;
+
+  // If an error message was specified, include it
+  // Build error string
+  if (message.size() > 0) {
+    error << "Assertion failed: \"" << message << "\", \"" << valueA << "\" "
+          << equalityType << " \"" << valueB << "\" in " << funcName << "() in "
+          << fileName << " at line " << lineNumber << "\n";
+  } else {
+    error << "Assertion failed: \"" << valueA << "\" " << equalityType << " \""
+          << valueB << "\" in " << funcName << "() in " << fileName
+          << " at line " << lineNumber << "\n";
+  }
+
+  // Print to console and send to remote dashboard
+  std::cout << "\n\n>>>>" << error.str();
+
+  wpi_handleTracing();
+}
+
+/**
+ * Assert equal implementation.
+ * This determines whether the two given integers are equal. If not,
+ * the value of each is printed along with an optional message string.
+ * The users don't call this, but instead use the wpi_assertEqual macros in Utility.h.
+ */
+bool wpi_assertEqual_impl(int valueA,
+					 	  int valueB,
+						  const std::string &message,
+						  const std::string &fileName,
+						  uint32_t lineNumber,
+						  const std::string &funcName)
+{
+	if(!(valueA == valueB))
+	{
+		wpi_assertEqual_common_impl(valueA, valueB, "!=", message, fileName, lineNumber, funcName);
+	}
+	return valueA == valueB;
+}
+
+/**
+ * Assert not equal implementation.
+ * This determines whether the two given integers are equal. If so,
+ * the value of each is printed along with an optional message string.
+ * The users don't call this, but instead use the wpi_assertNotEqual macros in Utility.h.
+ */
+bool wpi_assertNotEqual_impl(int valueA,
+					 	     int valueB,
+						     const std::string &message,
+						     const std::string &fileName,
+						     uint32_t lineNumber,
+						     const std::string &funcName)
+{
+	if(!(valueA != valueB))
+	{
+		wpi_assertEqual_common_impl(valueA, valueB, "==", message, fileName, lineNumber, funcName);
+	}
+	return valueA != valueB;
+}
+
+/**
+ * Read the microsecond-resolution timer on the FPGA.
+ *
+ * @return The current time in microseconds according to the FPGA (since FPGA reset).
+ */
+uint32_t GetFPGATime()
+{
+	return wpilib::internal::simTime * 1e6;
+}
+
+//TODO: implement symbol demangling and backtrace on windows
+#if defined(UNIX)
+
+/**
+ * Demangle a C++ symbol, used for printing stack traces.
+ */
+static std::string demangle(char const *mangledSymbol)
+{
+	char buffer[256];
+	size_t length;
+	int status;
+
+	if(sscanf(mangledSymbol, "%*[^(]%*[^_]%255[^)+]", buffer))
+	{
+		char *symbol = abi::__cxa_demangle(buffer, nullptr, &length, &status);
+
+		if(status == 0)
+		{
+			return symbol;
+		}
+		else
+		{
+			// If the symbol couldn't be demangled, it's probably a C function,
+			// so just return it as-is.
+			return buffer;
+		}
+	}
+
+
+	// If everything else failed, just return the mangled symbol
+	return mangledSymbol;
+}
+
+/**
+ * Get a stack trace, ignoring the first "offset" symbols.
+ */
+std::string GetStackTrace(uint32_t offset)
+{
+	void *stackTrace[128];
+	int stackSize = backtrace(stackTrace, 128);
+	char **mangledSymbols = backtrace_symbols(stackTrace, stackSize);
+	std::stringstream trace;
+
+	for(int i = offset; i < stackSize; i++)
+	{
+		// Only print recursive functions once in a row.
+		if(i == 0 ||stackTrace[i] != stackTrace[i - 1])
+		{
+			trace << "\tat " << demangle(mangledSymbols[i]) << std::endl;
+		}
+	}
+
+	free(mangledSymbols);
+
+	return trace.str();
+}
+
+#else
+static std::string demangle(char const *mangledSymbol)
+{
+	return "no demangling on windows";
+}
+std::string GetStackTrace(uint32_t offset)
+{
+	return "no stack trace on windows";
+}
+#endif
diff --git a/wpilibc/simulation/src/Victor.cpp b/wpilibc/simulation/src/Victor.cpp
new file mode 100644
index 0000000..54ba61f
--- /dev/null
+++ b/wpilibc/simulation/src/Victor.cpp
@@ -0,0 +1,79 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+
+#include "Victor.h"
+
+//#include "NetworkCommunication/UsageReporting.h"
+#include "LiveWindow/LiveWindow.h"
+
+/**
+ * @param channel The PWM channel that the Victor is attached to.
+ */
+Victor::Victor(uint32_t channel) : SafePWM(channel)
+{
+  /* Note that the Victor uses the following bounds for PWM values. These values
+   * were determined empirically and optimized for the Victor 888. These values
+   * should work reasonably well for Victor 884 controllers as well but if users
+   * experience issues such as asymmetric behavior around the deadband or
+   * inability to saturate the controller in either direction, calibration is
+   * recommended. The calibration procedure can be found in the Victor 884 User
+   * Manual available from IFI.
+   *
+   *   - 206 = full "forward"
+   *   - 131 = the "high end" of the deadband range
+   *   - 128 = center of the deadband range (off)
+   *   - 125 = the "low end" of the deadband range
+   *   - 56 = full "reverse"
+   */
+
+  SetBounds(2.027, 1.525, 1.507, 1.49, 1.026);
+  SetPeriodMultiplier(kPeriodMultiplier_2X);
+  SetRaw(m_centerPwm);
+
+  LiveWindow::GetInstance()->AddActuator("Victor", GetChannel(), this);
+}
+
+/**
+ * Set the PWM value.
+ *
+ * The PWM value is set using a range of -1.0 to 1.0, appropriately
+ * scaling the value for the FPGA.
+ *
+ * @param speed The speed value between -1.0 and 1.0 to set.
+ * @param syncGroup Unused interface.
+ */
+void Victor::Set(float speed, uint8_t syncGroup)
+{
+	SetSpeed(speed);
+}
+
+/**
+ * Get the recently set value of the PWM.
+ *
+ * @return The most recently set value for the PWM between -1.0 and 1.0.
+ */
+float Victor::Get() const
+{
+	return GetSpeed();
+}
+
+/**
+ * Common interface for disabling a motor.
+ */
+void Victor::Disable()
+{
+	SetRaw(kPwmDisabled);
+}
+
+/**
+ * Write out the PID value as seen in the PIDOutput base object.
+ *
+ * @param output Write out the PWM value as was found in the PIDController
+ */
+void Victor::PIDWrite(float output)
+{
+	Set(output);
+}
diff --git a/wpilibc/simulation/src/simulation/SimContinuousOutput.cpp b/wpilibc/simulation/src/simulation/SimContinuousOutput.cpp
new file mode 100644
index 0000000..39dbf70
--- /dev/null
+++ b/wpilibc/simulation/src/simulation/SimContinuousOutput.cpp
@@ -0,0 +1,24 @@
+/*
+ * SimContinuousOutput.cpp
+ *
+ *  Created on: May 28, 2014
+ *      Author: alex
+ */
+
+#include "simulation/SimContinuousOutput.h"
+#include "simulation/MainNode.h"
+
+SimContinuousOutput::SimContinuousOutput(std::string topic) {
+    pub = MainNode::Advertise<msgs::Float64>("~/simulator/"+topic);
+	std::cout << "Initialized ~/simulator/"+topic << std::endl;
+}
+
+void SimContinuousOutput::Set(float speed) {
+	msgs::Float64 msg;
+	msg.set_data(speed);
+	pub->Publish(msg);
+}
+
+float SimContinuousOutput::Get() {
+	return speed;
+}
diff --git a/wpilibc/simulation/src/simulation/SimDigitalInput.cpp b/wpilibc/simulation/src/simulation/SimDigitalInput.cpp
new file mode 100644
index 0000000..b39f2ae
--- /dev/null
+++ b/wpilibc/simulation/src/simulation/SimDigitalInput.cpp
@@ -0,0 +1,22 @@
+/*
+ * SimDigitalInput.cpp
+ *
+ *  Created on: May 28, 2014
+ *      Author: alex
+ */
+
+#include "simulation/SimDigitalInput.h"
+#include "simulation/MainNode.h"
+
+SimDigitalInput::SimDigitalInput(std::string topic) {
+    sub = MainNode::Subscribe("~/simulator/"+topic, &SimDigitalInput::callback, this);
+	std::cout << "Initialized ~/simulator/"+topic << std::endl;
+}
+
+bool SimDigitalInput::Get() {
+	return value;
+}
+
+void SimDigitalInput::callback(const msgs::ConstBoolPtr &msg) {
+  value = msg->data();
+}
diff --git a/wpilibc/simulation/src/simulation/SimEncoder.cpp b/wpilibc/simulation/src/simulation/SimEncoder.cpp
new file mode 100644
index 0000000..b72b8f1
--- /dev/null
+++ b/wpilibc/simulation/src/simulation/SimEncoder.cpp
@@ -0,0 +1,54 @@
+
+#include "simulation/SimEncoder.h"
+#include "simulation/MainNode.h"
+
+SimEncoder::SimEncoder(std::string topic) {
+	commandPub = MainNode::Advertise<msgs::GzString>("~/simulator/"+topic+"/control");
+
+	posSub = MainNode::Subscribe("~/simulator/"+topic+"/position",
+		                 &SimEncoder::positionCallback, this);
+	velSub = MainNode::Subscribe("~/simulator/"+topic+"/velocity",
+		                 &SimEncoder::velocityCallback, this);
+
+	if (commandPub->WaitForConnection(gazebo::common::Time(5.0))) { // Wait up to five seconds.
+		std::cout << "Initialized ~/simulator/" + topic << std::endl;
+	} else {
+		std::cerr << "Failed to initialize ~/simulator/" + topic + ": does the encoder exist?" << std::endl;
+	}
+}
+
+void SimEncoder::Reset() {
+	sendCommand("reset");
+}
+
+void SimEncoder::Start() {
+	sendCommand("start");
+}
+
+void SimEncoder::Stop() {
+	sendCommand("stop");
+}
+
+double SimEncoder::GetPosition() {
+	return position;
+}
+
+double SimEncoder::GetVelocity() {
+	return velocity;
+}
+
+
+void SimEncoder::sendCommand(std::string cmd) {
+	msgs::GzString msg;
+	msg.set_data(cmd);
+	commandPub->Publish(msg);
+}
+
+
+void SimEncoder::positionCallback(const msgs::ConstFloat64Ptr &msg) {
+	position = msg->data();
+}
+
+void SimEncoder::velocityCallback(const msgs::ConstFloat64Ptr &msg) {
+	velocity = msg->data();
+}
diff --git a/wpilibc/simulation/src/simulation/SimFloatInput.cpp b/wpilibc/simulation/src/simulation/SimFloatInput.cpp
new file mode 100644
index 0000000..1fa9337
--- /dev/null
+++ b/wpilibc/simulation/src/simulation/SimFloatInput.cpp
@@ -0,0 +1,22 @@
+/*
+ * SimFloatInput.cpp
+ *
+ *  Created on: May 28, 2014
+ *      Author: alex
+ */
+
+#include "simulation/SimFloatInput.h"
+#include "simulation/MainNode.h"
+
+SimFloatInput::SimFloatInput(std::string topic) {
+    sub = MainNode::Subscribe("~/simulator/"+topic, &SimFloatInput::callback, this);
+	std::cout << "Initialized ~/simulator/"+topic << std::endl;
+}
+
+double SimFloatInput::Get() {
+	return value;
+}
+
+void SimFloatInput::callback(const msgs::ConstFloat64Ptr &msg) {
+  value = msg->data();
+}
diff --git a/wpilibc/simulation/src/simulation/SimGyro.cpp b/wpilibc/simulation/src/simulation/SimGyro.cpp
new file mode 100644
index 0000000..c173c05
--- /dev/null
+++ b/wpilibc/simulation/src/simulation/SimGyro.cpp
@@ -0,0 +1,46 @@
+
+#include "simulation/SimGyro.h"
+#include "simulation/MainNode.h"
+
+SimGyro::SimGyro(std::string topic) {
+    commandPub = MainNode::Advertise<msgs::GzString>("~/simulator/"+topic+"/control");
+  
+    posSub = MainNode::Subscribe("~/simulator/"+topic+"/position",
+                                 &SimGyro::positionCallback, this);
+    velSub = MainNode::Subscribe("~/simulator/"+topic+"/velocity",
+                                 &SimGyro::velocityCallback, this);
+
+    if (commandPub->WaitForConnection(gazebo::common::Time(5.0))) { // Wait up to five seconds.
+		std::cout << "Initialized ~/simulator/" + topic << std::endl;
+	} else {
+		std::cerr << "Failed to initialize ~/simulator/" + topic + ": does the gyro exist?" << std::endl;
+	}
+}
+
+void SimGyro::Reset() {
+    sendCommand("reset");
+}
+
+double SimGyro::GetAngle() {
+    return position;
+}
+
+double SimGyro::GetVelocity() {
+    return velocity;
+}
+
+
+void SimGyro::sendCommand(std::string cmd) {
+  msgs::GzString msg;
+  msg.set_data(cmd);
+  commandPub->Publish(msg);
+}
+
+
+void SimGyro::positionCallback(const msgs::ConstFloat64Ptr &msg) {
+    position = msg->data();
+}
+
+void SimGyro::velocityCallback(const msgs::ConstFloat64Ptr &msg) {
+    velocity = msg->data();
+}
