changeset 231:783f69f37c64 main

Rework the simulator to better reflect the new/different nodes in the real hardware.
author Bob Cook <bob@bobcookdev.com>
date Sat, 12 Jul 2014 17:22:55 -0700
parents 50414c680910
children 417b3f3501ca
files main/robots/odr-sim/ControllerStatus.cpp main/robots/odr-sim/ControllerStatus.h main/robots/odr-sim/DisplayStatus.cpp main/robots/odr-sim/DisplayStatus.h main/robots/odr-sim/GpsStatus.cpp main/robots/odr-sim/GpsStatus.h main/robots/odr-sim/ImuStatus.cpp main/robots/odr-sim/ImuStatus.h main/robots/odr-sim/MotionStatus.cpp main/robots/odr-sim/MotionStatus.h main/robots/odr-sim/Receiver.cpp main/robots/odr-sim/Receiver.h main/robots/odr-sim/SimDisplay.cpp main/robots/odr-sim/SimDisplay.h main/robots/odr-sim/jamfile main/robots/odr-sim/odrsim.log
diffstat 16 files changed, 1110 insertions(+), 237 deletions(-) [+]
line wrap: on
line diff
--- a/main/robots/odr-sim/ControllerStatus.cpp	Sat Jul 12 17:21:10 2014 -0700
+++ b/main/robots/odr-sim/ControllerStatus.cpp	Sat Jul 12 17:22:55 2014 -0700
@@ -7,7 +7,7 @@
 // 
 //  Thread that periodically sends the controller "status" message.
 //
-//  Copyright (c) 2011 Bob Cook
+//  Copyright (c) 2011-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -40,6 +40,12 @@
 // ----------------------------------------------------------------------------------------
 
 Poco::RWLock ControllerStatus::sm_rwLock;
+bool         ControllerStatus::sm_isDisplayAlive;
+bool         ControllerStatus::sm_isGpsAlive;
+bool         ControllerStatus::sm_isImuAlive;
+bool         ControllerStatus::sm_isMotionAlive;
+bool         ControllerStatus::sm_isSonarFrontAlive;
+
 bool         ControllerStatus::sm_isEstopActive;
 bool         ControllerStatus::sm_isMotorCtlActive;
 bool         ControllerStatus::sm_isButtonOneDown;
@@ -47,6 +53,46 @@
 
 // ----------------------------------------------------------------------------------------
 
