Fawkes API  Fawkes Development Version
blocked_timing.cpp
1 
2 /***************************************************************************
3  * blocked_timing.h - Blocked timing aspect for Fawkes
4  *
5  * Created: Thu Jan 11 16:52:28 2007
6  * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
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 <aspect/blocked_timing.h>
25 #include <core/exception.h>
26 #include <core/threading/thread.h>
27 
28 #include <stdexcept>
29 
30 namespace fawkes {
31 
32 /** @class BlockedTimingAspect <aspect/blocked_timing.h>
33  * Thread aspect to use blocked timing.
34  * The Fawkes main application provides basic means to synchronize all
35  * running thread with respect to several given hooks (see WakeupHook).
36  * Threads of a woken up at a particular point in time. The hooks basically
37  * correspond to an extended sense - plan - act kind of loop.
38  * Your thread must run in Thread::OPMODE_WAITFORWAKEUP mode, otherwise it
39  * is not started. This is a requirement for having the BlockedTimingAspect.
40  *
41  * @see Thread::OpMode
42  * @ingroup Aspects
43  * @author Tim Niemueller
44  */
45 
46 // Side note: Overriding Thread::run() can make our requirement useless, but
47 // we believe in the best of the coder: laziness
48 
49 /** Constructor.
50  * This special constructor is needed to define the wakeup point.
51  * @param wakeup_hook hook when this thread should be woken up
52  */
54 : SyncPointAspect(SyncPoint::WAIT_FOR_ALL,
55  blocked_timing_hook_to_start_syncpoint(wakeup_hook),
56  blocked_timing_hook_to_end_syncpoint(wakeup_hook))
57 {
58  add_aspect("BlockedTimingAspect");
59  wakeup_hook_ = wakeup_hook;
60  loop_listener_ = new BlockedTimingLoopListener();
61 }
62 
63 /** Virtual empty destructor. */
65 {
66  delete loop_listener_;
67 }
68 
69 /** Init BlockedTiming aspect.
70  * This intializes the aspect and adds the loop listener to the thread.
71  * @param thread thread which uses this aspect
72  */
73 void
75 {
76  thread->add_loop_listener(loop_listener_);
77  thread->wakeup();
78 }
79 
80 /** Finalize BlockedTiming aspect.
81  * This finalizes the aspect and removes the loop listener from the thread.
82  * @param thread thread which uses this aspect
83  */
84 void
86 {
87  thread->remove_loop_listener(loop_listener_);
88 }
89 
90 /** Get the wakeup hook.
91  * The wakeup hook defines when this thread should be woken up. This heavily
92  * depends on the used main thread.
93  * @return wakeup hook
94  */
97 {
98  return wakeup_hook_;
99 }
100 
101 /** Get string for wakeup hook.
102  * @param hook wakeup hook to get string for
103  * @return string representation of hook
104  */
105 const char *
107 {
108  switch (hook) {
109  case WAKEUP_HOOK_PRE_LOOP: return "WAKEUP_HOOK_PRE_LOOP";
110  case WAKEUP_HOOK_SENSOR_ACQUIRE: return "WAKEUP_HOOK_SENSOR_ACQUIRE";
111  case WAKEUP_HOOK_SENSOR_PREPARE: return "WAKEUP_HOOK_SENSOR_PREPARE";
112  case WAKEUP_HOOK_SENSOR_PROCESS: return "WAKEUP_HOOK_SENSOR_PROCESS";
113  case WAKEUP_HOOK_WORLDSTATE: return "WAKEUP_HOOK_WORLDSTATE";
114  case WAKEUP_HOOK_THINK: return "WAKEUP_HOOK_THINK";
115  case WAKEUP_HOOK_SKILL: return "WAKEUP_HOOK_SKILL";
116  case WAKEUP_HOOK_ACT: return "WAKEUP_HOOK_ACT";
117  case WAKEUP_HOOK_ACT_EXEC: return "WAKEUP_HOOK_ACT_EXEC";
118  case WAKEUP_HOOK_POST_LOOP: return "WAKEUP_HOOK_POST_LOOP";
119  default: throw Exception("Unknown blocked timing wakeup hook");
120  }
121 }
122 
123 const std::map<const BlockedTimingAspect::WakeupHook, const std::string>
124  BlockedTimingAspect::hook_to_syncpoint = {{WAKEUP_HOOK_PRE_LOOP, "/preloop"},
125  {WAKEUP_HOOK_SENSOR_ACQUIRE, "/sensors/acquire"},
126  {WAKEUP_HOOK_SENSOR_PREPARE, "/sensors/prepare"},
127  {WAKEUP_HOOK_SENSOR_PROCESS, "/sensors/process"},
128  {WAKEUP_HOOK_WORLDSTATE, "/worldstate"},
129  {WAKEUP_HOOK_THINK, "/agent"},
130  {WAKEUP_HOOK_SKILL, "/skill"},
131  {WAKEUP_HOOK_ACT, "/act/main"},
132  {WAKEUP_HOOK_ACT_EXEC, "/act/exec"},
133  {WAKEUP_HOOK_POST_LOOP, "/postloop"}};
134 
135 /** Get the syncpoint identifier corresponding to the end of a wakeup hook.
136  * This is the syncpoint emitted at the end of a hook.
137  * @param hook wakeup hook to get the syncpoint identifier for
138  * @return the identifier of the corresponding syncpoint
139  */
140 std::string
142 {
143  try {
144  return std::string(hook_to_syncpoint.at(hook)) + "/end";
145  } catch (const std::out_of_range &e) {
146  throw Exception("Unknown blocked timing wakeup hook. Error: %s", e.what());
147  }
148 }
149 
150 /** Get the syncpoint identifier corresponding to the start of a wakeup hook.
151  * This is the syncpoint waited for at the start of a hook.
152  * @param hook wakeup hook to get the syncpoint identifier for
153  * @return the identifier of the corresponding syncpoint
154  */
155 std::string
157 {
158  try {
159  return std::string(hook_to_syncpoint.at(hook)) + "/start";
160  } catch (const std::out_of_range &e) {
161  throw Exception("Unknown blocked timing wakeup hook. Error: %s", e.what());
162  }
163 }
164 
165 /** The post loop function of the BlockedTimingAspect
166  * This function is called right after the loop of the thread with the aspect.
167  * @param thread thread this loop listener belongs to
168  */
169 void
171 {
172  thread->wakeup();
173 }
174 
175 } // end namespace fawkes
void add_aspect(const char *name)
Add an aspect to a thread.
Definition: aspect.cpp:49
WakeupHook blockedTimingAspectHook() const
Get the wakeup hook.
BlockedTimingAspect(WakeupHook wakeup_hook)
Constructor.
WakeupHook
Type to define at which hook the thread is woken up.
@ WAKEUP_HOOK_SENSOR_ACQUIRE
sensor acquisition thread, acquire data from sensor
@ WAKEUP_HOOK_ACT
act thread (motor module etc.)
@ WAKEUP_HOOK_WORLDSTATE
world state thread
@ WAKEUP_HOOK_PRE_LOOP
before each loop
@ WAKEUP_HOOK_SENSOR_PREPARE
sensor data preparation thread, convert acquired data to usable format
@ WAKEUP_HOOK_THINK
think thread (agent)
@ WAKEUP_HOOK_POST_LOOP
run after loop
@ WAKEUP_HOOK_SKILL
skill thread (skill module)
@ WAKEUP_HOOK_SENSOR_PROCESS
sensor data processing thread
@ WAKEUP_HOOK_ACT_EXEC
act execution thread
static const std::map< const WakeupHook, const std::string > hook_to_syncpoint
Translation from WakeupHooks to SyncPoints.
void finalize_BlockedTimingAspect(Thread *thread)
Finalize BlockedTiming aspect.
static std::string blocked_timing_hook_to_end_syncpoint(WakeupHook hook)
Get the syncpoint identifier corresponding to the end of a wakeup hook.
static std::string blocked_timing_hook_to_start_syncpoint(WakeupHook hook)
Get the syncpoint identifier corresponding to the start of a wakeup hook.
static const char * blocked_timing_hook_to_string(WakeupHook hook)
Get string for wakeup hook.
void init_BlockedTimingAspect(Thread *thread)
Init BlockedTiming aspect.
virtual ~BlockedTimingAspect()
Virtual empty destructor.
Loop Listener of the BlockedTimingAspect.
void post_loop(Thread *thread)
The post loop function of the BlockedTimingAspect This function is called right after the loop of the...
Base class for exceptions in Fawkes.
Definition: exception.h:36
Thread aspect to acces to SyncPoints Give this aspect to your thread to manage SyncPoints,...
Definition: syncpoint.h:35
The SyncPoint class.
Definition: syncpoint.h:50
Thread class encapsulation of pthreads.
Definition: thread.h:46
void add_loop_listener(ThreadLoopListener *loop_listener)
Add loop listener.
Definition: thread.cpp:1181
void wakeup()
Wake up thread.
Definition: thread.cpp:995
void remove_loop_listener(ThreadLoopListener *loop_listener)
Remove loop listener.
Definition: thread.cpp:1190
Fawkes library namespace.