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