+void ControllerStatus::setDisplayAlive( bool alive )
+{
+    Poco::RWLock::ScopedWriteLock lock( sm_rwLock );
+    sm_isDisplayAlive = alive;
+}
+
+// ----------------------------------------------------------------------------------------
+
+void ControllerStatus::setGpsAlive( bool alive )
+{
+    Poco::RWLock::ScopedWriteLock lock( sm_rwLock );
+    sm_isGpsAlive = alive;
+}
+
+// ----------------------------------------------------------------------------------------
+
+void ControllerStatus::setImuAlive( bool alive )
+{
+    Poco::RWLock::ScopedWriteLock lock( sm_rwLock );
+    sm_isImuAlive = alive;
+}
+
+// ----------------------------------------------------------------------------------------
+
+void ControllerStatus::setMotionAlive( bool alive )
+{
+    Poco::RWLock::ScopedWriteLock lock( sm_rwLock );
+    sm_isMotionAlive = alive;
+}
+
+// ----------------------------------------------------------------------------------------
+
+void ControllerStatus::setSonarFrontAlive( bool alive )
+{
+    Poco::RWLock::ScopedWriteLock lock( sm_rwLock );
+    sm_isSonarFrontAlive = alive;
+}
+
+// ----------------------------------------------------------------------------------------
+
 void ControllerStatus::sendButtonStatusMessage()
 {
     uint32_t msgid = can_build_message_id( can_node_odr_controller,
@@ -127,36 +173,57 @@
 
 // ----------------------------------------------------------------------------------------
 
+static void sendHeartbeatForNode( uint8_t theNode )
+{
+    uint32_t msgid = can_build_message_id( theNode,
+                                           can_node_broadcast,
+                                           can_dataid_heartbeat );
+
+    CANMessage::QueueToSend( new CANMessage( msgid ) );
+}
+
+// ----------------------------------------------------------------------------------------
+
 void ControllerStatus::run()
 {
     for ( ;; )
     {
         try
         {
-            uint32_t msgid = can_build_message_id( can_node_odr_controller,
-                                                   can_node_broadcast,
-                                                   can_dataid_odrctl_update );
-
-            can_data_odrctl_update info;
+            Poco::RWLock::ScopedReadLock lock( sm_rwLock );
 
+            if ( sm_isDisplayAlive )
             {
-                Poco::RWLock::ScopedReadLock lock( sm_rwLock );
+                sendHeartbeatForNode( can_node_odr_display );
+            }
 
-                info.estop    = sm_isEstopActive;
-                info.motorctl = sm_isMotorCtlActive;
+            if ( sm_isGpsAlive )
+            {
+                sendHeartbeatForNode( can_node_sensor_gps );
             }
 
-            CANMessage::QueueToSend(
-                new CANMessage( msgid,
-                                reinterpret_cast< uint8_t* >( &info ), 
-                                sizeof( info ) ) );
+            if ( sm_isImuAlive )
+            {
+                sendHeartbeatForNode( can_node_odr_display );
+            }
+
+            if ( sm_isMotionAlive )
+            {
+                sendHeartbeatForNode( can_node_odr_motion );
+            }
+
+            if ( sm_isSonarFrontAlive )
+            {
+                sendHeartbeatForNode( can_node_odr_sonar_front );
+            }
+
         }
         catch ( ... )
         {
             // nothing to do, but don't stop the thread
         }
 
-        if ( m_quitEvent.tryWait( 2500 ) ) // 2500 ms == 2.5s
+        if ( m_quitEvent.tryWait( 500 ) ) // 500 ms == 0.5s
         {
             return;
         }
--- a/main/robots/odr-sim/ControllerStatus.h	Sat Jul 12 17:21:10 2014 -0700
+++ b/main/robots/odr-sim/ControllerStatus.h	Sat Jul 12 17:22:55 2014 -0700
@@ -7,7 +7,7 @@
 // 
 //  Thread that periodically checks status and issues "heartbeat" messages.
 //
-//  Copyright (c) 2011 Bob Cook
+//  Copyright (c) 2011-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -41,10 +41,11 @@
 class ControllerStatus : public Poco::Runnable
 {
     public:
-        static void setEstopActive( bool active );
-        static void setMotorCtlActive( bool active );
-        static void setButtonOne( bool down );
-        static void setButtonTwo( bool down );
+        static void setDisplayAlive( bool alive );
+        static void setGpsAlive( bool alive );
+        static void setImuAlive( bool alive );
+        static void setMotionAlive( bool alive );
+        static void setSonarFrontAlive( bool alive );
 
     public:
         ControllerStatus();
@@ -53,14 +54,12 @@
         void timeToQuit();
 
     private:
-        static void sendButtonStatusMessage();
-
-    private:
         static Poco::RWLock sm_rwLock;
-        static bool         sm_isEstopActive;
-        static bool         sm_isMotorCtlActive;
-        static bool         sm_isButtonOneDown;
-        static bool         sm_isButtonTwoDown;
+        static bool         sm_isDisplayAlive;
+        static bool         sm_isGpsAlive;
+        static bool         sm_isImuAlive;
+        static bool         sm_isMotionAlive;
+        static bool         sm_isSonarFrontAlive;
 
     private:
         Poco::Event m_quitEvent;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/robots/odr-sim/DisplayStatus.cpp	Sat Jul 12 17:22:55 2014 -0700
@@ -0,0 +1,95 @@
+// ----------------------------------------------------------------------------------------
+//
+//  robots/odr-sim/DisplayStatus.cpp
+//    
+//  Bob Cook Development, Robotics Library
+//  http://www.bobcookdev.com/rl/
+// 
+//  Thread that emulates the "ODR display" node.
+//
+//  Copyright (c) 2014 Bob Cook
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------------------
+
+#include "DisplayStatus.h"
+
+#include "packages/common/can/can_helpers.h"
+#include "packages/common/can/can_messages.h"
+#include "packages/common/can/can_nodes.h"
+
+#include "packages/linux/can/CANMessage.h"
+
+// ----------------------------------------------------------------------------------------
+
+Poco::RWLock DisplayStatus::sm_rwLock;
+
+// ----------------------------------------------------------------------------------------
+
+DisplayStatus::DisplayStatus()
+    : Poco::Runnable(),
+      m_quitEvent( true /* auto-reset */ )
+{
+}
+
+// ----------------------------------------------------------------------------------------
+
+DisplayStatus::~DisplayStatus()
+{
+}
+
+// ----------------------------------------------------------------------------------------
+
+void DisplayStatus::timeToQuit()
+{
+    m_quitEvent.set();
+}
+
+// ----------------------------------------------------------------------------------------
+
+void DisplayStatus::run()
+{
+    for ( ;; )
+    {
+        try
+        {
+            Poco::RWLock::ScopedReadLock lock( sm_rwLock );
+
+            uint32_t msgid = can_build_message_id( can_node_odr_display,
+                                                   can_node_broadcast,
+                                                   can_dataid_heartbeat );
+
+            CANMessage::QueueToSend( new CANMessage( msgid ) );
+
+        }
+        catch ( ... )
+        {
+            // nothing to do, but don't stop the thread
+        }
+
+        if ( m_quitEvent.tryWait( 2500 /* milliseconds */ ) )
+        {
+            return;
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/robots/odr-sim/DisplayStatus.h	Sat Jul 12 17:22:55 2014 -0700
@@ -0,0 +1,62 @@
+// ----------------------------------------------------------------------------------------
+//
+//  robots/odr-sim/DisplayStatus.h
+//    
+//  Bob Cook Development, Robotics Library
+//  http://www.bobcookdev.com/rl/
+// 
+//  Thread that emulates the "ODR display" node.
+//
+//  Copyright (c) 2014 Bob Cook
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------------------
+
+#ifndef BCDRL_ROBOTS_ODRSIM_DISPLAYSTATUS_H
+#define BCDRL_ROBOTS_ODRSIM_DISPLAYSTATUS_H
+
+#include <Poco/Event.h>
+#include <Poco/Runnable.h>
+#include <Poco/RWLock.h>
+
+// ----------------------------------------------------------------------------------------
+
+class DisplayStatus : public Poco::Runnable
+{
+    public:
+        // static void set...( bool value );
+
+    public:
+        DisplayStatus();
+        virtual ~DisplayStatus();
+        virtual void run();
+        void timeToQuit();
+
+    private:
+        static Poco::RWLock sm_rwLock;
+
+    private:
+        Poco::Event m_quitEvent;
+};
+
+// ----------------------------------------------------------------------------------------
+#endif // #ifndef BCDRL_ROBOTS_ODRSIM_DISPLAYSTATUS_H
+// ----------------------------------------------------------------------------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/robots/odr-sim/GpsStatus.cpp	Sat Jul 12 17:22:55 2014 -0700
@@ -0,0 +1,95 @@
+// ----------------------------------------------------------------------------------------
+//
+//  robots/odr-sim/GpsStatus.cpp
+//    
+//  Bob Cook Development, Robotics Library
+//  http://www.bobcookdev.com/rl/
+// 
+//  Thread that emulates the "ODR display" node.
+//
+//  Copyright (c) 2014 Bob Cook
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------------------
+
+#include "GpsStatus.h"
+
+#include "packages/common/can/can_helpers.h"
+#include "packages/common/can/can_messages.h"
+#include "packages/common/can/can_nodes.h"
+
+#include "packages/linux/can/CANMessage.h"
+
+// ----------------------------------------------------------------------------------------
+
+Poco::RWLock GpsStatus::sm_rwLock;
+
+// ----------------------------------------------------------------------------------------
+
+GpsStatus::GpsStatus()
+    : Poco::Runnable(),
+      m_quitEvent( true /* auto-reset */ )
+{
+}
+
+// ----------------------------------------------------------------------------------------
+
+GpsStatus::~GpsStatus()
+{
+}
+
+// ----------------------------------------------------------------------------------------
+
+void GpsStatus::timeToQuit()
+{
+    m_quitEvent.set();
+}
+
+// ----------------------------------------------------------------------------------------
+
+void GpsStatus::run()
+{
+    for ( ;; )
+    {
+        try
+        {
+            Poco::RWLock::ScopedReadLock lock( sm_rwLock );
+
+            uint32_t msgid = can_build_message_id( can_node_sensor_gps,
+                                                   can_node_broadcast,
+                                                   can_dataid_heartbeat );
+
+            CANMessage::QueueToSend( new CANMessage( msgid ) );
+
+        }
+        catch ( ... )
+        {
+            // nothing to do, but don't stop the thread
+        }
+
+        if ( m_quitEvent.tryWait( 1250 /* milliseconds */ ) )
+        {
+            return;
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/robots/odr-sim/GpsStatus.h	Sat Jul 12 17:22:55 2014 -0700
@@ -0,0 +1,62 @@
+// ----------------------------------------------------------------------------------------
+//
+//  robots/odr-sim/GpsStatus.h
+//    
+//  Bob Cook Development, Robotics Library
+//  http://www.bobcookdev.com/rl/
+// 
+//  Thread that emulates the "GPS sensor" node.
+//
+//  Copyright (c) 2014 Bob Cook
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------------------
+
+#ifndef BCDRL_ROBOTS_ODRSIM_GPSSTATUS_H
+#define BCDRL_ROBOTS_ODRSIM_GPSSTATUS_H
+
+#include <Poco/Event.h>
+#include <Poco/Runnable.h>
+#include <Poco/RWLock.h>
+
+// ----------------------------------------------------------------------------------------
+
+class GpsStatus : public Poco::Runnable
+{
+    public:
+        // static void set...( bool value );
+
+    public:
+        GpsStatus();
+        virtual ~GpsStatus();
+        virtual void run();
+        void timeToQuit();
+
+    private:
+        static Poco::RWLock sm_rwLock;
+
+    private:
+        Poco::Event m_quitEvent;
+};
+
+// ----------------------------------------------------------------------------------------
+#endif // #ifndef BCDRL_ROBOTS_ODRSIM_GPSSTATUS_H
+// ----------------------------------------------------------------------------------------
+
--- a/main/robots/odr-sim/ImuStatus.cpp	Sat Jul 12 17:21:10 2014 -0700
+++ b/main/robots/odr-sim/ImuStatus.cpp	Sat Jul 12 17:22:55 2014 -0700
@@ -7,7 +7,7 @@
 // 
 //  Thread that periodically sends the IMU details.
 //
-//  Copyright (c) 2013 Bob Cook
+//  Copyright (c) 2013-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -41,58 +41,52 @@
 
 // ----------------------------------------------------------------------------------------
 
-static void SendImuDataMessages()
+static void SendImuUpdate()
 {
-#if 0
-    uint32_t msgid;
+    // YAW
+
+    uint32_t imudatamsgid = can_build_message_id(
+                    can_node_odr_manager, can_node_broadcast, can_dataid_imu_yaw );
+
+    can_data_imu_data data;
+    data.data = static_cast< int32_t >( ImuStatus::imuYaw() * can_data_imu_multiplier );
+
+    CANMessage::QueueToSend(
+            new CANMessage( imudatamsgid,
+                            reinterpret_cast< uint8_t* >( &data ),
+                            sizeof( data ) ) );
+
+    // PITCH
 
-    if ( SonarFrontStatus::isSonarFrontEnabled() )
-    {
-        msgid = can_build_message_id( can_node_odr_sonar_front,
-                                      can_node_broadcast,
-                                      can_dataid_sonar_front_state_enabled );
-    }
-    else
-    {
-        msgid = can_build_message_id( can_node_odr_sonar_front,
-                                      can_node_broadcast,
-                                      can_dataid_sonar_front_state_disabled );
-    }
-    CANMessage::QueueToSend( new CANMessage( msgid ) );
-#endif
+    imudatamsgid = can_build_message_id(
+                    can_node_odr_manager, can_node_broadcast, can_dataid_imu_pitch );
+
+    data.data = static_cast< int32_t >( ImuStatus::imuPitch() * can_data_imu_multiplier );
+
+    CANMessage::QueueToSend(
+            new CANMessage( imudatamsgid,
+                            reinterpret_cast< uint8_t* >( &data ),
+                            sizeof( data ) ) );
+
+    // ROLL
+
+    imudatamsgid = can_build_message_id(
+                    can_node_odr_manager, can_node_broadcast, can_dataid_imu_roll );
+
+    data.data = static_cast< int32_t >( ImuStatus::imuRoll() * can_data_imu_multiplier );
+
+    CANMessage::QueueToSend(
+            new CANMessage( imudatamsgid,
+                            reinterpret_cast< uint8_t* >( &data ),
+                            sizeof( data ) ) );
 }
 
 // ----------------------------------------------------------------------------------------
 
 Poco::RWLock ImuStatus::sm_rwLock;
-bool         ImuStatus::sm_isEnabled = false;
-double       ImuStatus::sm_yaw       = 0.0;
-double       ImuStatus::sm_pitch     = 0.0;
-double       ImuStatus::sm_roll      = 0.0;
-
-// ----------------------------------------------------------------------------------------
-
-bool ImuStatus::isImuEnabled()
-{
-    Poco::RWLock::ScopedReadLock lock( sm_rwLock );
-    return sm_isEnabled;
-}
-
-// ----------------------------------------------------------------------------------------
-
-void ImuStatus::setImuEnabled()
-{
-    Poco::RWLock::ScopedWriteLock lock( sm_rwLock );
-    sm_isEnabled = true;
-}
-
-// ----------------------------------------------------------------------------------------
-
-void ImuStatus::setImuDisabled()
-{
-    Poco::RWLock::ScopedWriteLock lock( sm_rwLock );
-    sm_isEnabled = false;
-}
+double       ImuStatus::sm_yaw   = 0.0;
+double       ImuStatus::sm_pitch = 0.0;
+double       ImuStatus::sm_roll  = 0.0;
 
 // ----------------------------------------------------------------------------------------
 
@@ -171,19 +165,15 @@
     {
         try
         {
-//                SendSonarFrontStatusMessage();
+            SendImuUpdate();
 
-//            if ( isSonarFrontEnabled() )
-//            {
-//                SendSonarFrontValueMessage();
-//            }
         }
         catch ( ... )
         {
             // nothing to do, but don't stop the thread
         }
 
-        if ( m_quitEvent.tryWait( 500 ) ) // 500ms = 1/2 second
+        if ( m_quitEvent.tryWait( 750 ) ) // 500ms = 1/2 second
         {
             return;
         }
--- a/main/robots/odr-sim/ImuStatus.h	Sat Jul 12 17:21:10 2014 -0700
+++ b/main/robots/odr-sim/ImuStatus.h	Sat Jul 12 17:22:55 2014 -0700
@@ -7,7 +7,7 @@
 // 
 //  Thread that periodically sends the IMU details.
 //
-//  Copyright (c) 2013 Bob Cook
+//  Copyright (c) 2013-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/robots/odr-sim/MotionStatus.cpp	Sat Jul 12 17:22:55 2014 -0700
@@ -0,0 +1,95 @@
+// ----------------------------------------------------------------------------------------
+//
+//  robots/odr-sim/MotionStatus.cpp
+//    
+//  Bob Cook Development, Robotics Library
+//  http://www.bobcookdev.com/rl/
+// 
+//  Thread that emulates the "ODR motion controller" node.
+//
+//  Copyright (c) 2014 Bob Cook
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------------------
+
+#include "MotionStatus.h"
+
+#include "packages/common/can/can_helpers.h"
+#include "packages/common/can/can_messages.h"
+#include "packages/common/can/can_nodes.h"
+
+#include "packages/linux/can/CANMessage.h"
+
+// ----------------------------------------------------------------------------------------
+
+Poco::RWLock MotionStatus::sm_rwLock;
+
+// ----------------------------------------------------------------------------------------
+
+MotionStatus::MotionStatus()
+    : Poco::Runnable(),
+      m_quitEvent( true /* auto-reset */ )
+{
+}
+
+// ----------------------------------------------------------------------------------------
+
+MotionStatus::~MotionStatus()
+{
+}
+
+// ----------------------------------------------------------------------------------------
+
+void MotionStatus::timeToQuit()
+{
+    m_quitEvent.set();
+}
+
+// ----------------------------------------------------------------------------------------
+
+void MotionStatus::run()
+{
+    for ( ;; )
+    {
+        try
+        {
+            Poco::RWLock::ScopedReadLock lock( sm_rwLock );
+
+            uint32_t msgid = can_build_message_id( can_node_odr_motion,
+                                                   can_node_broadcast,
+                                                   can_dataid_heartbeat );
+
+            CANMessage::QueueToSend( new CANMessage( msgid ) );
+
+        }
+        catch ( ... )
+        {
+            // nothing to do, but don't stop the thread
+        }
+
+        if ( m_quitEvent.tryWait( 1250 /* milliseconds */ ) )
+        {
+            return;
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/robots/odr-sim/MotionStatus.h	Sat Jul 12 17:22:55 2014 -0700
@@ -0,0 +1,62 @@
+// ----------------------------------------------------------------------------------------
+//
+//  robots/odr-sim/MotionStatus.h
+//    
+//  Bob Cook Development, Robotics Library
+//  http://www.bobcookdev.com/rl/
+// 
+//  Thread that emulates the "ODR motion controller" node.
+//
+//  Copyright (c) 2014 Bob Cook
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------------------
+
+#ifndef BCDRL_ROBOTS_ODRSIM_MOTIONSTATUS_H
+#define BCDRL_ROBOTS_ODRSIM_MOTIONSTATUS_H
+
+#include <Poco/Event.h>
+#include <Poco/Runnable.h>
+#include <Poco/RWLock.h>
+
+// ----------------------------------------------------------------------------------------
+
+class MotionStatus : public Poco::Runnable
+{
+    public:
+        // static void set...( bool value );
+
+    public:
+        MotionStatus();
+        virtual ~MotionStatus();
+        virtual void run();
+        void timeToQuit();
+
+    private:
+        static Poco::RWLock sm_rwLock;
+
+    private:
+        Poco::Event m_quitEvent;
+};
+
+// ----------------------------------------------------------------------------------------
+#endif // #ifndef BCDRL_ROBOTS_ODRSIM_MOTIONSTATUS_H
+// ----------------------------------------------------------------------------------------
+
--- a/main/robots/odr-sim/Receiver.cpp	Sat Jul 12 17:21:10 2014 -0700
+++ b/main/robots/odr-sim/Receiver.cpp	Sat Jul 12 17:22:55 2014 -0700
@@ -89,27 +89,27 @@
 
 // ----------------------------------------------------------------------------------------
 
-void Receiver::recvMotorSpeed( CANMessage* msg )
+void Receiver::recvWheelSpeed( CANMessage* msg )
 {
     can_data_wheel_speed data;
     msg->msgData( reinterpret_cast< uint8_t* >( &data ), sizeof( data ) );
 
     if ( m_display )
     {
-        m_display->updateMotorSpeeds( data.rpm_front, data.rpm_rear );
+        m_display->updateWheelSpeeds( data.rpm_front, data.rpm_rear );
     }
 }
 
 // ----------------------------------------------------------------------------------------
 
-void Receiver::recvServoPosition( CANMessage* msg )
+void Receiver::recvWheelPosition( CANMessage* msg )
 {
     can_data_wheel_position data;
     msg->msgData( reinterpret_cast< uint8_t* >( &data ), sizeof( data ) );
 
     if ( m_display )
     {
-        m_display->updateServoPositions( data.angle_front, data.angle_rear );
+        m_display->updateWheelPositions( data.angle_front, data.angle_rear );
     }
 }
 
@@ -166,11 +166,11 @@
                     break;
 
                 case can_dataid_wheel_speed:
-                    recvMotorSpeed( msg );
+                    recvWheelSpeed( msg );
                     break;
 
                 case can_dataid_wheel_position:
-                    recvServoPosition( msg );
+                    recvWheelPosition( msg );
                     break;
 
                 case can_dataid_sonar_front_enable:
--- a/main/robots/odr-sim/Receiver.h	Sat Jul 12 17:21:10 2014 -0700
+++ b/main/robots/odr-sim/Receiver.h	Sat Jul 12 17:22:55 2014 -0700
@@ -60,8 +60,8 @@
 
     private:
         void recvMgrUpdate( CANMessage* msg );
-        void recvServoPosition( CANMessage* msg );
-        void recvMotorSpeed( CANMessage* msg );
+        void recvWheelPosition( CANMessage* msg );
+        void recvWheelSpeed( CANMessage* msg );
         void recvSonarFrontStateChange( bool enabled );
 };
 
--- a/main/robots/odr-sim/SimDisplay.cpp	Sat Jul 12 17:21:10 2014 -0700
+++ b/main/robots/odr-sim/SimDisplay.cpp	Sat Jul 12 17:22:55 2014 -0700
@@ -7,7 +7,7 @@
 //
 //  Window display for the ODR platform simulator.
 //
-//  Copyright (c) 2011-2013 Bob Cook
+//  Copyright (c) 2011-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -48,16 +48,18 @@
 
 #include <Poco/Thread.h>
 
-#include "ControllerStatus.h"
+#include "DisplayStatus.h"
+#include "GpsStatus.h"
 #include "ImuStatus.h"
+#include "MotionStatus.h"
 #include "SonarFrontStatus.h"
 
 // ----------------------------------------------------------------------------------------
 
-static void SendControllerUpdateCB( Fl_Widget* widget, void* value )
+static void DoDisplayStatusCB( Fl_Widget* widget, void* value )
 {
-    static ControllerStatus s_csRunnable;
-    static Poco::Thread     s_csThread;
+    static DisplayStatus s_dsRunnable;
+    static Poco::Thread  s_dsThread;
 
     Fl_Light_Button* button = dynamic_cast< Fl_Light_Button* >( widget );
     if ( button == 0 )
@@ -68,40 +70,66 @@
     if ( button->value() == 0 )
     {
         // off
-        s_csRunnable.timeToQuit();
-        s_csThread.join();
+        s_dsRunnable.timeToQuit();
+        s_dsThread.join();
     }
     else
     {
         // on
-        s_csThread.start( s_csRunnable );
+        s_dsThread.start( s_dsRunnable );
     }
 }
 
 // ----------------------------------------------------------------------------------------
 
-static void PressEstopCB( Fl_Widget* widget, void* value )
+static void DoGpsStatusCB( Fl_Widget* widget, void* value )
 {
+    static GpsStatus    s_gsRunnable;
+    static Poco::Thread s_gsThread;
+
     Fl_Light_Button* button = dynamic_cast< Fl_Light_Button* >( widget );
     if ( button == 0 )
     {
-        return; // opps, not what we thought?!
+        return; // oops, not what we thought?!
     }
 
-    ControllerStatus::setEstopActive( button->value() != 0 );
+    if ( button->value() == 0 )
+    {
+        // off
+        s_gsRunnable.timeToQuit();
+        s_gsThread.join();
+    }
+    else
+    {
+        // on
+        s_gsThread.start( s_gsRunnable );
+    }
 }
 
 // ----------------------------------------------------------------------------------------
 
-static void PressMotorCtlCB( Fl_Widget* widget, void* value )
+static void DoMotionStatusCB( Fl_Widget* widget, void* value )
 {
+    static MotionStatus s_msRunnable;
+    static Poco::Thread s_msThread;
+
     Fl_Light_Button* button = dynamic_cast< Fl_Light_Button* >( widget );
     if ( button == 0 )
     {
-        return; // opps, not what we thought?!
+        return; // oops, not what we thought?!
     }
 
-    ControllerStatus::setMotorCtlActive( button->value() != 0 );
+    if ( button->value() == 0 )
+    {
+        // off
+        s_msRunnable.timeToQuit();
+        s_msThread.join();
+    }
+    else
+    {
+        // on
+        s_msThread.start( s_msRunnable );
+    }
 }
 
 // ----------------------------------------------------------------------------------------
@@ -114,7 +142,7 @@
         return; // opps, not what we thought?!
     }
 
-    ControllerStatus::setButtonOne( button->value() != 0 );
+    //ControllerStatus::setButtonOne( button->value() != 0 );
 }
 
 // ----------------------------------------------------------------------------------------
@@ -127,7 +155,7 @@
         return; // opps, not what we thought?!
     }
 
-    ControllerStatus::setButtonTwo( button->value() != 0 );
+    //ControllerStatus::setButtonTwo( button->value() != 0 );
 }
 
 // ----------------------------------------------------------------------------------------
@@ -319,20 +347,20 @@
 
 SimDisplay::SimDisplay()
     : m_window( 0 ),
-      m_dialMotorSpeedFront( 0 ),
-      m_textMotorSpeedFront( 0 ),
-      m_dialMotorSpeedRear( 0 ),
-      m_textMotorSpeedRear( 0 ),
-      m_sliderServoPosFront( 0 ),
-      m_textServoPosFront( 0 ),
-      m_sliderServoPosRear( 0 ),
-      m_textServoPosRear( 0 ),
+      m_dialWheelSpeedFront( 0 ),
+      m_textWheelSpeedFront( 0 ),
+      m_dialWheelSpeedRear( 0 ),
+      m_textWheelSpeedRear( 0 ),
+      m_sliderWheelPosFront( 0 ),
+      m_textWheelPosFront( 0 ),
+      m_sliderWheelPosRear( 0 ),
+      m_textWheelPosRear( 0 ),
       m_boxMgrHeartbeat( 0 ),
       m_textManagerMsg( 0 ),
       m_boxSonarFrontState( 0 ),
-      m_buttonSendCtlUpdate( 0 ),
-      m_buttonEstop( 0 ),
-      m_buttonMotorCtl( 0 ),
+      m_buttonDisplayAlive( 0 ),
+      m_buttonGpsAlive( 0 ),
+      m_buttonMotionAlive( 0 ),
       m_buttonA( 0 ),
       m_buttonB( 0 ),
       m_buttonSonarFrontKA( 0 ),
@@ -365,60 +393,60 @@
 
 // ----------------------------------------------------------------------------------------
 
-void SimDisplay::createMotorSpeedDials()
+void SimDisplay::createWheelSpeedDials()
 {
     m_window->begin();
 
     // front
     
-    Fl_Box* labelMotorSpeedFront = new Fl_Box( 10, 10, 75, 20 );
-    if ( labelMotorSpeedFront )
+    Fl_Box* labelWheelSpeedFront = new Fl_Box( 10, 10, 75, 20 );
+    if ( labelWheelSpeedFront )
     {
-        labelMotorSpeedFront->box( FL_NO_BOX );
-        labelMotorSpeedFront->align( FL_ALIGN_CENTER );
-        labelMotorSpeedFront->label( "Front Motor" );
+        labelWheelSpeedFront->box( FL_NO_BOX );
+        labelWheelSpeedFront->align( FL_ALIGN_CENTER );
+        labelWheelSpeedFront->label( "Front Speed" );
     }
 
-    m_dialMotorSpeedFront = new Fl_Line_Dial( 10, 35, 75, 75 );
-    if ( m_dialMotorSpeedFront )
+    m_dialWheelSpeedFront = new Fl_Line_Dial( 10, 35, 75, 75 );
+    if ( m_dialWheelSpeedFront )
     {
-        m_dialMotorSpeedFront->box( FL_ROUND_UP_BOX );
-        m_dialMotorSpeedFront->bounds( -128.0, 128.0 );
-        m_dialMotorSpeedFront->set_output();
+        m_dialWheelSpeedFront->box( FL_ROUND_UP_BOX );
+        m_dialWheelSpeedFront->bounds( -128.0, 128.0 );
+        m_dialWheelSpeedFront->set_output();
     }
 
-    m_textMotorSpeedFront = new Fl_Box( 10, 115, 75, 20 );
-    if ( m_textMotorSpeedFront )
+    m_textWheelSpeedFront = new Fl_Box( 10, 115, 75, 20 );
+    if ( m_textWheelSpeedFront )
     {
-        m_textMotorSpeedFront->box( FL_THIN_DOWN_BOX );
-        m_textMotorSpeedFront->align( FL_ALIGN_CENTER );
-        m_textMotorSpeedFront->label( "0" );
+        m_textWheelSpeedFront->box( FL_THIN_DOWN_BOX );
+        m_textWheelSpeedFront->align( FL_ALIGN_CENTER );
+        m_textWheelSpeedFront->label( "0" );
     }
 
     // rear
 
-    Fl_Box* labelMotorSpeedRear = new Fl_Box( 100, 10, 75, 20 );
-    if ( labelMotorSpeedRear )
+    Fl_Box* labelWheelSpeedRear = new Fl_Box( 100, 10, 75, 20 );
+    if ( labelWheelSpeedRear )
     {
-        labelMotorSpeedRear->box( FL_NO_BOX );
-        labelMotorSpeedRear->align( FL_ALIGN_CENTER );
-        labelMotorSpeedRear->label( "Rear Motor" );
+        labelWheelSpeedRear->box( FL_NO_BOX );
+        labelWheelSpeedRear->align( FL_ALIGN_CENTER );
+        labelWheelSpeedRear->label( "Rear Wheels" );
     }
 
-    m_dialMotorSpeedRear = new Fl_Line_Dial( 100, 35, 75, 75 );
-    if ( m_dialMotorSpeedRear )
+    m_dialWheelSpeedRear = new Fl_Line_Dial( 100, 35, 75, 75 );
+    if ( m_dialWheelSpeedRear )
     {
-        m_dialMotorSpeedRear->box( FL_ROUND_UP_BOX );
-        m_dialMotorSpeedRear->bounds( -128.0, 128.0 );
-        m_dialMotorSpeedRear->set_output();
+        m_dialWheelSpeedRear->box( FL_ROUND_UP_BOX );
+        m_dialWheelSpeedRear->bounds( -128.0, 128.0 );
+        m_dialWheelSpeedRear->set_output();
     }
 
-    m_textMotorSpeedRear = new Fl_Box( 100, 115, 75, 20 );
-    if ( m_textMotorSpeedRear )
+    m_textWheelSpeedRear = new Fl_Box( 100, 115, 75, 20 );
+    if ( m_textWheelSpeedRear )
     {
-        m_textMotorSpeedRear->box( FL_THIN_DOWN_BOX );
-        m_textMotorSpeedRear->align( FL_ALIGN_CENTER );
-        m_textMotorSpeedRear->label( "0" );
+        m_textWheelSpeedRear->box( FL_THIN_DOWN_BOX );
+        m_textWheelSpeedRear->align( FL_ALIGN_CENTER );
+        m_textWheelSpeedRear->label( "0" );
     }
 
     m_window->end();
@@ -426,60 +454,60 @@
 
 // ----------------------------------------------------------------------------------------
 
-void SimDisplay::createServoSliders()
+void SimDisplay::createWheelSliders()
 {
     m_window->begin();
 
     // front
     
-    Fl_Box* labelServoPosFront = new Fl_Box( 10, 150, 75, 20 );
-    if ( labelServoPosFront )
+    Fl_Box* labelWheelPosFront = new Fl_Box( 10, 150, 75, 20 );
+    if ( labelWheelPosFront )
     {
-        labelServoPosFront->box( FL_NO_BOX );
-        labelServoPosFront->align( FL_ALIGN_CENTER );
-        labelServoPosFront->label( "Front Servo" );
+        labelWheelPosFront->box( FL_NO_BOX );
+        labelWheelPosFront->align( FL_ALIGN_CENTER );
+        labelWheelPosFront->label( "Front Position" );
     }
 
-    m_sliderServoPosFront = new Fl_Hor_Slider( 10, 175, 75, 20 );
-    if ( m_sliderServoPosFront )
+    m_sliderWheelPosFront = new Fl_Hor_Slider( 10, 175, 75, 20 );
+    if ( m_sliderWheelPosFront )
     {
-        m_sliderServoPosFront->slider( FL_UP_BOX );
-        m_sliderServoPosFront->bounds( -12.0, 12.0 );
-        m_sliderServoPosFront->set_output();
+        m_sliderWheelPosFront->slider( FL_UP_BOX );
+        m_sliderWheelPosFront->bounds( -12.0, 12.0 );
+        m_sliderWheelPosFront->set_output();
     }
 
-    m_textServoPosFront = new Fl_Box( 10, 200, 75, 20 );
-    if ( m_textServoPosFront )
+    m_textWheelPosFront = new Fl_Box( 10, 200, 75, 20 );
+    if ( m_textWheelPosFront )
     {
-        m_textServoPosFront->box( FL_THIN_DOWN_BOX );
-        m_textServoPosFront->align( FL_ALIGN_CENTER );
-        m_textServoPosFront->label( "0" );
+        m_textWheelPosFront->box( FL_THIN_DOWN_BOX );
+        m_textWheelPosFront->align( FL_ALIGN_CENTER );
+        m_textWheelPosFront->label( "0" );
     }
 
     // rear
    
-    Fl_Box* labelServoPosRear = new Fl_Box( 100, 150, 75, 20 );
-    if ( labelServoPosRear )
+    Fl_Box* labelWheelPosRear = new Fl_Box( 100, 150, 75, 20 );
+    if ( labelWheelPosRear )
     {
-        labelServoPosRear->box( FL_NO_BOX );
-        labelServoPosRear->align( FL_ALIGN_CENTER );
-        labelServoPosRear->label( "Rear Servo" );
+        labelWheelPosRear->box( FL_NO_BOX );
+        labelWheelPosRear->align( FL_ALIGN_CENTER );
+        labelWheelPosRear->label( "Rear Wheel" );
     }
 
-    m_sliderServoPosRear = new Fl_Hor_Slider( 100, 175, 75, 20 );
-    if ( m_sliderServoPosRear )
+    m_sliderWheelPosRear = new Fl_Hor_Slider( 100, 175, 75, 20 );
+    if ( m_sliderWheelPosRear )
     {
-        m_sliderServoPosRear->slider( FL_UP_BOX );
-        m_sliderServoPosRear->bounds( -12.0, 12.0 );
-        m_sliderServoPosRear->set_output();
+        m_sliderWheelPosRear->slider( FL_UP_BOX );
+        m_sliderWheelPosRear->bounds( -12.0, 12.0 );
+        m_sliderWheelPosRear->set_output();
     }
 
-    m_textServoPosRear = new Fl_Box( 100, 200, 75, 20 );
-    if ( m_textServoPosRear )
+    m_textWheelPosRear = new Fl_Box( 100, 200, 75, 20 );
+    if ( m_textWheelPosRear )
     {
-        m_textServoPosRear->box( FL_THIN_DOWN_BOX );
-        m_textServoPosRear->align( FL_ALIGN_CENTER );
-        m_textServoPosRear->label( "0" );
+        m_textWheelPosRear->box( FL_THIN_DOWN_BOX );
+        m_textWheelPosRear->align( FL_ALIGN_CENTER );
+        m_textWheelPosRear->label( "0" );
     }
 
     m_window->end();
@@ -528,32 +556,32 @@
 {
     m_window->begin();
 
-    m_buttonSendCtlUpdate = new Fl_Light_Button( 250, 20, 165, 20 );
-    if ( m_buttonSendCtlUpdate )
+    m_buttonDisplayAlive = new Fl_Light_Button( 250, 20, 165, 20 );
+    if ( m_buttonDisplayAlive )
     {
-        m_buttonSendCtlUpdate->label( "Do Controller Updates" );
-        m_buttonSendCtlUpdate->selection_color( FL_GREEN );
-        m_buttonSendCtlUpdate->callback( &SendControllerUpdateCB );
-        m_buttonSendCtlUpdate->set();
-        m_buttonSendCtlUpdate->do_callback();
+        m_buttonDisplayAlive->label( "Display Alive" );
+        m_buttonDisplayAlive->selection_color( FL_GREEN );
+        m_buttonDisplayAlive->callback( &DoDisplayStatusCB );
+        //m_buttonDisplayAlive->set();
+        //m_buttonDisplayAlive->do_callback();
     }
 
-    m_buttonEstop = new Fl_Light_Button( 250, 50, 165, 20 );
-    if ( m_buttonEstop )
+    m_buttonGpsAlive = new Fl_Light_Button( 250, 50, 165, 20 );
+    if ( m_buttonGpsAlive )
     {
-        m_buttonEstop->label( "Remote ESTOP" );
-        m_buttonEstop->selection_color( FL_RED );
-        m_buttonEstop->callback( &PressEstopCB );
-        m_buttonEstop->set();
-        m_buttonEstop->do_callback();
+        m_buttonGpsAlive->label( "GPS Alive" );
+        m_buttonGpsAlive->selection_color( FL_GREEN );
+        m_buttonGpsAlive->callback( &DoGpsStatusCB );
+        //m_buttonGpsAlive->set();
+        //m_buttonGpsAlive->do_callback();
     }
 
-    m_buttonMotorCtl = new Fl_Light_Button( 250, 80, 165, 20 );
-    if ( m_buttonMotorCtl )
+    m_buttonMotionAlive = new Fl_Light_Button( 250, 80, 165, 20 );
+    if ( m_buttonMotionAlive )
     {
-        m_buttonMotorCtl->label( "Motor Controller" );
-        m_buttonMotorCtl->selection_color( FL_GREEN );
-        m_buttonMotorCtl->callback( &PressMotorCtlCB );
+        m_buttonMotionAlive->label( "Motion Control Alive" );
+        m_buttonMotionAlive->selection_color( FL_GREEN );
+        m_buttonMotionAlive->callback( &DoMotionStatusCB );
     }
 
     m_buttonA = new Fl_Toggle_Button( 250, 110, 80, 20 );
@@ -700,8 +728,8 @@
 
     if ( m_window )
     {
-        createMotorSpeedDials();
-        createServoSliders();
+        createWheelSpeedDials();
+        createWheelSliders();
         createDisplays();
         createActionButtons();
         createImuControls();
@@ -713,41 +741,41 @@
 
 // ----------------------------------------------------------------------------------------
 
-void SimDisplay::updateMotorSpeeds( int front, int rear )
+void SimDisplay::updateWheelSpeeds( int front, int rear )
 {
     Fl::lock();
 
     // front
 
-    if ( m_dialMotorSpeedFront )
+    if ( m_dialWheelSpeedFront )
     {
-        m_dialMotorSpeedFront->value( 
-                m_dialMotorSpeedFront->clamp( static_cast< double >( front ) ) );
+        m_dialWheelSpeedFront->value( 
+                m_dialWheelSpeedFront->clamp( static_cast< double >( front ) ) );
     }
 
-    if ( m_textMotorSpeedFront )
+    if ( m_textWheelSpeedFront )
     {
         char buf[ 20 ];
         snprintf( buf, sizeof( buf ), "%d", front );
-        m_textMotorSpeedFront->label( buf );
+        m_textWheelSpeedFront->label( buf );
     }
 
     Fl::flush();
 
     // rear
 
-    if ( m_dialMotorSpeedRear )
+    if ( m_dialWheelSpeedRear )
     {
-        m_dialMotorSpeedRear->value( 
-                m_dialMotorSpeedRear->clamp( static_cast< double >( rear ) ) );
-        m_dialMotorSpeedRear->redraw();
+        m_dialWheelSpeedRear->value( 
+                m_dialWheelSpeedRear->clamp( static_cast< double >( rear ) ) );
+        m_dialWheelSpeedRear->redraw();
     }
 
-    if ( m_textMotorSpeedRear )
+    if ( m_textWheelSpeedRear )
     {
         char buf[ 20 ];
         snprintf( buf, sizeof( buf ), "%d", rear );
-        m_textMotorSpeedRear->label( buf );
+        m_textWheelSpeedRear->label( buf );
     }
 
     Fl::flush();
@@ -757,40 +785,40 @@
 
 // ----------------------------------------------------------------------------------------
 
-void SimDisplay::updateServoPositions( int front, int rear )
+void SimDisplay::updateWheelPositions( int front, int rear )
 {
     Fl::lock();
    
    // front
 
-    if ( m_sliderServoPosFront )
+    if ( m_sliderWheelPosFront )
     {
-        m_sliderServoPosFront->value( 
-                m_sliderServoPosFront->clamp( static_cast< double >( front ) ) );
+        m_sliderWheelPosFront->value( 
+                m_sliderWheelPosFront->clamp( static_cast< double >( front ) ) );
     }
 
-    if ( m_textServoPosFront )
+    if ( m_textWheelPosFront )
     {
         char buf[ 20 ];
         snprintf( buf, sizeof( buf ), "%d", front );
-        m_textServoPosFront->label( buf );
+        m_textWheelPosFront->label( buf );
     }
 
     Fl::flush();
 
     // rear
     
-    if ( m_sliderServoPosRear )
+    if ( m_sliderWheelPosRear )
     {
-        m_sliderServoPosRear->value( 
-                m_sliderServoPosRear->clamp( static_cast< double >( rear ) ) );
+        m_sliderWheelPosRear->value( 
+                m_sliderWheelPosRear->clamp( static_cast< double >( rear ) ) );
     }
 
-    if ( m_textServoPosRear )
+    if ( m_textWheelPosRear )
     {
         char buf[ 20 ];
         snprintf( buf, sizeof( buf ), "%d", rear );
-        m_textServoPosRear->label( buf );
+        m_textWheelPosRear->label( buf );
     }
 
     Fl::flush();
--- a/main/robots/odr-sim/SimDisplay.h	Sat Jul 12 17:21:10 2014 -0700
+++ b/main/robots/odr-sim/SimDisplay.h	Sat Jul 12 17:22:55 2014 -0700
@@ -7,7 +7,7 @@
 //    
 //  Window display for the ODR platform simulator.
 //
-//  Copyright (c) 2011 Bob Cook
+//  Copyright (c) 2011-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -53,8 +53,8 @@
         SimDisplay();
         virtual ~SimDisplay();
         void showDisplay();
-        void updateMotorSpeeds( int front, int rear );
-        void updateServoPositions( int front, int rear );
+        void updateWheelSpeeds( int front, int rear );
+        void updateWheelPositions( int front, int rear );
         void updateManagerMsg( const char* msg, int length );
         void doMgrHeartbeat();
         void resetMgrHeartbeat();
@@ -64,20 +64,20 @@
 
     private:
         Fl_Double_Window* m_window;
-        Fl_Line_Dial*     m_dialMotorSpeedFront;
-        Fl_Box*           m_textMotorSpeedFront;
-        Fl_Line_Dial*     m_dialMotorSpeedRear;
-        Fl_Box*           m_textMotorSpeedRear;
-        Fl_Hor_Slider*    m_sliderServoPosFront;
-        Fl_Box*           m_textServoPosFront;
-        Fl_Hor_Slider*    m_sliderServoPosRear;
-        Fl_Box*           m_textServoPosRear;
+        Fl_Line_Dial*     m_dialWheelSpeedFront;
+        Fl_Box*           m_textWheelSpeedFront;
+        Fl_Line_Dial*     m_dialWheelSpeedRear;
+        Fl_Box*           m_textWheelSpeedRear;
+        Fl_Hor_Slider*    m_sliderWheelPosFront;
+        Fl_Box*           m_textWheelPosFront;
+        Fl_Hor_Slider*    m_sliderWheelPosRear;
+        Fl_Box*           m_textWheelPosRear;
         Fl_Box*           m_boxMgrHeartbeat;
         Fl_Box*           m_textManagerMsg;
         Fl_Box*           m_boxSonarFrontState;
-        Fl_Light_Button*  m_buttonSendCtlUpdate;
-        Fl_Light_Button*  m_buttonEstop;
-        Fl_Light_Button*  m_buttonMotorCtl;
+        Fl_Light_Button*  m_buttonDisplayAlive;
+        Fl_Light_Button*  m_buttonGpsAlive;
+        Fl_Light_Button*  m_buttonMotionAlive;
         Fl_Toggle_Button* m_buttonA;
         Fl_Toggle_Button* m_buttonB;
         Fl_Light_Button*  m_buttonImuKA;
@@ -95,8 +95,8 @@
 
     private:
         void createWindow();
-        void createMotorSpeedDials();
-        void createServoSliders();
+        void createWheelSpeedDials();
+        void createWheelSliders();
         void createDisplays();
         void createActionButtons();
         void createImuControls();
--- a/main/robots/odr-sim/jamfile	Sat Jul 12 17:21:10 2014 -0700
+++ b/main/robots/odr-sim/jamfile	Sat Jul 12 17:22:55 2014 -0700
@@ -36,8 +36,10 @@
 ubuntu_executable odr-sim
     : main.cpp
       ODRSimApp.cpp
-      ControllerStatus.cpp 
+      DisplayStatus.cpp
+      GpsStatus.cpp
       ImuStatus.cpp
+      MotionStatus.cpp
       Receiver.cpp 
       SimDisplay.cpp 
       SonarFrontStatus.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/robots/odr-sim/odrsim.log	Sat Jul 12 17:22:55 2014 -0700
@@ -0,0 +1,316 @@
+I 12/30/11-15:41:54.638594 ------------------------------------------------------
+I 12/30/11-15:41:54.638893 ODR H/W Simulator startup
+I 12/30/11-15:41:54.638909 ODRSimApp::main() started
+I 12/30/11-15:41:54.639032 using CANbus interface name "can0"
+I 12/30/11-15:41:54.740234 CAN frame send: [02:00:0012] 09                   .
+I 12/30/11-15:42:11.398476 CAN frame send: [02:00:0012] 09                   .
+I 12/30/11-15:42:13.911409 CAN frame send: [02:00:0012] 09                   .
+I 12/30/11-15:42:16.431669 CAN frame send: [02:00:0012] 09                   .
+I 12/30/11-15:42:18.947417 CAN frame send: [02:00:0012] 09                   .
+I 12/30/11-15:42:21.466028 CAN frame send: [02:00:0012] 08                   .
+I 12/30/11-15:42:23.983330 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:25.720028 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:26.426648 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:28.223911 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:28.930324 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:30.727640 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:31.432743 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:33.233196 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:33.938857 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:35.737285 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:36.443286 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:38.240750 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:38.944917 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:40.743815 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:41.448870 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:43.248206 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:43.954355 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:45.752622 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:46.458559 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:48.258283 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:48.965882 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:50.762645 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:51.468553 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:53.266126 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:53.973406 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:55.770770 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:56.476359 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:42:58.274529 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:42:58.978542 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:43:00.776061 CAN frame send: [03:00:0131]                      
+I 12/30/11-15:43:01.479613 CAN frame send: [02:00:0012] 0A                   .
+I 12/30/11-15:43:02.485439 ODR H/W Simulator shutdown
+I 12/30/11-15:44:09.586276 ------------------------------------------------------
+I 12/30/11-15:44:09.586532 ODR H/W Simulator startup
+I 12/30/11-15:44:09.586548 ODRSimApp::main() started
+I 12/30/11-15:44:09.586655 using CANbus interface name "can0"
+I 12/30/11-15:46:06.045971 ODR H/W Simulator shutdown
+I 12/30/11-15:50:52.906067 ------------------------------------------------------
+I 12/30/11-15:50:52.906316 ODR H/W Simulator startup
+I 12/30/11-15:50:52.906331 ODRSimApp::main() started
+I 12/30/11-15:50:52.906434 using CANbus interface name "can0"
+I 12/30/11-15:53:14.681129 ODR H/W Simulator shutdown
+I 01/13/12-05:29:48.828683 ------------------------------------------------------
+I 01/13/12-05:29:48.838202 ODR H/W Simulator startup
+I 01/13/12-05:29:48.838220 ODRSimApp::main() started
+I 01/13/12-05:29:48.838326 using CANbus interface name "can0"
+I 01/13/12-05:30:27.861651 ODR H/W Simulator shutdown
+I 02/11/12-20:00:09.841334 ------------------------------------------------------
+I 02/11/12-20:00:10.044188 ODR H/W Simulator startup
+I 02/11/12-20:00:10.044232 ODRSimApp::main() started
+I 02/11/12-20:00:10.044382 using CANbus interface name "can0"
+I 02/11/12-20:01:44.293176 ODR H/W Simulator shutdown
+I 02/11/12-22:09:02.353065 ------------------------------------------------------
+I 02/11/12-22:09:02.353311 ODR H/W Simulator startup
+I 02/11/12-22:09:02.353327 ODRSimApp::main() started
+I 02/11/12-22:09:02.353429 using CANbus interface name "can0"
+I 02/11/12-22:11:38.319707 ODR H/W Simulator shutdown
+I 02/12/12-18:43:38.707217 ------------------------------------------------------
+I 02/12/12-18:43:38.707452 ODR H/W Simulator startup
+I 02/12/12-18:43:38.707467 ODRSimApp::main() started
+I 02/12/12-18:43:38.707568 using CANbus interface name "can0"
+I 02/12/12-18:46:10.109877 ODR H/W Simulator shutdown
+I 06/09/12-19:53:40.084032 ------------------------------------------------------
+I 06/09/12-19:53:40.118266 ODR H/W Simulator startup
+I 06/09/12-19:53:40.118307 ODRSimApp::main() started
+I 06/09/12-19:53:40.118446 using CANbus interface name "can0"
+I 06/09/12-20:01:09.281913 ODR H/W Simulator shutdown
+I 06/09/12-20:16:00.804035 ------------------------------------------------------
+I 06/09/12-20:16:00.804261 ODR H/W Simulator startup
+I 06/09/12-20:16:00.804277 ODRSimApp::main() started
+I 06/09/12-20:16:00.804378 using CANbus interface name "can0"
+I 07/08/12-00:04:43.311729 ------------------------------------------------------
+I 07/08/12-00:04:43.333980 ODR H/W Simulator startup
+I 07/08/12-00:04:43.334026 ODRSimApp::main() started
+I 07/08/12-00:04:43.334173 using CANbus interface name "can0"
+I 07/08/12-00:05:00.460464 ODR H/W Simulator shutdown
+I 07/08/12-00:09:37.061681 ------------------------------------------------------
+I 07/08/12-00:09:37.061906 ODR H/W Simulator startup
+I 07/08/12-00:09:37.061922 ODRSimApp::main() started
+I 07/08/12-00:09:37.062025 using CANbus interface name "can0"
+I 07/08/12-00:09:50.248281 ODR H/W Simulator shutdown
+I 07/08/12-00:10:51.106037 ------------------------------------------------------
+I 07/08/12-00:10:51.106729 ODR H/W Simulator startup
+I 07/08/12-00:10:51.106745 ODRSimApp::main() started
+I 07/08/12-00:10:51.106849 using CANbus interface name "can0"
+I 07/08/12-00:11:03.599376 ODR H/W Simulator shutdown
+I 02/09/13-20:54:32.547108 ------------------------------------------------------
+I 02/09/13-20:54:32.552550 ODR H/W Simulator startup
+I 02/09/13-20:54:32.552582 ODRSimApp::main() started
+I 02/09/13-20:54:32.552698 using CANbus interface name "can0"
+I 02/09/13-20:54:56.482210 ODR H/W Simulator shutdown
+I 08/10/13-21:23:54.877694 ------------------------------------------------------
+I 08/10/13-21:23:54.877985 ODR H/W Simulator startup
+I 08/10/13-21:23:54.877999 ODRSimApp::main() started
+I 08/10/13-21:23:54.878076 using CANbus interface name "can0"
+I 08/10/13-21:25:15.574660 ODR H/W Simulator shutdown
+I 08/10/13-21:32:15.271464 ------------------------------------------------------
+I 08/10/13-21:32:15.271537 ODR H/W Simulator startup
+I 08/10/13-21:32:15.271546 ODRSimApp::main() started
+I 08/10/13-21:32:15.271615 using CANbus interface name "can0"
+I 08/10/13-21:32:22.317674 ODR H/W Simulator shutdown
+I 08/10/13-21:33:55.119721 ------------------------------------------------------
+I 08/10/13-21:33:55.119801 ODR H/W Simulator startup
+I 08/10/13-21:33:55.119810 ODRSimApp::main() started
+I 08/10/13-21:33:55.119876 using CANbus interface name "can0"
+I 08/10/13-21:34:07.921040 ODR H/W Simulator shutdown
+I 08/10/13-21:35:12.551851 ------------------------------------------------------
+I 08/10/13-21:35:12.551922 ODR H/W Simulator startup
+I 08/10/13-21:35:12.551931 ODRSimApp::main() started
+I 08/10/13-21:35:12.551994 using CANbus interface name "can0"
+I 08/10/13-21:35:29.196782 ODR H/W Simulator shutdown
+I 08/10/13-21:36:14.001590 ------------------------------------------------------
+I 08/10/13-21:36:14.001661 ODR H/W Simulator startup
+I 08/10/13-21:36:14.001671 ODRSimApp::main() started
+I 08/10/13-21:36:14.001747 using CANbus interface name "can0"
+I 08/10/13-21:36:38.997458 ODR H/W Simulator shutdown
+I 08/10/13-21:38:56.914045 ------------------------------------------------------
+I 08/10/13-21:38:56.914115 ODR H/W Simulator startup
+I 08/10/13-21:38:56.914124 ODRSimApp::main() started
+I 08/10/13-21:38:56.914190 using CANbus interface name "can0"
+I 08/10/13-21:39:00.031050 ODR H/W Simulator shutdown
+I 08/10/13-21:39:32.102198 ------------------------------------------------------
+I 08/10/13-21:39:32.102277 ODR H/W Simulator startup
+I 08/10/13-21:39:32.102285 ODRSimApp::main() started
+I 08/10/13-21:39:32.102352 using CANbus interface name "can0"
+I 08/10/13-21:39:36.025963 ODR H/W Simulator shutdown
+I 08/10/13-21:40:52.166575 ------------------------------------------------------
+I 08/10/13-21:40:52.166650 ODR H/W Simulator startup
+I 08/10/13-21:40:52.166659 ODRSimApp::main() started
+I 08/10/13-21:40:52.166727 using CANbus interface name "can0"
+I 08/10/13-21:41:06.948733 ODR H/W Simulator shutdown
+I 08/10/13-21:43:05.306256 ------------------------------------------------------
+I 08/10/13-21:43:05.306336 ODR H/W Simulator startup
+I 08/10/13-21:43:05.306346 ODRSimApp::main() started
+I 08/10/13-21:43:05.306446 using CANbus interface name "can0"
+I 08/10/13-21:43:49.243835 ODR H/W Simulator shutdown
+I 08/10/13-21:44:03.223969 ------------------------------------------------------
+I 08/10/13-21:44:03.224050 ODR H/W Simulator startup
+I 08/10/13-21:44:03.224060 ODRSimApp::main() started
+I 08/10/13-21:44:03.224131 using CANbus interface name "can0"
+I 08/10/13-21:44:17.020165 ODR H/W Simulator shutdown
+I 08/10/13-22:05:58.303742 ------------------------------------------------------
+I 08/10/13-22:05:58.303834 ODR H/W Simulator startup
+I 08/10/13-22:05:58.303876 ODRSimApp::main() started
+I 08/10/13-22:05:58.303973 using CANbus interface name "can0"
+I 08/10/13-22:06:29.378061 ODR H/W Simulator shutdown
+I 08/10/13-22:08:04.788293 ------------------------------------------------------
+I 08/10/13-22:08:04.788383 ODR H/W Simulator startup
+I 08/10/13-22:08:04.788395 ODRSimApp::main() started
+I 08/10/13-22:08:04.788483 using CANbus interface name "can0"
+I 08/10/13-22:08:17.998494 ODR H/W Simulator shutdown
+I 08/10/13-22:09:40.075972 ------------------------------------------------------
+I 08/10/13-22:09:40.076065 ODR H/W Simulator startup
+I 08/10/13-22:09:40.076078 ODRSimApp::main() started
+I 08/10/13-22:09:40.076165 using CANbus interface name "can0"
+I 08/10/13-22:09:44.196287 ODR H/W Simulator shutdown
+I 08/10/13-22:11:30.568274 ------------------------------------------------------
+I 08/10/13-22:11:30.568382 ODR H/W Simulator startup
+I 08/10/13-22:11:30.568392 ODRSimApp::main() started
+I 08/10/13-22:11:30.568462 using CANbus interface name "can0"
+I 08/10/13-22:11:36.005252 ODR H/W Simulator shutdown
+I 08/10/13-22:12:49.786019 ------------------------------------------------------
+I 08/10/13-22:12:49.786092 ODR H/W Simulator startup
+I 08/10/13-22:12:49.786102 ODRSimApp::main() started
+I 08/10/13-22:12:49.786169 using CANbus interface name "can0"
+I 08/10/13-22:13:15.207680 ODR H/W Simulator shutdown
+I 08/10/13-22:17:31.113035 ------------------------------------------------------
+I 08/10/13-22:17:31.113115 ODR H/W Simulator startup
+I 08/10/13-22:17:31.113126 ODRSimApp::main() started
+I 08/10/13-22:17:31.113200 using CANbus interface name "can0"
+I 08/10/13-22:17:44.318427 ODR H/W Simulator shutdown
+I 08/10/13-22:21:52.798099 ------------------------------------------------------
+I 08/10/13-22:21:52.798198 ODR H/W Simulator startup
+I 08/10/13-22:21:52.798211 ODRSimApp::main() started
+I 08/10/13-22:21:52.798303 using CANbus interface name "can0"
+I 08/10/13-22:22:03.473455 ODR H/W Simulator shutdown
+I 08/10/13-22:22:48.510786 ------------------------------------------------------
+I 08/10/13-22:22:48.510859 ODR H/W Simulator startup
+I 08/10/13-22:22:48.510868 ODRSimApp::main() started
+I 08/10/13-22:22:48.510935 using CANbus interface name "can0"
+I 08/10/13-22:22:59.191150 ODR H/W Simulator shutdown
+I 08/10/13-22:27:23.774583 ------------------------------------------------------
+I 08/10/13-22:27:23.774666 ODR H/W Simulator startup
+I 08/10/13-22:27:23.774675 ODRSimApp::main() started
+I 08/10/13-22:27:23.774743 using CANbus interface name "can0"
+I 08/10/13-22:27:34.057964 ODR H/W Simulator shutdown
+I 08/10/13-22:30:07.736631 ------------------------------------------------------
+I 08/10/13-22:30:07.736721 ODR H/W Simulator startup
+I 08/10/13-22:30:07.736733 ODRSimApp::main() started
+I 08/10/13-22:30:07.736821 using CANbus interface name "can0"
+I 08/10/13-22:30:19.627229 ODR H/W Simulator shutdown
+I 08/10/13-22:32:00.890957 ------------------------------------------------------
+I 08/10/13-22:32:00.891272 ODR H/W Simulator startup
+I 08/10/13-22:32:00.891283 ODRSimApp::main() started
+I 08/10/13-22:32:00.891351 using CANbus interface name "can0"
+I 08/10/13-22:32:21.353636 ODR H/W Simulator shutdown
+I 08/10/13-22:35:23.221157 ------------------------------------------------------
+I 08/10/13-22:35:23.221248 ODR H/W Simulator startup
+I 08/10/13-22:35:23.221260 ODRSimApp::main() started
+I 08/10/13-22:35:23.221348 using CANbus interface name "can0"
+I 08/10/13-22:35:42.975009 ODR H/W Simulator shutdown
+I 08/10/13-22:37:16.698070 ------------------------------------------------------
+I 08/10/13-22:37:16.698161 ODR H/W Simulator startup
+I 08/10/13-22:37:16.698173 ODRSimApp::main() started
+I 08/10/13-22:37:16.698260 using CANbus interface name "can0"
+I 08/10/13-22:37:31.712473 ODR H/W Simulator shutdown
+I 08/10/13-22:38:20.493683 ------------------------------------------------------
+I 08/10/13-22:38:20.493757 ODR H/W Simulator startup
+I 08/10/13-22:38:20.493767 ODRSimApp::main() started
+I 08/10/13-22:38:20.493834 using CANbus interface name "can0"
+I 08/10/13-22:38:26.931993 ODR H/W Simulator shutdown
+I 08/10/13-22:38:49.599385 ------------------------------------------------------
+I 08/10/13-22:38:49.599457 ODR H/W Simulator startup
+I 08/10/13-22:38:49.599466 ODRSimApp::main() started
+I 08/10/13-22:38:49.599532 using CANbus interface name "can0"
+I 08/10/13-22:39:14.905809 ODR H/W Simulator shutdown
+I 08/10/13-22:40:30.139337 ------------------------------------------------------
+I 08/10/13-22:40:30.139408 ODR H/W Simulator startup
+I 08/10/13-22:40:30.139418 ODRSimApp::main() started
+I 08/10/13-22:40:30.139504 using CANbus interface name "can0"
+I 08/10/13-22:40:45.960987 ODR H/W Simulator shutdown
+I 08/10/13-22:41:21.006798 ------------------------------------------------------
+I 08/10/13-22:41:21.006887 ODR H/W Simulator startup
+I 08/10/13-22:41:21.006899 ODRSimApp::main() started
+I 08/10/13-22:41:21.007353 using CANbus interface name "can0"
+I 08/10/13-22:41:30.382858 ODR H/W Simulator shutdown
+I 08/10/13-22:42:09.184492 ------------------------------------------------------
+I 08/10/13-22:42:09.184581 ODR H/W Simulator startup
+I 08/10/13-22:42:09.184593 ODRSimApp::main() started
+I 08/10/13-22:42:09.184680 using CANbus interface name "can0"
+I 08/10/13-22:45:23.453537 ODR H/W Simulator shutdown
+I 08/10/13-22:45:44.661356 ------------------------------------------------------
+I 08/10/13-22:45:44.661428 ODR H/W Simulator startup
+I 08/10/13-22:45:44.661437 ODRSimApp::main() started
+I 08/10/13-22:45:44.661504 using CANbus interface name "can0"
+I 08/10/13-22:46:14.046225 ODR H/W Simulator shutdown
+I 08/10/13-23:06:03.703308 ------------------------------------------------------
+I 08/10/13-23:06:03.703389 ODR H/W Simulator startup
+I 08/10/13-23:06:03.703399 ODRSimApp::main() started
+I 08/10/13-23:06:03.703468 using CANbus interface name "can0"
+I 08/10/13-23:06:58.048740 ODR H/W Simulator shutdown
+I 08/10/13-23:10:50.459136 ------------------------------------------------------
+I 08/10/13-23:10:50.459213 ODR H/W Simulator startup
+I 08/10/13-23:10:50.459222 ODRSimApp::main() started
+I 08/10/13-23:10:50.459292 using CANbus interface name "can0"
+I 08/10/13-23:11:37.678220 ODR H/W Simulator shutdown
+I 08/11/13-18:21:33.889143 ------------------------------------------------------
+I 08/11/13-18:21:33.889227 ODR H/W Simulator startup
+I 08/11/13-18:21:33.889236 ODRSimApp::main() started
+I 08/11/13-18:21:33.889318 using CANbus interface name "can0"
+I 08/16/13-02:00:50.781111 ODR H/W Simulator shutdown
+I 08/17/13-18:07:44.662561 ------------------------------------------------------
+I 08/17/13-18:07:44.663440 ODR H/W Simulator startup
+I 08/17/13-18:07:44.663471 ODRSimApp::main() started
+I 08/17/13-18:07:44.663612 using CANbus interface name "can0"
+I 08/17/13-18:09:40.583010 ODR H/W Simulator shutdown
+I 07/12/14-18:25:54.972583 ------------------------------------------------------
+I 07/12/14-18:25:54.973245 ODR H/W Simulator startup
+I 07/12/14-18:25:54.973267 ODRSimApp::main() started
+I 07/12/14-18:25:54.973372 using CANbus interface name "can0"
+I 07/12/14-18:27:11.818084 ODR H/W Simulator shutdown
+I 07/12/14-19:00:23.939175 ------------------------------------------------------
+I 07/12/14-19:00:23.939292 ODR H/W Simulator startup
+I 07/12/14-19:00:23.939306 ODRSimApp::main() started
+I 07/12/14-19:00:23.939399 using CANbus interface name "can0"
+I 07/12/14-19:02:08.176230 ODR H/W Simulator shutdown
+I 07/12/14-19:21:40.436115 ------------------------------------------------------
+I 07/12/14-19:21:40.436234 ODR H/W Simulator startup
+I 07/12/14-19:21:40.436248 ODRSimApp::main() started
+I 07/12/14-19:21:40.436342 using CANbus interface name "can0"
+I 07/12/14-19:22:05.701147 ODR H/W Simulator shutdown
+I 07/12/14-19:40:23.244222 ------------------------------------------------------
+I 07/12/14-19:40:23.244334 ODR H/W Simulator startup
+I 07/12/14-19:40:23.244347 ODRSimApp::main() started
+I 07/12/14-19:40:23.244438 using CANbus interface name "can0"
+I 07/12/14-19:44:43.266963 ODR H/W Simulator shutdown
+I 07/12/14-19:47:51.473531 ------------------------------------------------------
+I 07/12/14-19:47:51.473649 ODR H/W Simulator startup
+I 07/12/14-19:47:51.473663 ODRSimApp::main() started
+I 07/12/14-19:47:51.473753 using CANbus interface name "can0"
+I 07/12/14-19:48:00.352214 ODR H/W Simulator shutdown
+I 07/12/14-20:17:52.302488 ------------------------------------------------------
+I 07/12/14-20:17:52.302848 ODR H/W Simulator startup
+I 07/12/14-20:17:52.302866 ODRSimApp::main() started
+I 07/12/14-20:17:52.302964 using CANbus interface name "can0"
+I 07/12/14-20:18:54.617871 ODR H/W Simulator shutdown
+I 07/12/14-20:24:05.654917 ------------------------------------------------------
+I 07/12/14-20:24:05.655027 ODR H/W Simulator startup
+I 07/12/14-20:24:05.655041 ODRSimApp::main() started
+I 07/12/14-20:24:05.655136 using CANbus interface name "can0"
+I 07/12/14-20:24:52.235568 ODR H/W Simulator shutdown
+I 07/12/14-22:04:28.953071 ------------------------------------------------------
+I 07/12/14-22:04:28.953192 ODR H/W Simulator startup
+I 07/12/14-22:04:28.953206 ODRSimApp::main() started
+I 07/12/14-22:04:28.953298 using CANbus interface name "can0"
+I 07/12/14-22:08:10.500004 ODR H/W Simulator shutdown
+I 07/12/14-22:18:54.694580 ------------------------------------------------------
+I 07/12/14-22:18:54.694698 ODR H/W Simulator startup
+I 07/12/14-22:18:54.694712 ODRSimApp::main() started
+I 07/12/14-22:18:54.694803 using CANbus interface name "can0"
+I 07/12/14-22:25:29.472422 ODR H/W Simulator shutdown
+I 07/12/14-22:25:54.573827 ------------------------------------------------------
+I 07/12/14-22:25:54.573932 ODR H/W Simulator startup
+I 07/12/14-22:25:54.573945 ODRSimApp::main() started
+I 07/12/14-22:25:54.574036 using CANbus interface name "can0"
+I 07/12/14-22:29:47.876123 ODR H/W Simulator shutdown