CMSDK 2.0.1
Cross-platform C++ base library and SDK for the Psyclone AIOS platform
Loading...
Searching...
No Matches
Observations.h
Go to the documentation of this file.
1
11#if !defined(_OBSERVATIONS_H_)
12#define _OBSERVATIONS_H_
13
14#include "DataMessage.h"
15
16namespace cmlabs {
17
19struct ObsEntry {
20 std::string name;
21 std::string type;
22 std::string trigger;
23 std::map<std::string, std::string> mappings;
24};
25
28 bool operator()(const ObsEntry& a, const ObsEntry& b) const {
29 return (a.name == b.name);
30 }
31};
32
36int64 ExtractIntFromMessage(const char* name, DataMessage* msg, std::map<std::string, std::string>& mappings, bool &ok);
38float64 ExtractFloatFromMessage(const char* name, DataMessage* msg, std::map<std::string, std::string>& mappings, bool &ok);
40uint64 ExtractTimeFromMessage(const char* name, DataMessage* msg, std::map<std::string, std::string>& mappings, bool &ok);
42std::string ExtractStringFromMessage(const char* name, DataMessage* msg, std::map<std::string, std::string>& mappings, bool &ok);
43
45struct ObsHeader {
46 uint32 cid;
47 uint32 size;
48 uint64 timestamp;
49 uint64 id;
50 uint64 creatorID;
51 uint64 objectID;
52 uint64 topicID;
53 uint32 type;
55 float64 confidence;
56 float64 consensus;
57};
58
59#define OBSID_LOC 1
64 float64 x, y, z, pitch, roll, yaw, size;
65 uint64 mapID;
66 static uint32 getType() { return OBSID_LOC; }
67 static std::string getTypeName() { return "Location"; }
68 void init() { memset(this, 0, sizeof(*this)); }
69 std::string print() {
70 std::string loc;
71 if (!z)
72 loc = utils::StringFormat("(%.3f,%.3f)", x, y);
73 else
74 loc = utils::StringFormat("(%.3f,%.3f,%.3f)", x, y, z);
75 if (yaw)
76 loc = utils::StringFormat("%s {%.3f}", loc.c_str(), yaw);
77 if (size)
78 loc = utils::StringFormat("%s [%.3f]", loc.c_str(), size);
79 return loc;
80 }
81 std::string toJSON() { return utils::StringFormat(" \"x\": %.3f, \"y\": %.3f, \"z\": %.3f, \"pitch\": %.3f, \"roll\": %.3f, \"yaw\": %.3f, \"size\": %.2f", x, y, z, pitch, roll, yaw, size); }
83 bool ok;
84 x = msg->getFloat("FromX", ok); if (!ok) return false;
85 y = msg->getFloat("FromY", ok);
86 return ok;
87 }
89 bool ok;
90 x = msg->getFloat("ToX", ok);
91 y = msg->getFloat("ToY", ok);
92 return ok;
93 }
95 if (a.x <= b.x) {
96 if ((x < a.x) || (x > b.x))
97 return false;
98 if (a.y <= b.y) {
99 if ((y < a.y) || (y > b.y))
100 return false;
101 }
102 else {
103 if ((y < b.y) || (y > a.y))
104 return false;
105 }
106 }
107 else {
108 if ((x < b.x) || (x > a.x))
109 return false;
110 if (a.y <= b.y) {
111 if ((y < a.y) || (y > b.y))
112 return false;
113 }
114 else {
115 if ((y < b.y) || (y > a.y))
116 return false;
117 }
118 }
119 return true;
120 }
121 bool extractDataFromMessage(DataMessage* msg, std::map<std::string, std::string>& mappings) {
122 bool ok;
123 x = ExtractFloatFromMessage("x", msg, mappings, ok);
124 if (!ok) return false;
125 y = ExtractFloatFromMessage("y", msg, mappings, ok);
126 if (!ok) return false;
127 z = ExtractFloatFromMessage("z", msg, mappings, ok);
128 pitch = ExtractFloatFromMessage("pitch", msg, mappings, ok);
129 roll = ExtractFloatFromMessage("roll", msg, mappings, ok);
130 yaw = ExtractFloatFromMessage("yaw", msg, mappings, ok);
131 size = ExtractFloatFromMessage("size", msg, mappings, ok);
132 mapID = (uint64)ExtractIntFromMessage("mapid", msg, mappings, ok);
133 return true;
134 }
135};
136
137
138#define OBSID_DIM 2
141 float64 w, h, d;
142 uint32 getType() { return OBSID_DIM; }
143 static std::string getTypeName() { return "Dimension"; }
144 void init() { memset(this, 0, sizeof(*this)); }
145 std::string print() { return utils::StringFormat("(%.3f,%.3f,%.3f)", w, h, d); }
146 std::string toJSON() { return utils::StringFormat(" \"w\": %.3f, \"h\": %.3f, \"d\": %.3f ", w, h, d); }
148 bool ok;
149 w = msg->getFloat("FromW", ok); if (!ok) return false;
150 h = msg->getFloat("FromH", ok); if (!ok) return false;
151 d = msg->getFloat("FromD");
152 return true;
153 }
155 bool ok;
156 w = msg->getFloat("ToW", ok); if (!ok) return false;
157 h = msg->getFloat("ToH", ok); if (!ok) return false;
158 d = msg->getFloat("ToD");
159 return ok;
160 }
162 float64 vol, volA, volB;
163 if (this->d) {
164 // consider depth
165 vol = w * h * d;
166 volA = a.w * a.h * a.d;
167 volB = b.w * b.h * b.d;
168 }
169 else {
170 // ignore depth
171 vol = w * h;
172 volA = a.w * a.h;
173 volB = b.w * b.h;
174 }
175 if (volA <= volB) {
176 if ((vol < volA) || (vol > volB))
177 return false;
178 }
179 else {
180 if ((vol < volB) || (vol > volA))
181 return false;
182 }
183 return true;
184 }
185 bool extractDataFromMessage(DataMessage* msg, std::map<std::string, std::string>& mappings) {
186 bool ok;
187 w = ExtractFloatFromMessage("w", msg, mappings, ok);
188 if (!ok) return false;
189 h = ExtractFloatFromMessage("h", msg, mappings, ok);
190 if (!ok) return false;
191 d = ExtractFloatFromMessage("d", msg, mappings, ok);
192 return true;
193 }
194};
195
196
197#define OBSID_INT 3
200 int64 val;
201 uint32 getType() { return OBSID_INT; }
202 static std::string getTypeName() { return "Integer"; }
203 void init() { memset(this, 0, sizeof(*this)); }
204 std::string print() { return utils::StringFormat("%lld", val); }
205 std::string toJSON() { return utils::StringFormat(" \"value\": %lld ", val); }
207 bool ok;
208 val = msg->getInt("FromVal", ok);
209 return ok;
210 }
212 bool ok;
213 val = msg->getInt("ToVal", ok);
214 return ok;
215 }
217 if (a.val <= b.val)
218 return ((val < a.val) || (val > b.val));
219 else
220 return ((val < b.val) || (val > a.val));
221 }
222 bool extractDataFromMessage(DataMessage* msg, std::map<std::string, std::string>& mappings) {
223 bool ok;
224 val = ExtractIntFromMessage("val", msg, mappings, ok);
225 return ok;
226 }
227};
228
229#define OBSID_FLOAT 4
231struct ObsFloat {
232 float64 val;
233 uint32 getType() { return OBSID_FLOAT; }
234 static std::string getTypeName() { return "Float"; }
235 void init() { memset(this, 0, sizeof(*this)); }
236 std::string print() { return utils::StringFormat("%.3f", val); }
237 std::string toJSON() { return utils::StringFormat(" \"value\": %.3f ", val); }
239 bool ok;
240 val = msg->getFloat("FromVal", ok);
241 return ok;
242 }
244 bool ok;
245 val = msg->getFloat("ToVal", ok);
246 return ok;
247 }
249 if (a.val <= b.val)
250 return ((val < a.val) || (val > b.val));
251 else
252 return ((val < b.val) || (val > a.val));
253 }
254 bool extractDataFromMessage(DataMessage* msg, std::map<std::string, std::string>& mappings) {
255 bool ok;
256 val = ExtractFloatFromMessage("val", msg, mappings, ok);
257 return ok;
258 }
259};
260
261#define OBSID_TIME 5
263struct ObsTime {
264 uint64 val;
265 uint32 getType() { return OBSID_TIME; }
266 static std::string getTypeName() { return "Time"; }
267 void init() { memset(this, 0, sizeof(*this)); }
268 std::string print() { return utils::StringFormat("%s", PrintTime(val)); }
269 std::string toJSON() { return utils::StringFormat(" \"time\": %llu, \"timetext\": \"%s\" ", val, PrintTimeString(val).c_str()); }
271 bool ok;
272 val = msg->getTime("FromVal", ok);
273 return ok;
274 }
276 bool ok;
277 val = msg->getTime("ToVal", ok);
278 return ok;
279 }
280 bool isBetween(ObsTime& a, ObsTime& b) {
281 if (a.val <= b.val)
282 return ((val < a.val) || (val > b.val));
283 else
284 return ((val < b.val) || (val > a.val));
285 }
286 bool extractDataFromMessage(DataMessage* msg, std::map<std::string, std::string>& mappings) {
287 bool ok;
288 val = ExtractTimeFromMessage("val", msg, mappings, ok);
289 return ok;
290 }
291};
292
293#define OBSID_STRING 6
295struct ObsString {
296 char val[1024];
297 uint32 getType() { return OBSID_STRING; }
298 static std::string getTypeName() { return "String"; }
299 void init() { memset(this, 0, sizeof(*this)); }
300 std::string print() { return utils::StringFormat("%s", val); }
301 std::string toJSON() { return utils::StringFormat(" \"value\": \"%s\" ", val); }
303 bool ok;
304 const char* str = msg->getString("FromVal", ok);
305 if (!ok) return false;
306 utils::strcpyavail(val, str, 1023, true);
307 return true;
308 }
310 bool ok;
311 const char* str = msg->getString("ToVal", ok);
312 if (!ok) return false;
313 utils::strcpyavail(val, str, 1023, true);
314 return true;
315 }
316
318 int64 comp = stricmp(a.val, b.val);
319 if (comp <= 0) {
320 if ((stricmp(val, a.val) < 0) || (stricmp(val, b.val) > 0))
321 return false;
322 }
323 else {
324 if ((stricmp(val, b.val) < 0) || (stricmp(val, a.val) > 0))
325 return false;
326 }
327 return true;
328 }
329 bool extractDataFromMessage(DataMessage* msg, std::map<std::string, std::string>& mappings) {
330 bool ok;
331 std::string str = ExtractStringFromMessage("val", msg, mappings, ok);
332 if (!ok) return false;
333 utils::strcpyavail(val, str.c_str(), 1023, true);
334 return true;
335 }
336};
337
339#define OBSID_COUNT 6
340
342uint32 GetObsTypeFromRawData(const char* data, uint32 size);
343
347template <typename T>
349public:
351 static std::list<GenericObservation<T>*> ReadAllFromMessage(DataMessage* msg);
353 static bool WriteAllToMessage(DataMessage* msg, std::list<GenericObservation<T>*>& list);
354
356 GenericObservation(const char* data, uint32 size, uint64 id = 0);
358
361
362 std::string print();
363 std::string toJSON();
364
366 bool extractDataFromMessage(DataMessage* msg, std::map<std::string, std::string>& mappings);
367
368 bool writeToMessage(DataMessage* msg, uint64 id);
369 bool readFromMessage(DataMessage* msg, uint64 id = 0);
370 bool readFromData(const char* data, uint32 size, uint64 id = 0);
371
372 //bool buildFromQuery(uint8 queryType, std::string& query);
374};
375
380
381
382} // namespace cmlabs
383
384#include "Observations.tpl.h"
385
386#endif //_OBSERVATIONS_H_
387
The binary DataMessage container — the central data-exchange object of Psyclone/CMSDK.
#define OBSID_STRING
#define OBSID_TIME
#define OBSID_LOC
#define OBSID_INT
#define OBSID_FLOAT
#define OBSID_DIM
Template implementations for GenericObservation<T> (declared in Observations.h).
#define stricmp
Definition Utils.h:132
#define MAXVALUENAMELEN
Definition Utils.h:86
The central Psyclone data container: a self-contained binary message with typed, named user entries.
bool getInt(const char *key, int64 &value)
getInt(const char* key, int64& value)
uint64 getTime(const char *key)
getTime(const char* key)
bool getFloat(const char *key, float64 &value)
getFloat(const char* key, float64& value)
const char * getString(const char *key)
getString(const char* key)
std::string toJSON()
JSON object rendering.
bool extractDataFromMessage(DataMessage *msg, std::map< std::string, std::string > &mappings)
Populate the payload from a message using logical→actual field mappings.
static bool WriteAllToMessage(DataMessage *msg, std::list< GenericObservation< T > * > &list)
Serialize all observations in list into msg.
ObsHeader header
Identity/provenance/confidence header.
bool readFromMessage(DataMessage *msg, uint64 id=0)
Read the observation with id id (0 = first) from msg.
std::string print()
One-line human-readable rendering (header + payload).
static std::list< GenericObservation< T > * > ReadAllFromMessage(DataMessage *msg)
Deserialize every observation of type T carried by msg.
bool writeToMessage(DataMessage *msg, uint64 id)
Append this observation to msg under entry id id.
bool readFromData(const char *data, uint32 size, uint64 id=0)
Parse from a raw blob.
GenericObservation()
Empty observation (zeroed header and payload).
bool isBetween(GenericObservation< T > *a, GenericObservation< T > *b)
Range test delegated to the payload's isBetween(); see per-type notes on semantics.
std::string PrintTimeString(uint64 t, bool local=true, bool us=true, bool ms=true)
Definition PsyTime.cpp:676
char * PrintTime(uint64 t, bool local=true, bool us=true, bool ms=true)
Full date + time-of-day.
Definition PsyTime.cpp:527
std::string StringFormat(const char *format,...)
printf into a std::string.
Definition Utils.cpp:6626
uint32 strcpyavail(char *dst, const char *src, uint32 maxlen, bool copyAvailable)
Bounded strcpy that always NUL-terminates.
Definition Utils.cpp:6056
std::string ExtractStringFromMessage(const char *name, DataMessage *msg, std::map< std::string, std::string > &mappings, bool &ok)
String variant of ExtractIntFromMessage(); same mapping semantics.
uint64 ExtractTimeFromMessage(const char *name, DataMessage *msg, std::map< std::string, std::string > &mappings, bool &ok)
Timestamp variant of ExtractIntFromMessage(); same mapping semantics.
float64 ExtractFloatFromMessage(const char *name, DataMessage *msg, std::map< std::string, std::string > &mappings, bool &ok)
Float variant of ExtractIntFromMessage(); same mapping semantics.
bool Observations_UnitTest()
Unit test for the Observations module.
uint32 GetObsTypeFromRawData(const char *data, uint32 size)
Inspect a raw observation blob and return its OBSID_* type tag from the embedded ObsHeader.
int64 ExtractIntFromMessage(const char *name, DataMessage *msg, std::map< std::string, std::string > &mappings, bool &ok)
Read an integer field from a message, translating name through mappings first.
void Register_Observations_Tests()
Register the Observations tests with the unit test framework.
Extent observation (w,h,d).
bool extractRangeTo(DataMessage *msg)
bool extractRangeFrom(DataMessage *msg)
static std::string getTypeName()
std::string print()
std::string toJSON()
bool isBetween(ObsDimension &a, ObsDimension &b)
bool extractDataFromMessage(DataMessage *msg, std::map< std::string, std::string > &mappings)
Declarative description of one observation source: name, observation type, trigger expression and fie...
std::string type
std::string name
std::string trigger
std::map< std::string, std::string > mappings
Scalar float observation.
bool extractRangeTo(DataMessage *msg)
bool isBetween(ObsFloat &a, ObsFloat &b)
std::string toJSON()
bool extractRangeFrom(DataMessage *msg)
std::string print()
bool extractDataFromMessage(DataMessage *msg, std::map< std::string, std::string > &mappings)
static std::string getTypeName()
Fixed-size header preceding every observation payload: sizes/ids, provenance (creator,...
char name[MAXVALUENAMELEN+1]
Scalar integer observation.
bool extractRangeFrom(DataMessage *msg)
std::string print()
bool extractRangeTo(DataMessage *msg)
bool isBetween(ObsInteger &a, ObsInteger &b)
static std::string getTypeName()
std::string toJSON()
bool extractDataFromMessage(DataMessage *msg, std::map< std::string, std::string > &mappings)
6-DOF pose observation: position (x,y,z), orientation (pitch,roll,yaw), size and owning map id.
bool isBetween(ObsLocation &a, ObsLocation &b)
static std::string getTypeName()
std::string print()
bool extractDataFromMessage(DataMessage *msg, std::map< std::string, std::string > &mappings)
bool extractRangeFrom(DataMessage *msg)
static uint32 getType()
bool extractRangeTo(DataMessage *msg)
std::string toJSON()
Fixed-buffer (1023 chars + NUL) string observation; comparisons are case-insensitive lexicographic.
static std::string getTypeName()
std::string toJSON()
bool extractRangeFrom(DataMessage *msg)
bool extractRangeTo(DataMessage *msg)
bool extractDataFromMessage(DataMessage *msg, std::map< std::string, std::string > &mappings)
std::string print()
bool isBetween(ObsString &a, ObsString &b)
Timestamp observation (ms epoch).
std::string toJSON()
static std::string getTypeName()
std::string print()
bool extractRangeTo(DataMessage *msg)
bool extractDataFromMessage(DataMessage *msg, std::map< std::string, std::string > &mappings)
bool extractRangeFrom(DataMessage *msg)
bool isBetween(ObsTime &a, ObsTime &b)
Comparator matching ObsEntry records by name only (used for de-duplication in containers).
bool operator()(const ObsEntry &a, const ObsEntry &b) const