Fawkes API Fawkes Development Version
SkillerInterface.cpp
1
2/***************************************************************************
3 * SkillerInterface.cpp - Fawkes BlackBoard Interface - SkillerInterface
4 *
5 * Templated created: Thu Oct 12 10:49:19 2006
6 * Copyright 2008 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/SkillerInterface.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 SkillerInterface <interfaces/SkillerInterface.h>
36 * SkillerInterface Fawkes BlackBoard Interface.
37 *
38 The interface provides access to the skill execution runtime plugin.
39 It provides basic status information about skiller and allows for
40 calling skills via messages. It can also be used to manually restart
41 the Lua interpreter if something is wedged.
42
43 * @ingroup FawkesInterfaces
44 */
45
46
47
48/** Constructor */
49SkillerInterface::SkillerInterface() : Interface()
50{
51 data_size = sizeof(SkillerInterface_data_t);
52 data_ptr = malloc(data_size);
53 data = (SkillerInterface_data_t *)data_ptr;
54 data_ts = (interface_data_ts_t *)data_ptr;
55 memset(data_ptr, 0, data_size);
56 enum_map_SkillStatusEnum[(int)S_INACTIVE] = "S_INACTIVE";
57 enum_map_SkillStatusEnum[(int)S_FINAL] = "S_FINAL";
58 enum_map_SkillStatusEnum[(int)S_RUNNING] = "S_RUNNING";
59 enum_map_SkillStatusEnum[(int)S_FAILED] = "S_FAILED";
60 add_fieldinfo(IFT_STRING, "skill_string", 1024, data->skill_string);
61 add_fieldinfo(IFT_STRING, "error", 128, data->error);
62 add_fieldinfo(IFT_STRING, "exclusive_controller", 37, data->exclusive_controller);
63 add_fieldinfo(IFT_UINT32, "msgid", 1, &data->msgid);
64 add_fieldinfo(IFT_ENUM, "status", 1, &data->status, "SkillStatusEnum", &enum_map_SkillStatusEnum);
65 add_messageinfo("ExecSkillMessage");
66 add_messageinfo("RestartInterpreterMessage");
67 add_messageinfo("StopExecMessage");
68 add_messageinfo("AcquireControlMessage");
69 add_messageinfo("ReleaseControlMessage");
70 unsigned char tmp_hash[] = {0xe, 00, 0x50, 0xea, 0xd0, 0x19, 0x76, 0xd1, 0x45, 0xc7, 0xd, 0xde, 0xff, 0x5b, 0x10, 0xa6};
71 set_hash(tmp_hash);
72}
73
74/** Destructor */
75SkillerInterface::~SkillerInterface()
76{
77 free(data_ptr);
78}
79/** Convert SkillStatusEnum constant to string.
80 * @param value value to convert to string
81 * @return constant value as string.
82 */
83const char *
84SkillerInterface::tostring_SkillStatusEnum(SkillStatusEnum value) const
85{
86 switch (value) {
87 case S_INACTIVE: return "S_INACTIVE";
88 case S_FINAL: return "S_FINAL";
89 case S_RUNNING: return "S_RUNNING";
90 case S_FAILED: return "S_FAILED";
91 default: return "UNKNOWN";
92 }
93}
94/* Methods */
95/** Get skill_string value.
96 *
97 Currently executed skill string, at least the first 1023 bytes of it.
98 Must be properly null-terminated.
99
100 * @return skill_string value
101 */
102char *
103SkillerInterface::skill_string() const
104{
105 return data->skill_string;
106}
107
108/** Get maximum length of skill_string value.
109 * @return length of skill_string value, can be length of the array or number of
110 * maximum number of characters for a string
111 */
112size_t
113SkillerInterface::maxlenof_skill_string() const
114{
115 return 1024;
116}
117
118/** Set skill_string value.
119 *
120 Currently executed skill string, at least the first 1023 bytes of it.
121 Must be properly null-terminated.
122
123 * @param new_skill_string new skill_string value
124 */
125void
126SkillerInterface::set_skill_string(const char * new_skill_string)
127{
128 set_field(data->skill_string, new_skill_string);
129}
130
131/** Get error value.
132 *
133 String describing the error. Can be set by a skill when it fails.
134
135 * @return error value
136 */
137char *
138SkillerInterface::error() const
139{
140 return data->error;
141}
142
143/** Get maximum length of error value.
144 * @return length of error value, can be length of the array or number of
145 * maximum number of characters for a string
146 */
147size_t
148SkillerInterface::maxlenof_error() const
149{
150 return 128;
151}
152
153/** Set error value.
154 *
155 String describing the error. Can be set by a skill when it fails.
156
157 * @param new_error new error value
158 */
159void
160SkillerInterface::set_error(const char * new_error)
161{
162 set_field(data->error, new_error);
163}
164
165/** Get exclusive_controller value.
166 *
167 Instance serial of the exclusive controller of the skiller. If this does not
168 carry your instance serial your exec messages will be ignored. Aquire control with
169 the AquireControlMessage. Make sure you release control before exiting.
170 The serial is a null-terminated 36 character string.
171
172 * @return exclusive_controller value
173 */
174char *
175SkillerInterface::exclusive_controller() const
176{
177 return data->exclusive_controller;
178}
179
180/** Get maximum length of exclusive_controller value.
181 * @return length of exclusive_controller value, can be length of the array or number of
182 * maximum number of characters for a string
183 */
184size_t
185SkillerInterface::maxlenof_exclusive_controller() const
186{
187 return 37;
188}
189
190/** Set exclusive_controller value.
191 *
192 Instance serial of the exclusive controller of the skiller. If this does not
193 carry your instance serial your exec messages will be ignored. Aquire control with
194 the AquireControlMessage. Make sure you release control before exiting.
195 The serial is a null-terminated 36 character string.
196
197 * @param new_exclusive_controller new exclusive_controller value
198 */
199void
200SkillerInterface::set_exclusive_controller(const char * new_exclusive_controller)
201{
202 set_field(data->exclusive_controller, new_exclusive_controller);
203}
204
205/** Get msgid value.
206 *
207 The ID of the message that is currently being processed,
208 or 0 if no message is being processed.
209
210 * @return msgid value
211 */
212uint32_t
213SkillerInterface::msgid() const
214{
215 return data->msgid;
216}
217
218/** Get maximum length of msgid value.
219 * @return length of msgid value, can be length of the array or number of
220 * maximum number of characters for a string
221 */
222size_t
223SkillerInterface::maxlenof_msgid() const
224{
225 return 1;
226}
227
228/** Set msgid value.
229 *
230 The ID of the message that is currently being processed,
231 or 0 if no message is being processed.
232
233 * @param new_msgid new msgid value
234 */
235void
236SkillerInterface::set_msgid(const uint32_t new_msgid)
237{
238 set_field(data->msgid, new_msgid);
239}
240
241/** Get status value.
242 *
243 The status of the current skill execution.
244
245 * @return status value
246 */
248SkillerInterface::status() const
249{
250 return (SkillerInterface::SkillStatusEnum)data->status;
251}
252
253/** Get maximum length of status value.
254 * @return length of status value, can be length of the array or number of
255 * maximum number of characters for a string
256 */
257size_t
258SkillerInterface::maxlenof_status() const
259{
260 return 1;
261}
262
263/** Set status value.
264 *
265 The status of the current skill execution.
266
267 * @param new_status new status value
268 */
269void
270SkillerInterface::set_status(const SkillStatusEnum new_status)
271{
272 set_field(data->status, new_status);
273}
274
275/* =========== message create =========== */
276Message *
277SkillerInterface::create_message(const char *type) const
278{
279 if ( strncmp("ExecSkillMessage", type, INTERFACE_MESSAGE_TYPE_SIZE_ - 1) == 0 ) {
280 return new ExecSkillMessage();
281 } else if ( strncmp("RestartInterpreterMessage", type, INTERFACE_MESSAGE_TYPE_SIZE_ - 1) == 0 ) {
282 return new RestartInterpreterMessage();
283 } else if ( strncmp("StopExecMessage", type, INTERFACE_MESSAGE_TYPE_SIZE_ - 1) == 0 ) {
284 return new StopExecMessage();
285 } else if ( strncmp("AcquireControlMessage", type, INTERFACE_MESSAGE_TYPE_SIZE_ - 1) == 0 ) {
286 return new AcquireControlMessage();
287 } else if ( strncmp("ReleaseControlMessage", type, INTERFACE_MESSAGE_TYPE_SIZE_ - 1) == 0 ) {
288 return new ReleaseControlMessage();
289 } else {
290 throw UnknownTypeException("The given type '%s' does not match any known "
291 "message type for this interface type.", type);
292 }
293}
294
295
296/** Copy values from other interface.
297 * @param other other interface to copy values from
298 */
299void
300SkillerInterface::copy_values(const Interface *other)
301{
302 const SkillerInterface *oi = dynamic_cast<const SkillerInterface *>(other);
303 if (oi == NULL) {
304 throw TypeMismatchException("Can only copy values from interface of same type (%s vs. %s)",
305 type(), other->type());
306 }
307 memcpy(data, oi->data, sizeof(SkillerInterface_data_t));
308}
309
310const char *
311SkillerInterface::enum_tostring(const char *enumtype, int val) const
312{
313 if (strcmp(enumtype, "SkillStatusEnum") == 0) {
314 return tostring_SkillStatusEnum((SkillStatusEnum)val);
315 }
316 throw UnknownTypeException("Unknown enum type %s", enumtype);
317}
318
319/* =========== messages =========== */
320/** @class SkillerInterface::ExecSkillMessage <interfaces/SkillerInterface.h>
321 * ExecSkillMessage Fawkes BlackBoard Interface Message.
322 *
323
324 */
325
326
327/** Constructor with initial values.
328 * @param ini_skill_string initial value for skill_string
329 */
330SkillerInterface::ExecSkillMessage::ExecSkillMessage(const char * ini_skill_string) : Message("ExecSkillMessage")
331{
332 data_size = sizeof(ExecSkillMessage_data_t);
333 data_ptr = malloc(data_size);
334 memset(data_ptr, 0, data_size);
335 data = (ExecSkillMessage_data_t *)data_ptr;
337 strncpy(data->skill_string, ini_skill_string, 1024-1);
338 data->skill_string[1024-1] = 0;
339 enum_map_SkillStatusEnum[(int)S_INACTIVE] = "S_INACTIVE";
340 enum_map_SkillStatusEnum[(int)S_FINAL] = "S_FINAL";
341 enum_map_SkillStatusEnum[(int)S_RUNNING] = "S_RUNNING";
342 enum_map_SkillStatusEnum[(int)S_FAILED] = "S_FAILED";
343 add_fieldinfo(IFT_STRING, "skill_string", 1024, data->skill_string);
344}
345/** Constructor */
347{
348 data_size = sizeof(ExecSkillMessage_data_t);
349 data_ptr = malloc(data_size);
350 memset(data_ptr, 0, data_size);
351 data = (ExecSkillMessage_data_t *)data_ptr;
353 enum_map_SkillStatusEnum[(int)S_INACTIVE] = "S_INACTIVE";
354 enum_map_SkillStatusEnum[(int)S_FINAL] = "S_FINAL";
355 enum_map_SkillStatusEnum[(int)S_RUNNING] = "S_RUNNING";
356 enum_map_SkillStatusEnum[(int)S_FAILED] = "S_FAILED";
357 add_fieldinfo(IFT_STRING, "skill_string", 1024, data->skill_string);
358}
359
360/** Destructor */
362{
363 free(data_ptr);
364}
365
366/** Copy constructor.
367 * @param m message to copy from
368 */
370{
371 data_size = m->data_size;
372 data_ptr = malloc(data_size);
373 memcpy(data_ptr, m->data_ptr, data_size);
374 data = (ExecSkillMessage_data_t *)data_ptr;
376}
377
378/* Methods */
379/** Get skill_string value.
380 *
381 Currently executed skill string, at least the first 1023 bytes of it.
382 Must be properly null-terminated.
383
384 * @return skill_string value
385 */
386char *
388{
389 return data->skill_string;
390}
391
392/** Get maximum length of skill_string value.
393 * @return length of skill_string value, can be length of the array or number of
394 * maximum number of characters for a string
395 */
396size_t
398{
399 return 1024;
400}
401
402/** Set skill_string value.
403 *
404 Currently executed skill string, at least the first 1023 bytes of it.
405 Must be properly null-terminated.
406
407 * @param new_skill_string new skill_string value
408 */
409void
411{
412 set_field(data->skill_string, new_skill_string);
413}
414
415/** Clone this message.
416 * Produces a message of the same type as this message and copies the
417 * data to the new message.
418 * @return clone of this message
419 */
420Message *
422{
423 return new SkillerInterface::ExecSkillMessage(this);
424}
425/** @class SkillerInterface::RestartInterpreterMessage <interfaces/SkillerInterface.h>
426 * RestartInterpreterMessage Fawkes BlackBoard Interface Message.
427 *
428
429 */
430
431
432/** Constructor */
434{
435 data_size = sizeof(RestartInterpreterMessage_data_t);
436 data_ptr = malloc(data_size);
437 memset(data_ptr, 0, data_size);
438 data = (RestartInterpreterMessage_data_t *)data_ptr;
440 enum_map_SkillStatusEnum[(int)S_INACTIVE] = "S_INACTIVE";
441 enum_map_SkillStatusEnum[(int)S_FINAL] = "S_FINAL";
442 enum_map_SkillStatusEnum[(int)S_RUNNING] = "S_RUNNING";
443 enum_map_SkillStatusEnum[(int)S_FAILED] = "S_FAILED";
444}
445
446/** Destructor */
448{
449 free(data_ptr);
450}
451
452/** Copy constructor.
453 * @param m message to copy from
454 */
456{
457 data_size = m->data_size;
458 data_ptr = malloc(data_size);
459 memcpy(data_ptr, m->data_ptr, data_size);
460 data = (RestartInterpreterMessage_data_t *)data_ptr;
462}
463
464/* Methods */
465/** Clone this message.
466 * Produces a message of the same type as this message and copies the
467 * data to the new message.
468 * @return clone of this message
469 */
470Message *
472{
474}
475/** @class SkillerInterface::StopExecMessage <interfaces/SkillerInterface.h>
476 * StopExecMessage Fawkes BlackBoard Interface Message.
477 *
478
479 */
480
481
482/** Constructor */
484{
485 data_size = sizeof(StopExecMessage_data_t);
486 data_ptr = malloc(data_size);
487 memset(data_ptr, 0, data_size);
488 data = (StopExecMessage_data_t *)data_ptr;
490 enum_map_SkillStatusEnum[(int)S_INACTIVE] = "S_INACTIVE";
491 enum_map_SkillStatusEnum[(int)S_FINAL] = "S_FINAL";
492 enum_map_SkillStatusEnum[(int)S_RUNNING] = "S_RUNNING";
493 enum_map_SkillStatusEnum[(int)S_FAILED] = "S_FAILED";
494}
495
496/** Destructor */
498{
499 free(data_ptr);
500}
501
502/** Copy constructor.
503 * @param m message to copy from
504 */
506{
507 data_size = m->data_size;
508 data_ptr = malloc(data_size);
509 memcpy(data_ptr, m->data_ptr, data_size);
510 data = (StopExecMessage_data_t *)data_ptr;
512}
513
514/* Methods */
515/** Clone this message.
516 * Produces a message of the same type as this message and copies the
517 * data to the new message.
518 * @return clone of this message
519 */
520Message *
522{
523 return new SkillerInterface::StopExecMessage(this);
524}
525/** @class SkillerInterface::AcquireControlMessage <interfaces/SkillerInterface.h>
526 * AcquireControlMessage Fawkes BlackBoard Interface Message.
527 *
528
529 */
530
531
532/** Constructor with initial values.
533 * @param ini_steal_control initial value for steal_control
534 */
535SkillerInterface::AcquireControlMessage::AcquireControlMessage(const bool ini_steal_control) : Message("AcquireControlMessage")
536{
537 data_size = sizeof(AcquireControlMessage_data_t);
538 data_ptr = malloc(data_size);
539 memset(data_ptr, 0, data_size);
540 data = (AcquireControlMessage_data_t *)data_ptr;
542 data->steal_control = ini_steal_control;
543 enum_map_SkillStatusEnum[(int)S_INACTIVE] = "S_INACTIVE";
544 enum_map_SkillStatusEnum[(int)S_FINAL] = "S_FINAL";
545 enum_map_SkillStatusEnum[(int)S_RUNNING] = "S_RUNNING";
546 enum_map_SkillStatusEnum[(int)S_FAILED] = "S_FAILED";
547 add_fieldinfo(IFT_BOOL, "steal_control", 1, &data->steal_control);
548}
549/** Constructor */
551{
552 data_size = sizeof(AcquireControlMessage_data_t);
553 data_ptr = malloc(data_size);
554 memset(data_ptr, 0, data_size);
555 data = (AcquireControlMessage_data_t *)data_ptr;
557 enum_map_SkillStatusEnum[(int)S_INACTIVE] = "S_INACTIVE";
558 enum_map_SkillStatusEnum[(int)S_FINAL] = "S_FINAL";
559 enum_map_SkillStatusEnum[(int)S_RUNNING] = "S_RUNNING";
560 enum_map_SkillStatusEnum[(int)S_FAILED] = "S_FAILED";
561 add_fieldinfo(IFT_BOOL, "steal_control", 1, &data->steal_control);
562}
563
564/** Destructor */
566{
567 free(data_ptr);
568}
569
570/** Copy constructor.
571 * @param m message to copy from
572 */
574{
575 data_size = m->data_size;
576 data_ptr = malloc(data_size);
577 memcpy(data_ptr, m->data_ptr, data_size);
578 data = (AcquireControlMessage_data_t *)data_ptr;
580}
581
582/* Methods */
583/** Get steal_control value.
584 *
585 If set to true steal the control from someone else who has it
586 atm. Use this with caution. But sometimes it is necessary to
587 ensure a successful operation, e.g. if the agent tries to
588 acquire control.
589
590 * @return steal_control value
591 */
592bool
594{
595 return data->steal_control;
596}
597
598/** Get maximum length of steal_control value.
599 * @return length of steal_control value, can be length of the array or number of
600 * maximum number of characters for a string
601 */
602size_t
604{
605 return 1;
606}
607
608/** Set steal_control value.
609 *
610 If set to true steal the control from someone else who has it
611 atm. Use this with caution. But sometimes it is necessary to
612 ensure a successful operation, e.g. if the agent tries to
613 acquire control.
614
615 * @param new_steal_control new steal_control value
616 */
617void
619{
620 set_field(data->steal_control, new_steal_control);
621}
622
623/** Clone this message.
624 * Produces a message of the same type as this message and copies the
625 * data to the new message.
626 * @return clone of this message
627 */
628Message *
630{
632}
633/** @class SkillerInterface::ReleaseControlMessage <interfaces/SkillerInterface.h>
634 * ReleaseControlMessage Fawkes BlackBoard Interface Message.
635 *
636
637 */
638
639
640/** Constructor */
642{
643 data_size = sizeof(ReleaseControlMessage_data_t);
644 data_ptr = malloc(data_size);
645 memset(data_ptr, 0, data_size);
646 data = (ReleaseControlMessage_data_t *)data_ptr;
648 enum_map_SkillStatusEnum[(int)S_INACTIVE] = "S_INACTIVE";
649 enum_map_SkillStatusEnum[(int)S_FINAL] = "S_FINAL";
650 enum_map_SkillStatusEnum[(int)S_RUNNING] = "S_RUNNING";
651 enum_map_SkillStatusEnum[(int)S_FAILED] = "S_FAILED";
652}
653
654/** Destructor */
656{
657 free(data_ptr);
658}
659
660/** Copy constructor.
661 * @param m message to copy from
662 */
664{
665 data_size = m->data_size;
666 data_ptr = malloc(data_size);
667 memcpy(data_ptr, m->data_ptr, data_size);
668 data = (ReleaseControlMessage_data_t *)data_ptr;
670}
671
672/* Methods */
673/** Clone this message.
674 * Produces a message of the same type as this message and copies the
675 * data to the new message.
676 * @return clone of this message
677 */
678Message *
680{
682}
683/** Check if message is valid and can be enqueued.
684 * @param message Message to check
685 * @return true if the message is valid, false otherwise.
686 */
687bool
689{
690 const ExecSkillMessage *m0 = dynamic_cast<const ExecSkillMessage *>(message);
691 if ( m0 != NULL ) {
692 return true;
693 }
694 const RestartInterpreterMessage *m1 = dynamic_cast<const RestartInterpreterMessage *>(message);
695 if ( m1 != NULL ) {
696 return true;
697 }
698 const StopExecMessage *m2 = dynamic_cast<const StopExecMessage *>(message);
699 if ( m2 != NULL ) {
700 return true;
701 }
702 const AcquireControlMessage *m3 = dynamic_cast<const AcquireControlMessage *>(message);
703 if ( m3 != NULL ) {
704 return true;
705 }
706 const ReleaseControlMessage *m4 = dynamic_cast<const ReleaseControlMessage *>(message);
707 if ( m4 != NULL ) {
708 return true;
709 }
710 return false;
711}
712
713/// @cond INTERNALS
714EXPORT_INTERFACE(SkillerInterface)
715/// @endcond
716
717
718} // end namespace fawkes
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
AcquireControlMessage Fawkes BlackBoard Interface Message.
bool is_steal_control() const
Get steal_control value.
void set_steal_control(const bool new_steal_control)
Set steal_control value.
size_t maxlenof_steal_control() const
Get maximum length of steal_control value.
virtual Message * clone() const
Clone this message.
ExecSkillMessage Fawkes BlackBoard Interface Message.
virtual Message * clone() const
Clone this message.
size_t maxlenof_skill_string() const
Get maximum length of skill_string value.
char * skill_string() const
Get skill_string value.
void set_skill_string(const char *new_skill_string)
Set skill_string value.
ReleaseControlMessage Fawkes BlackBoard Interface Message.
virtual Message * clone() const
Clone this message.
RestartInterpreterMessage Fawkes BlackBoard Interface Message.
virtual Message * clone() const
Clone this message.
StopExecMessage Fawkes BlackBoard Interface Message.
virtual Message * clone() const
Clone this message.
SkillerInterface Fawkes BlackBoard Interface.
virtual bool message_valid(const Message *message) const
Check if message is valid and can be enqueued.
SkillStatusEnum
This determines the current status of skill execution.
@ S_INACTIVE
No skill is running.
@ S_RUNNING
The execution is still running.
@ S_FAILED
The execution failed and cannot succeed anymore.
@ S_FINAL
The skill string has been successfully processed.
Fawkes library namespace.
@ IFT_STRING
string field
Definition: types.h:48
@ IFT_BOOL
boolean field
Definition: types.h:37
Timestamp data, must be present and first entries for each interface data structs!...
Definition: message.h:152