copied everything over from 2012 and removed all of the actual robot code except the drivetrain stuff
git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4078 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/aos/common/messages/QueueHolder.h b/aos/common/messages/QueueHolder.h
new file mode 100644
index 0000000..6cf2835
--- /dev/null
+++ b/aos/common/messages/QueueHolder.h
@@ -0,0 +1,173 @@
+#ifndef __AOS_MESSAGES_QUEUE_HOLDER_H_
+#define __AOS_MESSAGES_QUEUE_HOLDER_H_
+
+#include <stddef.h>
+
+#include <algorithm>
+
+#include "aos/aos_core.h"
+#include "aos/common/control_loop/Timing.h"
+#include "aos/common/byteorder.h"
+#include "aos/common/time.h"
+#include "aos/common/type_traits.h"
+
+namespace aos {
+
+// Specializations of TypeOperator and QueueBuilder that are actually
+// implemented are created in the generated code for all message value types.
+// These specializations have the same functions declared in the actual types.
+
+// Defines a way for types to be manipulated.
+template<typename T> class TypeOperator {
+ public:
+ // Sets all fields to their default constructor.
+ static void Zero(T &t_);
+ // Returns the size of buffer NToH and HToN use.
+ static size_t Size();
+ // Converts everything from network to host byte order.
+ // input must have Size() bytes available in it.
+ static void NToH(char *input, T &t_);
+ // Converts everything from host to network byte order and puts it into output.
+ // output must have Size() bytes available in it.
+ static void HToN(const T &t_, char *output);
+ // Creates a string with the names and values of all the fields.
+ // The return value might will be to a static buffer.
+ static const char *Print(const T &t_);
+};
+
+template<typename T> class QueueHolder;
+
+// An easy way to set values for queue messages.
+// Each specialization has chainable setter functions for building a message
+// of type T to put into a queue (like QueueBuilder<T> &field(int value);).
+template<class T> class QueueBuilder {
+ public:
+ QueueBuilder(QueueHolder<T> &holder);
+ bool Send();
+};
+
+// Internal class to make implementing identical behavior with structs that go
+// into queues easier. Also a central location for the documentation.
+//
+// When compiled for the cRIO, everything except Clear does nothing (and Get
+// turns into just a Clear) which means that the internal T instance is the only one.
+// Also, the internal instance becomes static.
+//
+// To look at the current message, you Get a copy and then View the result.
+// To make changes, you modify the message that you can View (after possibly
+// Clearing it) and then you Send it. You can also just Clear the message, put
+// data into it, and then Send it. A way to modify the local message is using
+// the Builder function.
+// Note that there is no way to avoid potentially overwriting other changes between
+// when you Get one and when you Send it (mainly applicable to 1-length queues).
+//
+// T must be POD and have a "timespec set_time;" field.
+//
+// This first class doesn't have the builder; QueueHolder does.
+#define aos_check_rv __attribute__((warn_unused_result))
+template<typename T> class QueueHolderNoBuilder {
+#ifndef __VXWORKS__
+ aos_queue *const queue_;
+ static_assert(shm_ok<T>::value, "T must be able to"
+ " go through shared memory and memcpy");
+ T t_;
+#else
+ static T t_;
+#endif
+ public:
+#ifndef __VXWORKS__
+ explicit QueueHolderNoBuilder(aos_queue *queue) : queue_(queue) {}
+#else
+ QueueHolderNoBuilder() {}
+#endif
+ // Gets the current value and stores it in View().
+ // check_time is whether or not to check to see if the last time a value was Sent
+ // was too long ago (returns false if it was)
+ // Returns true if View() is now the current value.
+ // IMPORTANT: If this function returns false, the contents of View() are
+ // either the same as they were before or (if check_time is true) the current
+ // message. That is why it creates compile-time warnings if the return value
+ // is not checked.
+ bool Get(bool check_time) aos_check_rv;
+ // Looks at the current value. Starts out undefined.
+ // If the last Get call returned false, then this the contents of the
+ // return value are undefined.
+#ifdef __VXWORKS__
+ static
+#endif
+ inline T &View() { return t_; }
+ // Clears (calls the default constructor of) all the fields of the current
+ // Goal.
+ void Clear() { TypeOperator<T>::Zero(t_); }
+ // Sends the current value. Does not affect the current value.
+ // Returns whether or not the Send succeeded.
+ bool Send();
+ // Returns a string containing the values of all the fields in the current
+ // value.
+ // The return value is valid until Print is called again. The class owns the
+ // memory.
+ const char *Print() const { return TypeOperator<T>::Print(t_); }
+};
+
+template<typename T>
+bool QueueHolderNoBuilder<T>::Get(bool check_time) {
+#ifdef __VXWORKS__
+ (void)check_time;
+ return true;
+#else
+ const T *msg = static_cast<const T *>(aos_queue_read_msg(queue_,
+ PEEK | NON_BLOCK));
+ if (msg == NULL) {
+ return false;
+ }
+ static_assert(sizeof(t_) == sizeof(*msg), "something is wrong here");
+ memcpy(&t_, msg, sizeof(t_));
+ aos_queue_free_msg(queue_, msg);
+ if (check_time && !((time::Time::Now() - time::Time(t_.set_time)) > time::Time::InMS(45))) {
+ LOG(WARNING, "too long since last Set msg={%s}\n", Print());
+ return false;
+ } else {
+ return true;
+ }
+#endif
+}
+template<typename T>
+bool QueueHolderNoBuilder<T>::Send() {
+#ifndef __VXWORKS__
+ T *msg = static_cast<T *>(aos_queue_get_msg(queue_));
+ if (msg == NULL) {
+ return false;
+ }
+ static_assert(sizeof(*msg) == sizeof(t_), "something is wrong here");
+ memcpy(msg, &t_, sizeof(t_));
+ msg->set_time = ::aos::time::Time::Now().ToTimespec();
+
+ return aos_queue_write_msg_free(queue_, msg, OVERRIDE) == 0;
+#else
+ return true;
+#endif
+}
+#ifdef __VXWORKS__
+template<typename T> T QueueHolderNoBuilder<T>::t_;
+#endif
+template<typename T> class QueueHolder : public QueueHolderNoBuilder<T> {
+ QueueBuilder<T> builder_;
+ public:
+#ifndef __VXWORKS__
+ explicit QueueHolder(aos_queue *queue) : QueueHolderNoBuilder<T>(queue),
+ builder_(*this) {}
+#else
+ QueueHolder() : builder_(*this) {}
+#endif
+ // Clears the current Goal and returns an object that allows setting various
+ // fields with chained method calls and then calling Send() on it.
+ QueueBuilder<T> &Builder() {
+ QueueHolderNoBuilder<T>::Clear();
+ return builder_;
+ }
+};
+
+} // namespace aos
+
+#endif
+
diff --git a/aos/common/messages/QueueHolder.swg b/aos/common/messages/QueueHolder.swg
new file mode 100644
index 0000000..816e297
--- /dev/null
+++ b/aos/common/messages/QueueHolder.swg
@@ -0,0 +1,9 @@
+namespace aos {
+
+template<class T> class QueueBuilder {
+ public:
+ bool Send();
+};
+
+} // namespace aos
+
diff --git a/aos/common/messages/RobotState.q b/aos/common/messages/RobotState.q
new file mode 100644
index 0000000..32baa05
--- /dev/null
+++ b/aos/common/messages/RobotState.q
@@ -0,0 +1,14 @@
+package aos;
+
+message RobotState {
+ bool enabled;
+ bool autonomous;
+ uint16_t team_id;
+};
+
+// The robot_state Queue is checked by all control loops to make sure that the
+// joystick code hasn't died.
+// It also provides information about whether or not the robot is in autonomous
+// mode and what the team_id is.
+
+queue RobotState robot_state;
diff --git a/aos/common/messages/messages.gyp b/aos/common/messages/messages.gyp
new file mode 100644
index 0000000..94508c4
--- /dev/null
+++ b/aos/common/messages/messages.gyp
@@ -0,0 +1,45 @@
+{
+ 'targets': [
+ {
+ 'target_name': 'aos_queues',
+ 'type': 'static_library',
+ 'sources': [
+ 'RobotState.q',
+ ],
+ 'variables': {
+ 'header_path': 'aos/common/messages',
+ },
+ 'dependencies': [
+ '<(AOS)/build/aos.gyp:aos_internal_nolib',
+ '<(AOS)/common/common.gyp:queues',
+ ],
+ 'export_dependent_settings': [
+ '<(AOS)/build/aos.gyp:aos_internal_nolib',
+ '<(AOS)/common/common.gyp:queues',
+ ],
+ 'includes': ['../../build/queues.gypi'],
+ },
+ {
+ 'target_name': 'queues_so',
+ 'type': 'shared_library',
+ 'sources': [
+ 'RobotState.q',
+ ],
+ 'variables': {
+ 'header_path': 'aos/common/messages',
+ },
+ 'dependencies': [
+ '<(AOS)/build/aos.gyp:aos_internal_nolib',
+ ],
+ 'export_dependent_settings': [
+ '<(AOS)/build/aos.gyp:aos_internal_nolib',
+ ],
+ 'direct_dependent_settings': {
+ 'variables': {
+ 'jni_libs': ['queues_so'],
+ },
+ },
+ 'includes': ['../../build/queues.gypi'],
+ },
+ ],
+}