Fawkes API Fawkes Development Version
RobotinoSensorInterface.cpp
1
2/***************************************************************************
3 * RobotinoSensorInterface.cpp - Fawkes BlackBoard Interface - RobotinoSensorInterface
4 *
5 * Templated created: Thu Oct 12 10:49:19 2006
6 * Copyright 2012-2016 Tim Niemueller
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24#include <interfaces/RobotinoSensorInterface.h>
25
26#include <core/exceptions/software.h>
27
28#include <map>
29#include <string>
30#include <cstring>
31#include <cstdlib>
32
33namespace fawkes {
34
35/** @class RobotinoSensorInterface <interfaces/RobotinoSensorInterface.h>
36 * RobotinoSensorInterface Fawkes BlackBoard Interface.
37 * Sensor information of a Robotino robot
38 * @ingroup FawkesInterfaces
39 */
40
41
42
43/** Constructor */
44RobotinoSensorInterface::RobotinoSensorInterface() : Interface()
45{
46 data_size = sizeof(RobotinoSensorInterface_data_t);
47 data_ptr = malloc(data_size);
48 data = (RobotinoSensorInterface_data_t *)data_ptr;
49 data_ts = (interface_data_ts_t *)data_ptr;
50 memset(data_ptr, 0, data_size);
51 add_fieldinfo(IFT_FLOAT, "mot_velocity", 3, &data->mot_velocity);
52 add_fieldinfo(IFT_INT32, "mot_position", 3, &data->mot_position);
53 add_fieldinfo(IFT_FLOAT, "mot_current", 3, &data->mot_current);
54 add_fieldinfo(IFT_BOOL, "bumper", 1, &data->bumper);
55 add_fieldinfo(IFT_FLOAT, "distance", 9, &data->distance);
56 add_fieldinfo(IFT_BOOL, "digital_in", 8, &data->digital_in);
57 add_fieldinfo(IFT_BOOL, "digital_out", 8, &data->digital_out);
58 add_fieldinfo(IFT_FLOAT, "analog_in", 8, &data->analog_in);
59 add_fieldinfo(IFT_BOOL, "bumper_estop_enabled", 1, &data->bumper_estop_enabled);
60 add_messageinfo("SetBumperEStopEnabledMessage");
61 add_messageinfo("SetDigitalOutputMessage");
62 unsigned char tmp_hash[] = {0xa5, 0xb, 0xa1, 0x94, 0xea, 0x39, 0x14, 0x7, 0x98, 0x77, 0x10, 0xc, 0x25, 0x72, 0x57, 0xa0};
63 set_hash(tmp_hash);
64}
65
66/** Destructor */
67RobotinoSensorInterface::~RobotinoSensorInterface()
68{
69 free(data_ptr);
70}
71/* Methods */
72/** Get mot_velocity value.
73 * Velocities of the wheels.
74 * @return mot_velocity value
75 */
76float *
77RobotinoSensorInterface::mot_velocity() const
78{
79 return data->mot_velocity;
80}
81
82/** Get mot_velocity value at given index.
83 * Velocities of the wheels.
84 * @param index index of value
85 * @return mot_velocity value
86 * @exception Exception thrown if index is out of bounds
87 */
88float
89RobotinoSensorInterface::mot_velocity(unsigned int index) const
90{
91 if (index > 2) {
92 throw Exception("Index value %u out of bounds (0..2)", index);
93 }
94 return data->mot_velocity[index];
95}
96
97/** Get maximum length of mot_velocity value.
98 * @return length of mot_velocity value, can be length of the array or number of
99 * maximum number of characters for a string
100 */
101size_t
102RobotinoSensorInterface::maxlenof_mot_velocity() const
103{
104 return 3;
105}
106
107/** Set mot_velocity value.
108 * Velocities of the wheels.
109 * @param new_mot_velocity new mot_velocity value
110 */
111void
112RobotinoSensorInterface::set_mot_velocity(const float * new_mot_velocity)
113{
114 set_field(data->mot_velocity, new_mot_velocity);
115}
116
117/** Set mot_velocity value at given index.
118 * Velocities of the wheels.
119 * @param new_mot_velocity new mot_velocity value
120 * @param index index for of the value
121 */
122void
123RobotinoSensorInterface::set_mot_velocity(unsigned int index, const float new_mot_velocity)
124{
125 set_field(data->mot_velocity, index, new_mot_velocity);
126}
127/** Get mot_position value.
128 * Positions of the wheels.
129 * @return mot_position value
130 */
131int32_t *
132RobotinoSensorInterface::mot_position() const
133{
134 return data->mot_position;
135}
136
137/** Get mot_position value at given index.
138 * Positions of the wheels.
139 * @param index index of value
140 * @return mot_position value
141 * @exception Exception thrown if index is out of bounds
142 */
143int32_t
144RobotinoSensorInterface::mot_position(unsigned int index) const
145{
146 if (index > 2) {
147 throw Exception("Index value %u out of bounds (0..2)", index);
148 }
149 return data->mot_position[index];
150}
151
152/** Get maximum length of mot_position value.
153 * @return length of mot_position value, can be length of the array or number of
154 * maximum number of characters for a string
155 */
156size_t
157RobotinoSensorInterface::maxlenof_mot_position() const
158{
159 return 3;
160}
161
162/** Set mot_position value.
163 * Positions of the wheels.
164 * @param new_mot_position new mot_position value
165 */
166void
167RobotinoSensorInterface::set_mot_position(const int32_t * new_mot_position)
168{
169 set_field(data->mot_position, new_mot_position);
170}
171
172/** Set mot_position value at given index.
173 * Positions of the wheels.
174 * @param new_mot_position new mot_position value
175 * @param index index for of the value
176 */
177void
178RobotinoSensorInterface::set_mot_position(unsigned int index, const int32_t new_mot_position)
179{
180 set_field(data->mot_position, index, new_mot_position);
181}
182/** Get mot_current value.
183 * Motor currents.
184 * @return mot_current value
185 */
186float *
187RobotinoSensorInterface::mot_current() const
188{
189 return data->mot_current;
190}
191
192/** Get mot_current value at given index.
193 * Motor currents.
194 * @param index index of value
195 * @return mot_current value
196 * @exception Exception thrown if index is out of bounds
197 */
198float
199RobotinoSensorInterface::mot_current(unsigned int index) const
200{
201 if (index > 2) {
202 throw Exception("Index value %u out of bounds (0..2)", index);
203 }
204 return data->mot_current[index];
205}
206
207/** Get maximum length of mot_current value.
208 * @return length of mot_current value, can be length of the array or number of
209 * maximum number of characters for a string
210 */
211size_t
212RobotinoSensorInterface::maxlenof_mot_current() const
213{
214 return 3;
215}
216
217/** Set mot_current value.
218 * Motor currents.
219 * @param new_mot_current new mot_current value
220 */
221void
222RobotinoSensorInterface::set_mot_current(const float * new_mot_current)
223{
224 set_field(data->mot_current, new_mot_current);
225}
226
227/** Set mot_current value at given index.
228 * Motor currents.
229 * @param new_mot_current new mot_current value
230 * @param index index for of the value
231 */
232void
233RobotinoSensorInterface::set_mot_current(unsigned int index, const float new_mot_current)
234{
235 set_field(data->mot_current, index, new_mot_current);
236}
237/** Get bumper value.
238 * Bumper pressed indicator.
239 * @return bumper value
240 */
241bool
242RobotinoSensorInterface::is_bumper() const
243{
244 return data->bumper;
245}
246
247/** Get maximum length of bumper value.
248 * @return length of bumper value, can be length of the array or number of
249 * maximum number of characters for a string
250 */
251size_t
252RobotinoSensorInterface::maxlenof_bumper() const
253{
254 return 1;
255}
256
257/** Set bumper value.
258 * Bumper pressed indicator.
259 * @param new_bumper new bumper value
260 */
261void
262RobotinoSensorInterface::set_bumper(const bool new_bumper)
263{
264 set_field(data->bumper, new_bumper);
265}
266
267/** Get distance value.
268 * Distance sensor values.
269 * @return distance value
270 */
271float *
272RobotinoSensorInterface::distance() const
273{
274 return data->distance;
275}
276
277/** Get distance value at given index.
278 * Distance sensor values.
279 * @param index index of value
280 * @return distance value
281 * @exception Exception thrown if index is out of bounds
282 */
283float
284RobotinoSensorInterface::distance(unsigned int index) const
285{
286 if (index > 8) {
287 throw Exception("Index value %u out of bounds (0..8)", index);
288 }
289 return data->distance[index];
290}
291
292/** Get maximum length of distance value.
293 * @return length of distance value, can be length of the array or number of
294 * maximum number of characters for a string
295 */
296size_t
297RobotinoSensorInterface::maxlenof_distance() const
298{
299 return 9;
300}
301
302/** Set distance value.
303 * Distance sensor values.
304 * @param new_distance new distance value
305 */
306void
307RobotinoSensorInterface::set_distance(const float * new_distance)
308{
309 set_field(data->distance, new_distance);
310}
311
312/** Set distance value at given index.
313 * Distance sensor values.
314 * @param new_distance new distance value
315 * @param index index for of the value
316 */
317void
318RobotinoSensorInterface::set_distance(unsigned int index, const float new_distance)
319{
320 set_field(data->distance, index, new_distance);
321}
322/** Get digital_in value.
323 * Digital input values.
324 * @return digital_in value
325 */
326bool *
327RobotinoSensorInterface::is_digital_in() const
328{
329 return data->digital_in;
330}
331
332/** Get digital_in value at given index.
333 * Digital input values.
334 * @param index index of value
335 * @return digital_in value
336 * @exception Exception thrown if index is out of bounds
337 */
338bool
339RobotinoSensorInterface::is_digital_in(unsigned int index) const
340{
341 if (index > 7) {
342 throw Exception("Index value %u out of bounds (0..7)", index);
343 }
344 return data->digital_in[index];
345}
346
347/** Get maximum length of digital_in value.
348 * @return length of digital_in value, can be length of the array or number of
349 * maximum number of characters for a string
350 */
351size_t
352RobotinoSensorInterface::maxlenof_digital_in() const
353{
354 return 8;
355}
356
357/** Set digital_in value.
358 * Digital input values.
359 * @param new_digital_in new digital_in value
360 */
361void
362RobotinoSensorInterface::set_digital_in(const bool * new_digital_in)
363{
364 set_field(data->digital_in, new_digital_in);
365}
366
367/** Set digital_in value at given index.
368 * Digital input values.
369 * @param new_digital_in new digital_in value
370 * @param index index for of the value
371 */
372void
373RobotinoSensorInterface::set_digital_in(unsigned int index, const bool new_digital_in)
374{
375 set_field(data->digital_in, index, new_digital_in);
376}
377/** Get digital_out value.
378 * Digital output values.
379 * @return digital_out value
380 */
381bool *
382RobotinoSensorInterface::is_digital_out() const
383{
384 return data->digital_out;
385}
386
387/** Get digital_out value at given index.
388 * Digital output values.
389 * @param index index of value
390 * @return digital_out value
391 * @exception Exception thrown if index is out of bounds
392 */
393bool
394RobotinoSensorInterface::is_digital_out(unsigned int index) const
395{
396 if (index > 7) {
397 throw Exception("Index value %u out of bounds (0..7)", index);
398 }
399 return data->digital_out[index];
400}
401
402/** Get maximum length of digital_out value.
403 * @return length of digital_out value, can be length of the array or number of
404 * maximum number of characters for a string
405 */
406size_t
407RobotinoSensorInterface::maxlenof_digital_out() const
408{
409 return 8;
410}
411
412/** Set digital_out value.
413 * Digital output values.
414 * @param new_digital_out new digital_out value
415 */
416void
417RobotinoSensorInterface::set_digital_out(const bool * new_digital_out)
418{
419 set_field(data->digital_out, new_digital_out);
420}
421
422/** Set digital_out value at given index.
423 * Digital output values.
424 * @param new_digital_out new digital_out value
425 * @param index index for of the value
426 */
427void
428RobotinoSensorInterface::set_digital_out(unsigned int index, const bool new_digital_out)
429{
430 set_field(data->digital_out, index, new_digital_out);
431}
432/** Get analog_in value.
433 * Analog input values.
434 * @return analog_in value
435 */
436float *
437RobotinoSensorInterface::analog_in() const
438{
439 return data->analog_in;
440}
441
442/** Get analog_in value at given index.
443 * Analog input values.
444 * @param index index of value
445 * @return analog_in value
446 * @exception Exception thrown if index is out of bounds
447 */
448float
449RobotinoSensorInterface::analog_in(unsigned int index) const
450{
451 if (index > 7) {
452 throw Exception("Index value %u out of bounds (0..7)", index);
453 }
454 return data->analog_in[index];
455}
456
457/** Get maximum length of analog_in value.
458 * @return length of analog_in value, can be length of the array or number of
459 * maximum number of characters for a string
460 */
461size_t
462RobotinoSensorInterface::maxlenof_analog_in() const
463{
464 return 8;
465}
466
467/** Set analog_in value.
468 * Analog input values.
469 * @param new_analog_in new analog_in value
470 */
471void
472RobotinoSensorInterface::set_analog_in(const float * new_analog_in)
473{
474 set_field(data->analog_in, new_analog_in);
475}
476
477/** Set analog_in value at given index.
478 * Analog input values.
479 * @param new_analog_in new analog_in value
480 * @param index index for of the value
481 */
482void
483RobotinoSensorInterface::set_analog_in(unsigned int index, const float new_analog_in)
484{
485 set_field(data->analog_in, index, new_analog_in);
486}
487/** Get bumper_estop_enabled value.
488 *
489 True if emergency stop on bumper contact is enabled, false otherwise.
490
491 * @return bumper_estop_enabled value
492 */
493bool
494RobotinoSensorInterface::is_bumper_estop_enabled() const
495{
496 return data->bumper_estop_enabled;
497}
498
499/** Get maximum length of bumper_estop_enabled value.
500 * @return length of bumper_estop_enabled value, can be length of the array or number of
501 * maximum number of characters for a string
502 */
503size_t
504RobotinoSensorInterface::maxlenof_bumper_estop_enabled() const
505{
506 return 1;
507}
508
509/** Set bumper_estop_enabled value.
510 *
511 True if emergency stop on bumper contact is enabled, false otherwise.
512
513 * @param new_bumper_estop_enabled new bumper_estop_enabled value
514 */
515void
516RobotinoSensorInterface::set_bumper_estop_enabled(const bool new_bumper_estop_enabled)
517{
518 set_field(data->bumper_estop_enabled, new_bumper_estop_enabled);
519}
520
521/* =========== message create =========== */
522Message *
523RobotinoSensorInterface::create_message(const char *type) const
524{
525 if ( strncmp("SetBumperEStopEnabledMessage", type, INTERFACE_MESSAGE_TYPE_SIZE_ - 1) == 0 ) {
526 return new SetBumperEStopEnabledMessage();
527 } else if ( strncmp("SetDigitalOutputMessage", type, INTERFACE_MESSAGE_TYPE_SIZE_ - 1) == 0 ) {
528 return new SetDigitalOutputMessage();
529 } else {
530 throw UnknownTypeException("The given type '%s' does not match any known "
531 "message type for this interface type.", type);
532 }
533}
534
535
536/** Copy values from other interface.
537 * @param other other interface to copy values from
538 */
539void
540RobotinoSensorInterface::copy_values(const Interface *other)
541{
542 const RobotinoSensorInterface *oi = dynamic_cast<const RobotinoSensorInterface *>(other);
543 if (oi == NULL) {
544 throw TypeMismatchException("Can only copy values from interface of same type (%s vs. %s)",
545 type(), other->type());
546 }
547 memcpy(data, oi->data, sizeof(RobotinoSensorInterface_data_t));
548}
549
550const char *
551RobotinoSensorInterface::enum_tostring(const char *enumtype, int val) const
552{
553 throw UnknownTypeException("Unknown enum type %s", enumtype);
554}
555
556/* =========== messages =========== */
557/** @class RobotinoSensorInterface::SetBumperEStopEnabledMessage <interfaces/RobotinoSensorInterface.h>
558 * SetBumperEStopEnabledMessage Fawkes BlackBoard Interface Message.
559 *
560
561 */
562
563
564/** Constructor with initial values.
565 * @param ini_enabled initial value for enabled
566 */
567RobotinoSensorInterface::SetBumperEStopEnabledMessage::SetBumperEStopEnabledMessage(const bool ini_enabled) : Message("SetBumperEStopEnabledMessage")
568{
569 data_size = sizeof(SetBumperEStopEnabledMessage_data_t);
570 data_ptr = malloc(data_size);
571 memset(data_ptr, 0, data_size);
572 data = (SetBumperEStopEnabledMessage_data_t *)data_ptr;
574 data->enabled = ini_enabled;
575 add_fieldinfo(IFT_BOOL, "enabled", 1, &data->enabled);
576}
577/** Constructor */
579{
580 data_size = sizeof(SetBumperEStopEnabledMessage_data_t);
581 data_ptr = malloc(data_size);
582 memset(data_ptr, 0, data_size);
583 data = (SetBumperEStopEnabledMessage_data_t *)data_ptr;
585 add_fieldinfo(IFT_BOOL, "enabled", 1, &data->enabled);
586}
587
588/** Destructor */
590{
591 free(data_ptr);
592}
593
594/** Copy constructor.
595 * @param m message to copy from
596 */
598{
599 data_size = m->data_size;
600 data_ptr = malloc(data_size);
601 memcpy(data_ptr, m->data_ptr, data_size);
602 data = (SetBumperEStopEnabledMessage_data_t *)data_ptr;
604}
605
606/* Methods */
607/** Get enabled value.
608 *
609 True to enable emergency stop on bumper contact, false to
610 disable. This will persist over OpenRobotino stated restarts.
611
612 * @return enabled value
613 */
614bool
616{
617 return data->enabled;
618}
619
620/** Get maximum length of enabled value.
621 * @return length of enabled value, can be length of the array or number of
622 * maximum number of characters for a string
623 */
624size_t
626{
627 return 1;
628}
629
630/** Set enabled value.
631 *
632 True to enable emergency stop on bumper contact, false to
633 disable. This will persist over OpenRobotino stated restarts.
634
635 * @param new_enabled new enabled value
636 */
637void
639{
640 set_field(data->enabled, new_enabled);
641}
642
643/** Clone this message.
644 * Produces a message of the same type as this message and copies the
645 * data to the new message.
646 * @return clone of this message
647 */
648Message *
650{
652}
653/** @class RobotinoSensorInterface::SetDigitalOutputMessage <interfaces/RobotinoSensorInterface.h>
654 * SetDigitalOutputMessage Fawkes BlackBoard Interface Message.
655 *
656
657 */
658
659
660/** Constructor with initial values.
661 * @param ini_digital_out initial value for digital_out
662 * @param ini_enabled initial value for enabled
663 */
664RobotinoSensorInterface::SetDigitalOutputMessage::SetDigitalOutputMessage(const uint8_t ini_digital_out, const bool ini_enabled) : Message("SetDigitalOutputMessage")
665{
666 data_size = sizeof(SetDigitalOutputMessage_data_t);
667 data_ptr = malloc(data_size);
668 memset(data_ptr, 0, data_size);
669 data = (SetDigitalOutputMessage_data_t *)data_ptr;
671 data->digital_out = ini_digital_out;
672 data->enabled = ini_enabled;
673 add_fieldinfo(IFT_UINT8, "digital_out", 1, &data->digital_out);
674 add_fieldinfo(IFT_BOOL, "enabled", 1, &data->enabled);
675}
676/** Constructor */
678{
679 data_size = sizeof(SetDigitalOutputMessage_data_t);
680 data_ptr = malloc(data_size);
681 memset(data_ptr, 0, data_size);
682 data = (SetDigitalOutputMessage_data_t *)data_ptr;
684 add_fieldinfo(IFT_UINT8, "digital_out", 1, &data->digital_out);
685 add_fieldinfo(IFT_BOOL, "enabled", 1, &data->enabled);
686}
687
688/** Destructor */
690{
691 free(data_ptr);
692}
693
694/** Copy constructor.
695 * @param m message to copy from
696 */
698{
699 data_size = m->data_size;
700 data_ptr = malloc(data_size);
701 memcpy(data_ptr, m->data_ptr, data_size);
702 data = (SetDigitalOutputMessage_data_t *)data_ptr;
704}
705
706/* Methods */
707/** Get digital_out value.
708 *
709 The number of the digital output to set.
710
711 * @return digital_out value
712 */
713uint8_t
715{
716 return data->digital_out;
717}
718
719/** Get maximum length of digital_out value.
720 * @return length of digital_out value, can be length of the array or number of
721 * maximum number of characters for a string
722 */
723size_t
725{
726 return 1;
727}
728
729/** Set digital_out value.
730 *
731 The number of the digital output to set.
732
733 * @param new_digital_out new digital_out value
734 */
735void
737{
738 set_field(data->digital_out, new_digital_out);
739}
740
741/** Get enabled value.
742 *
743 True to enable digital out, false to disable.
744
745 * @return enabled value
746 */
747bool
749{
750 return data->enabled;
751}
752
753/** Get maximum length of enabled value.
754 * @return length of enabled value, can be length of the array or number of
755 * maximum number of characters for a string
756 */
757size_t
759{
760 return 1;
761}
762
763/** Set enabled value.
764 *
765 True to enable digital out, false to disable.
766
767 * @param new_enabled new enabled value
768 */
769void
771{
772 set_field(data->enabled, new_enabled);
773}
774
775/** Clone this message.
776 * Produces a message of the same type as this message and copies the
777 * data to the new message.
778 * @return clone of this message
779 */
780Message *
782{
784}
785/** Check if message is valid and can be enqueued.
786 * @param message Message to check
787 * @return true if the message is valid, false otherwise.
788 */
789bool
791{
792 const SetBumperEStopEnabledMessage *m0 = dynamic_cast<const SetBumperEStopEnabledMessage *>(message);
793 if ( m0 != NULL ) {
794 return true;
795 }
796 const SetDigitalOutputMessage *m1 = dynamic_cast<const SetDigitalOutputMessage *>(message);
797 if ( m1 != NULL ) {
798 return true;
799 }
800 return false;
801}
802
803/// @cond INTERNALS
804EXPORT_INTERFACE(RobotinoSensorInterface)
805/// @endcond
806
807
808} // end namespace fawkes
Base class for exceptions in Fawkes.
Definition: exception.h:36
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:80
const char * type() const
Get type of interface.
Definition: interface.cpp:652
void * data_ptr
Pointer to local memory storage.
Definition: interface.h:244
void set_field(FieldT &field, DataT &data)
Set a field, set data_changed to true and update data_changed accordingly.
Definition: interface.h:304
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Definition: message.h:44
void add_fieldinfo(interface_fieldtype_t type, const char *name, size_t length, void *value, const char *enumtype=0, const interface_enum_map_t *enum_map=0)
Add an entry to the info list.
Definition: message.cpp:435
void * data_ptr
Pointer to memory that contains local data.
Definition: message.h:146
message_data_ts_t * data_ts
data timestamp aliasing pointer
Definition: message.h:156
unsigned int data_size
Size of memory needed to hold all data.
Definition: message.h:147
SetBumperEStopEnabledMessage Fawkes BlackBoard Interface Message.
size_t maxlenof_enabled() const
Get maximum length of enabled value.
void set_enabled(const bool new_enabled)
Set enabled value.
SetDigitalOutputMessage Fawkes BlackBoard Interface Message.
void set_enabled(const bool new_enabled)
Set enabled value.
void set_digital_out(const uint8_t new_digital_out)
Set digital_out value.
size_t maxlenof_enabled() const
Get maximum length of enabled value.
size_t maxlenof_digital_out() const
Get maximum length of digital_out value.
RobotinoSensorInterface Fawkes BlackBoard Interface.
virtual bool message_valid(const Message *message) const
Check if message is valid and can be enqueued.
Fawkes library namespace.
@ IFT_BOOL
boolean field
Definition: types.h:37
@ IFT_UINT8
8 bit unsigned integer field
Definition: types.h:39
Timestamp data, must be present and first entries for each interface data structs!...
Definition: message.h:152