TopicRecorder.h
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package ArmarX
17 * @author Mirko Waechter( mirko.waechter at kit dot edu)
18 * @date 2016
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22 #pragma once
23 
24 
25 #include <condition_variable>
26 #include <filesystem>
27 #include <mutex>
28 
31 #include <ArmarXCore/interface/components/TopicRecorderInterface.h>
32 
33 #include "GenericTopicSubscriber.h"
34 #include "TopicWriterInterface.h"
35 
36 namespace armarx
37 {
38 
40  {
41  public:
43  {
44  defineRequiredProperty<std::string>(
45  "TopicsToLog",
46  "Comma seperated list of topics to log. Use * to record all. To specify the max "
47  "frequency append a : to the topic name, e.g. \"RobotState:10,Log\" Topic names "
48  "must not contain : or ,");
49  defineOptionalProperty<std::string>(
50  "Outputfile",
51  "topic_recording.bag",
52  "File to write the output to. The file will be overwritten if the file exists");
53  defineOptionalProperty<bool>(
54  "TimestampedFilename", true, "If true, a timestamp is added to the filename");
55  defineOptionalProperty<std::string>(
56  "StorageMode",
57  "database",
58  "Storage variant to use, currently 'database' (default) and 'file' are available");
59  defineOptionalProperty<bool>(
60  "EnableRecording",
61  true,
62  "Immediately start recording after the component is launched.");
63  defineOptionalProperty<int>("Duration", 0, "Limit recording.");
64  }
65  };
66 
67  /**
68  * \page ArmarXCore-TopicRecording Recording and Replaying Topics
69  * It is possible to easily record and replay any topic available in ArmarX.
70  * For recording a topic use the app *TopicRecorderAppRun* like this:
71  * \verbatim
72  $ARMARX_CORE/build/bin/TopicRecorderAppRun --ArmarX.TopicRecorder.Outputfile=test.bag --ArmarX.TopicRecorder.TopicsToLog=* --ArmarX.TopicRecorder.TimestampedFilename=false
73  \endverbatim
74  * This will log any topic that was running, when the recorder was **started** and write it to the file *test.bag*.
75  *
76  * To replay this file, use the GUI \ref ArmarXGui-GuiPlugins-TopicReplayer or use the command line tool *TopicReplayerrAppRun* like this:
77  * \verbatim
78  $ARMARX_CORE/build/bin/TopicReplayerAppRun --ArmarX.TopicReplayer.RecordFile=test.bag
79  \endverbatim
80  * This will replay the recorded topics in the same speed as they were recorded.
81  *
82  * You can add the optional values
83  * \verbatim
84  --ArmarX.TopicRecorder.StorageMode="database"
85  --ArmarX.TopicReplayer.StorageMode="database"
86  \endverbatim
87  * or
88  * \verbatim
89  --ArmarX.TopicRecorder.StorageMode="file"
90  --ArmarX.TopicReplayer.StorageMode="file"
91  \endverbatim
92  * to the Recorder and Replayer to switch between the available storage modes, which currently are *sqlite3* database and simple file storage in JSON format with base64 data-encoding.
93  * If you do not specify the storage mode, the default value 'database' is used.
94  *
95  * If you want to play the topic alongside their normal components you need to redirect their topic output.
96  * You can do this by adding the following property to all or some components:
97  * \verbatim
98  --ArmarX.TopicSuffix=/dev/null
99  \endverbatim
100  * This will add a topic suffix to all topics this component requested with the armarx::IceManager convenience functions
101  * (does not work if the component used Ice directly).
102  */
103 
104  class TopicRecorderComponent : public Component, public TopicRecorderInterface
105  {
106  public:
108 
109 
110  void startRecording(const int maxDuration,
111  const Ice::Current& c = Ice::emptyCurrent) override;
112 
113  void stopRecording(const Ice::Current& c = Ice::emptyCurrent) override;
114 
115  void
116  setOutputFilename(const std::string& newFilename,
117  const Ice::Current& c = Ice::emptyCurrent) override
118  {
119  outputFilename = newFilename;
120  }
121 
122  bool
123  isRecording(const Ice::Current& c = Ice::emptyCurrent) override
124  {
125  return isRecordingEnabled;
126  }
127 
128  // PropertyUser interface
130  void wakeUp();
131 
132  // ManagedIceObject interface
133  protected:
134  void onInitComponent() override;
135  void onConnectComponent() override;
136  void onDisconnectComponent() override;
137  void onExitComponent() override;
138  std::string getDefaultName() const override;
139 
140  void write();
141 
142  // Blobject interface
143 
144  protected:
146 
148 
150  std::map<std::string, GenericTopicSubscriberPtr> topicsSubscribers;
151  std::mutex queueMutex;
152  std::condition_variable idleCondition;
153  std::shared_ptr<std::ofstream> log;
154  std::filesystem::path outputfilePath;
155  std::string outputFilename;
156 
158 
160 
161  std::mutex mutex;
162 
163  TopicRecorderListenerInterfacePrx topicRecoderListener;
164  };
165 
166 } // namespace armarx
armarx::TopicRecorderComponent::writer
TopicWriterInterfacePtr writer
Definition: TopicRecorder.h:145
armarx::TopicRecorderComponent
Definition: TopicRecorder.h:104
armarx::TopicRecorderComponent::queueMutex
std::mutex queueMutex
Definition: TopicRecorder.h:151
armarx::TopicRecorderComponent::outputFilename
std::string outputFilename
Definition: TopicRecorder.h:155
armarx::TopicRecorderComponent::maxDuration
int maxDuration
Definition: TopicRecorder.h:157
armarx::TopicRecorderComponent::topicRecoderListener
TopicRecorderListenerInterfacePrx topicRecoderListener
Definition: TopicRecorder.h:163
armarx::TopicRecorderComponent::onExitComponent
void onExitComponent() override
Hook for subclass.
Definition: TopicRecorder.cpp:217
armarx::TopicRecorderComponent::mutex
std::mutex mutex
Definition: TopicRecorder.h:161
armarx::TopicRecorderComponent::stopRecording
void stopRecording(const Ice::Current &c=Ice::emptyCurrent) override
Definition: TopicRecorder.cpp:186
armarx::TopicRecorderComponent::topicsSubscribers
std::map< std::string, GenericTopicSubscriberPtr > topicsSubscribers
Definition: TopicRecorder.h:150
armarx::PropertyDefinitionContainer::prefix
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
Definition: PropertyDefinitionContainer.h:345
armarx::TopicRecorderComponent::startRecording
void startRecording(const int maxDuration, const Ice::Current &c=Ice::emptyCurrent) override
Definition: TopicRecorder.cpp:120
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::TopicRecorderComponent::startTime
IceUtil::Time startTime
Definition: TopicRecorder.h:147
RunningTask.h
TopicWriterInterface.h
armarx::TopicRecorderComponent::log
std::shared_ptr< std::ofstream > log
Definition: TopicRecorder.h:153
armarx::TopicRecorderComponent::isRecordingEnabled
bool isRecordingEnabled
Definition: TopicRecorder.h:159
GenericTopicSubscriber.h
armarx::TopicRecorderProperties::TopicRecorderProperties
TopicRecorderProperties(std::string prefix)
Definition: TopicRecorder.h:42
armarx::TopicRecorderComponent::isRecording
bool isRecording(const Ice::Current &c=Ice::emptyCurrent) override
Definition: TopicRecorder.h:123
armarx::TopicWriterInterfacePtr
std::shared_ptr< TopicWriterInterface > TopicWriterInterfacePtr
Definition: TopicWriterInterface.h:47
armarx::TopicRecorderComponent::write
void write()
Definition: TopicRecorder.cpp:229
armarx::TopicRecorderComponent::idleCondition
std::condition_variable idleCondition
Definition: TopicRecorder.h:152
armarx::TopicRecorderComponent::setOutputFilename
void setOutputFilename(const std::string &newFilename, const Ice::Current &c=Ice::emptyCurrent) override
Definition: TopicRecorder.h:116
armarx::TopicRecorderComponent::getDefaultName
std::string getDefaultName() const override
Retrieve default name of component.
Definition: TopicRecorder.cpp:223
armarx::TopicRecorderComponent::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: TopicRecorder.cpp:69
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
Component.h
armarx::Component
Baseclass for all ArmarX ManagedIceObjects requiring properties.
Definition: Component.h:91
armarx::TopicRecorderComponent::outputfilePath
std::filesystem::path outputfilePath
Definition: TopicRecorder.h:154
armarx::ComponentPropertyDefinitions
Default component property definition container.
Definition: Component.h:69
armarx::TopicRecorderComponent::onDisconnectComponent
void onDisconnectComponent() override
Hook for subclass.
Definition: TopicRecorder.cpp:211
armarx::TopicRecorderComponent::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: TopicRecorder.cpp:60
IceUtil::Handle
Definition: forward_declarations.h:30
armarx::TopicRecorderComponent::createPropertyDefinitions
PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: TopicRecorder.cpp:48
armarx::TopicRecorderComponent::wakeUp
void wakeUp()
Definition: TopicRecorder.cpp:54
armarx::TopicRecorderComponent::queueTask
RunningTask< TopicRecorderComponent >::pointer_type queueTask
Definition: TopicRecorder.h:149
armarx::TopicRecorderProperties
Definition: TopicRecorder.h:39
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::TopicRecorderComponent::TopicRecorderComponent
TopicRecorderComponent()
Definition: TopicRecorder.cpp:42