blob: a6b2bfafedbcea4c69c595848aef0bb691e62631 [file] [log] [blame]
Brian Silverman3204dd82013-03-12 18:42:01 -07001#ifndef AOS_COMMON_SENSORS_SENSORS_H_
2#define AOS_COMMON_SENSORS_SENSORS_H_
3
4#include "aos/common/time.h"
Brian Silvermanffe3d712013-03-15 21:35:59 -07005#include "aos/common/byteorder.h"
Brian Silverman3204dd82013-03-12 18:42:01 -07006#include "aos/common/control_loop/ControlLoop.h"
Brian Silverman50df23f2013-03-20 21:38:07 -07007#include "aos/common/inttypes.h"
Brian Silverman3204dd82013-03-12 18:42:01 -07008
9namespace aos {
10// This namespace contains all of the stuff for dealing with reading sensors and
11// communicating it to everything that needs it. There are 4 main classes whose
12// instances actually process the data. They must all be registered in the
13// appropriate ::aos::crio::ControlsManager hooks.
14//
15// SensorPackers get run on the cRIO to read inputs (from WPILib or elsewhere)
16// and put the values into the Values struct (which is templated for all of the
17// classes that use it).
18// SensorUnpackers get run on both the atom and the cRIO to take the data from
19// the Values struct and put them into queues for control loops etc.
20// SensorBroadcasters (on the cRIO) send the data to a SensorReceiver (on the
21// atom) to pass to its SensorUnpacker there.
22// CRIOControlLoopRunners register with a SensorBroadcaster to get called right
23// after reading the sensor data so that they can immediately pass it so a
24// SensorUnpacker and then run their control loops.
25// The actual SensorPacker and SensorUnpacker classes have the Interface suffix
26// on them.
27namespace sensors {
28
29// How many times per ::aos::control_loops::kLoopFrequency sensor
30// values get sent out by the cRIO.
31// This must evenly divide that frequency into multiples of sysClockRateGet().
32const int kSendsPerCycle = 10;
33// ::aos::control_loops::kLoopFrequency / kSendsPerCycle for
34// convenience.
35extern const time::Time kSensorSendFrequency;
36using ::aos::control_loops::kLoopFrequency;
Brian Silverman15ca9852013-03-17 18:24:15 -070037using ::aos::control_loops::NextLoopTime;
Brian Silverman3204dd82013-03-12 18:42:01 -070038
Brian Silverman50df23f2013-03-20 21:38:07 -070039uint32_t CalculateChecksum(char *buf, size_t size);
40
Brian Silverman3204dd82013-03-12 18:42:01 -070041// This is the struct that actually gets sent over the UDP socket.
42template<class Values>
43struct SensorData {
Brian Silverman50df23f2013-03-20 21:38:07 -070044 // All of the other 4-byte chunks in the message bitwise-exclusive-ORed
45 // together. Needed because it seems like nobody else checks... (vxworks not
46 // sending the UDP checksum or (not very likely) linux not checking it).
Brian Silvermand3f92f12013-03-20 23:01:33 -070047 // TODO(brians): static_assert that this is at the front
Brian Silverman50df23f2013-03-20 21:38:07 -070048 uint32_t checksum;
49
Brian Silverman3204dd82013-03-12 18:42:01 -070050 Values values;
51 // Starts at 0 and goes up.
52 int32_t count;
Brian Silvermanffe3d712013-03-15 21:35:59 -070053
54 void NetworkToHost() {
55 count = ntoh(count);
56 }
Brian Silverman15ca9852013-03-17 18:24:15 -070057 void HostToNetwork() {
58 count = hton(count);
59 }
Brian Silverman50df23f2013-03-20 21:38:07 -070060
61 void FillinChecksum() {
62 checksum = CalculateChecksum(reinterpret_cast<char *>(this) +
63 sizeof(checksum),
64 sizeof(*this) - sizeof(checksum));
65 }
66 // Returns whether or not checksum is correct.
67 bool CheckChecksum() {
68 uint32_t expected = CalculateChecksum(reinterpret_cast<char *>(this) +
69 sizeof(checksum),
70 sizeof(*this) - sizeof(checksum));
71 if (checksum != expected) {
72 LOG(INFO, "expected %"PRIx32" but got %"PRIx32"\n",
73 expected, checksum);
74 return false;
75 }
76 return true;
77 }
Brian Silverman3204dd82013-03-12 18:42:01 -070078} __attribute__((packed));
79
80} // namespace sensors
81} // namespace aos
82
83#endif // AOS_COMMON_SENSORS_SENSORS_H_