diff --git a/examples/CppCheesyVisionSample/CheesyVisionRobot/.cproject b/examples/CppCheesyVisionSample/CheesyVisionRobot/.cproject
new file mode 100644
index 0000000..2588463
--- /dev/null
+++ b/examples/CppCheesyVisionSample/CheesyVisionRobot/.cproject
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/CppCheesyVisionSample/CheesyVisionRobot/.project b/examples/CppCheesyVisionSample/CheesyVisionRobot/.project
new file mode 100644
index 0000000..fdfc17c
--- /dev/null
+++ b/examples/CppCheesyVisionSample/CheesyVisionRobot/.project
@@ -0,0 +1,20 @@
+
+
+ CheesyVisionRobot
+
+
+
+
+
+ com.windriver.ide.core.wrbuilder
+
+
+
+
+
+ com.windriver.ide.core.wrnature
+ com.windriver.ide.core.wrcorenature
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+
+
diff --git a/examples/CppCheesyVisionSample/CheesyVisionRobot/.wrmakefile b/examples/CppCheesyVisionSample/CheesyVisionRobot/.wrmakefile
new file mode 100644
index 0000000..6ad1e05
--- /dev/null
+++ b/examples/CppCheesyVisionSample/CheesyVisionRobot/.wrmakefile
@@ -0,0 +1,48 @@
+# The file ".wrmakefile" is the template used by the Wind River Workbench to
+# generate the makefiles of this project. Add user-specific build targets and
+# make rules only(!) in this project's ".wrmakefile" file. These will then be
+# automatically dumped into the makefiles.
+
+WIND_HOME := $(subst \,/,$(WIND_HOME))
+WIND_BASE := $(subst \,/,$(WIND_BASE))
+WIND_USR := $(subst \,/,$(WIND_USR))
+
+all : pre_build main_all post_build
+
+_clean ::
+ @echo "make: removing targets and objects of `pwd`"
+
+%IDE_GENERATED%
+
+-include $(PRJ_ROOT_DIR)/*.makefile
+
+-include *.makefile
+
+main_all : external_build $(PROJECT_TARGETS)
+ @echo "make: built targets of `pwd`"
+
+# entry point for extending the build
+external_build ::
+ @echo ""
+
+# main entry point for pre processing prior to the build
+pre_build :: $(PRE_BUILD_STEP) generate_sources
+ @echo ""
+
+# entry point for generating sources prior to the build
+generate_sources ::
+ @echo ""
+
+# main entry point for post processing after the build
+post_build :: $(POST_BUILD_STEP) deploy_output
+ @echo ""
+
+# entry point for deploying output after the build
+deploy_output ::
+ @echo ""
+
+clean :: external_clean $(CLEAN_STEP) _clean
+
+# entry point for extending the build clean
+external_clean ::
+ @echo ""
diff --git a/examples/CppCheesyVisionSample/CheesyVisionRobot/.wrproject b/examples/CppCheesyVisionSample/CheesyVisionRobot/.wrproject
new file mode 100644
index 0000000..b637f5e
--- /dev/null
+++ b/examples/CppCheesyVisionSample/CheesyVisionRobot/.wrproject
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/CppCheesyVisionSample/CheesyVisionRobot/CheesyVisionRobot.cpp b/examples/CppCheesyVisionSample/CheesyVisionRobot/CheesyVisionRobot.cpp
new file mode 100644
index 0000000..c3e55c5
--- /dev/null
+++ b/examples/CppCheesyVisionSample/CheesyVisionRobot/CheesyVisionRobot.cpp
@@ -0,0 +1,52 @@
+#include "WPILib.h"
+#include "CheesyVisionServer.h"
+
+class CheesyVisionRobot : public IterativeRobot
+{
+ CheesyVisionServer *server;
+public:
+ static const int listenPort = 1180;
+ CheesyVisionRobot()
+ {
+ server = CheesyVisionServer::GetInstance();
+ }
+
+void CheesyVisionRobot::RobotInit() {
+server->SetPort(listenPort);
+server->StartListening();
+}
+
+void CheesyVisionRobot::DisabledInit() {
+ server->StopSamplingCounts();
+}
+
+void CheesyVisionRobot::DisabledPeriodic() {
+
+}
+
+void CheesyVisionRobot::AutonomousInit() {
+ server->Reset();
+ server->StartSamplingCounts();
+}
+
+void CheesyVisionRobot::AutonomousPeriodic() {
+ printf("Left Status: %d\tRight Status: %d\n", server->GetLeftStatus(), server->GetRightStatus());
+ printf("Left Counts: %d\tRight Counts: %d\tTotal Count: %d", server->GetLeftCount(), server->GetRightCount(), server->GetTotalCount());
+}
+
+void CheesyVisionRobot::TeleopInit() {
+}
+
+void CheesyVisionRobot::TeleopPeriodic() {
+}
+
+void CheesyVisionRobot::TestInit() {
+}
+
+void CheesyVisionRobot::TestPeriodic() {
+}
+
+};
+
+START_ROBOT_CLASS(CheesyVisionRobot);
+
diff --git a/examples/CppCheesyVisionSample/CheesyVisionRobot/CheesyVisionServer.cpp b/examples/CppCheesyVisionSample/CheesyVisionRobot/CheesyVisionServer.cpp
new file mode 100644
index 0000000..7fa0ff9
--- /dev/null
+++ b/examples/CppCheesyVisionSample/CheesyVisionRobot/CheesyVisionServer.cpp
@@ -0,0 +1,103 @@
+#include "CheesyVisionServer.h"
+#include "WPILib.h"
+#include "networktables2/util/EOFException.h"
+
+CheesyVisionServer *CheesyVisionServer::_instance = (CheesyVisionServer *) 0;
+
+#define HEARTBEAT_TIMEOUT 3.0
+
+CheesyVisionServer::CheesyVisionServer(int port)
+{
+ _listenPort = port;
+ _counting = false;
+ _curLeftStatus = false;
+ _curRightStatus = false;
+ _lastHeartbeatTime = Timer::GetFPGATimestamp();
+ _leftCount = 0;
+ _rightCount = 0;
+ _totalCount = 0;
+ _listening = false;
+
+
+}
+
+void CheesyVisionServer::Run()
+{
+ if (_listening == false) return; //Make sure we are listening
+
+ SocketServerStreamProvider *sock;
+ sock = new SocketServerStreamProvider(_listenPort);
+ while (_listening)
+ {
+ IOStream *stream = sock->accept();
+ _lastHeartbeatTime = Timer::GetFPGATimestamp();
+ try
+ {
+ while (Timer::GetFPGATimestamp() < _lastHeartbeatTime + HEARTBEAT_TIMEOUT)
+ {
+ try
+ {
+ uint8_t byte;
+ stream->read(&byte, 1);
+ _curLeftStatus = (byte & (1 << 1)) > 0;
+ _curRightStatus = (byte & (1 << 0)) > 0;
+ UpdateCounts(_curLeftStatus,_curRightStatus);
+ _lastHeartbeatTime = Timer::GetFPGATimestamp();
+ }
+ catch (EOFException e)
+ {
+ //End of file, wait for a bit and read some more
+
+ Wait(0.05);
+ }
+
+ }
+ }
+ catch (IOException e)
+ {
+ printf("Socket IO error: %s\n", e.what());
+ //Catching this exception will dro
+ }
+ delete stream;//close, delete and recreate the stream
+
+ Wait(0.05);
+ }
+ delete sock;
+}
+
+void CheesyVisionServer::Reset()
+{
+ _leftCount = 0;
+ _rightCount = 0;
+ _totalCount = 0;
+
+ _curLeftStatus = false;
+ _curRightStatus = false;
+}
+
+void CheesyVisionServer::UpdateCounts(bool left, bool right)
+{
+ if (true == _counting)
+ {
+ _leftCount += left ? 1 : 0;
+ _rightCount += right ? 1 : 0;
+ _totalCount++;
+ }
+}
+
+CheesyVisionServer *CheesyVisionServer::GetInstance()
+{
+ if (CheesyVisionServer::_instance == (CheesyVisionServer *) 0)
+ {
+ CheesyVisionServer::_instance = new CheesyVisionServer();
+ }
+ return CheesyVisionServer::_instance;
+}
+
+bool CheesyVisionServer::HasClientConnection()
+{
+ return (_lastHeartbeatTime > 0) && (Timer::GetFPGATimestamp() - _lastHeartbeatTime);
+}
+
+
+
diff --git a/examples/CppCheesyVisionSample/CheesyVisionRobot/CheesyVisionServer.h b/examples/CppCheesyVisionSample/CheesyVisionRobot/CheesyVisionServer.h
new file mode 100644
index 0000000..398e273
--- /dev/null
+++ b/examples/CppCheesyVisionSample/CheesyVisionRobot/CheesyVisionServer.h
@@ -0,0 +1,50 @@
+#include "jankyTask.h"
+#include "networktables2/stream/SocketServerStreamProvider.h"
+
+#ifndef CHEESYVISIONSERVER_H_
+#define CHEESYVISIONSERVER_H_
+
+
+
+class CheesyVisionServer: private JankyTask
+{
+
+ static CheesyVisionServer *_instance;
+
+
+ CheesyVisionServer(int port = 1180);
+ int _listenPort;
+
+ int _leftCount;
+ int _rightCount;
+ int _totalCount;
+ bool _curLeftStatus;
+ bool _curRightStatus;
+ bool _counting;
+
+ double _lastHeartbeatTime;
+ bool _listening;
+public:
+ static CheesyVisionServer *GetInstance();
+ bool HasClientConnection();
+ void SetPort(int port){_listenPort = port;}
+ virtual void Run();
+ void StartListening(){_listening = true; Start();}
+ void StopListening(){_listening = false; Pause();}
+
+ void Reset();
+ void UpdateCounts(bool left, bool right);
+ void StartSamplingCounts(){_counting = true;}
+ void StopSamplingCounts(){_counting = false;}
+
+ bool GetLeftStatus(){return _curLeftStatus;}
+ bool GetRightStatus(){return _curRightStatus;}
+ int GetLeftCount(){return _leftCount;}
+ int GetRightCount(){return _rightCount;}
+ int GetTotalCount(){return _totalCount;}
+
+
+};
+
+
+#endif //CHEESYVISIONSERVER_H_
diff --git a/examples/CppCheesyVisionSample/CheesyVisionRobot/jankyTask.cpp b/examples/CppCheesyVisionSample/CheesyVisionRobot/jankyTask.cpp
new file mode 100644
index 0000000..b924bc6
--- /dev/null
+++ b/examples/CppCheesyVisionSample/CheesyVisionRobot/jankyTask.cpp
@@ -0,0 +1,60 @@
+#include "WPILib.h"
+#include "jankyTask.h"
+#include
+
+JankyTask::JankyTask(const char* taskName, UINT32 priority) {
+ std::string name = taskName;
+ char tmp[30];
+
+ if (!taskName)
+ {
+ sprintf(tmp, "%d", GetFPGATime());
+ name = "jankyTask-";
+ name += tmp;
+ }
+
+ enabled_ = false;
+ running_ = true;
+ isDead_ = false;
+
+ task_ = new Task(name.c_str(), (FUNCPTR)JankyTask::JankyPrivateStarterTask, priority);
+ task_->Start((UINT32)this);
+}
+
+JankyTask::~JankyTask(){
+ task_->Stop();
+
+ delete task_; // Now kill the WPI class for the task.
+}
+
+void JankyTask::JankyPrivateStarterTask(JankyTask* task) {
+ while (task->running_) {
+ if (task->enabled_) {
+ task->Run();
+ Wait(0.002); // Only wait 2ms when task is active.
+ }
+ else
+ Wait(0.05); // 50 ms wait period while task is 'paused'
+ }
+
+ task->isDead_ = true; // Falling off the edge of the earth...
+}
+
+void JankyTask::Start() {
+ enabled_ = true;
+}
+
+void JankyTask::Pause() {
+ enabled_ = false;
+}
+
+void JankyTask::Terminate() {
+ running_ = false;
+
+ // Above told the task to exit on the next loop around.
+ // That could take 2ms or 50ms based on whether it's in pause or run and how long
+ // the actual Run() routine takes too. So we have to wait until we're really terminated here.
+ while (!isDead_) {
+ Wait(0.02); // Wait until we're really dead on that task.
+ }
+}
diff --git a/examples/CppCheesyVisionSample/CheesyVisionRobot/jankyTask.h b/examples/CppCheesyVisionSample/CheesyVisionRobot/jankyTask.h
new file mode 100644
index 0000000..63e92eb
--- /dev/null
+++ b/examples/CppCheesyVisionSample/CheesyVisionRobot/jankyTask.h
@@ -0,0 +1,64 @@
+#ifndef JANKYTASK_H_
+#define JANKYTASK_H_
+
+#include "WPILib.h"
+
+/**
+ * @author Robert Wolff - based largely on Tom Bottglieri's work from Team 254
+ * @author Tom Bottglieri
+ *
+ * @brief Abstract superclass of tasks (run on a separate thread).
+ * Call Start() to begin the task and Pause() to temporarily pause it.
+ * The inheriting class must implement Run() which will be called again and
+ * again when the task is in 'Start/Running' mode.
+ */
+class JankyTask {
+ public:
+ /**
+ * @brief Constructor which takes an optional taskname. In the absence of a task name,
+ * a task name will be created based upon the current system-time.
+ */
+ JankyTask(const char* taskName = NULL, UINT32 priority = Task::kDefaultPriority);
+ virtual ~JankyTask();
+
+ /**
+ * @brief PRIVATE- Do not call this function externally as it's only passed to the constructor to initialize the object.
+ *
+ * This function sets up an operating-system task which will perpetually loop the Run() function.
+ * @note When running, loops wait 2ms between calls to Run(). During pause, loop waits 50ms.
+ * @param JankyTask the given JankyTask object to run.
+ */
+ static void JankyPrivateStarterTask(JankyTask* task);
+
+ /**
+ * @brief Starts the task.
+ */
+ void Start();
+
+ /**
+ * @brief Pauses the task.
+ */
+ void Pause();
+
+ /**
+ * @brief Terminate the task.
+ */
+ void Terminate();
+
+ /**
+ * @brief The inheriting class must implement this function. This is the function
+ * which gets run in the new task.
+ *
+ * Subclasses should override this function to specify their own behavior.
+ */
+ virtual void Run() = 0;
+
+ bool TaskRunning() {return enabled_;}
+ private:
+ bool enabled_;
+ bool running_;
+ bool isDead_;
+ Task* task_;
+};
+
+#endif // JANKYTASK_H_