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
35
36namespace armarx
37{
38
40 {
41 public:
43 {
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 ,");
50 "Outputfile",
51 "topic_recording.bag",
52 "File to write the output to. The file will be overwritten if the file exists");
54 "TimestampedFilename", true, "If true, a timestamp is added to the filename");
56 "StorageMode",
57 "database",
58 "Storage variant to use, currently 'database' (default) and 'file' are available");
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
147 IceUtil::Time startTime;
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
constexpr T c
ComponentPropertyDefinitions(std::string prefix, bool hasObjectNameParameter=true)
Definition Component.cpp:46
Component()
Protected default constructor. Used for virtual inheritance. Use createManagedIceObject() instead.
Definition Component.cpp:66
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
PropertyDefinition< PropertyType > & defineRequiredProperty(const std::string &name, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
IceUtil::Handle< RunningTask< T > > pointer_type
Shared pointer type for convenience.
void onInitComponent() override
Pure virtual hook for the subclass.
std::condition_variable idleCondition
RunningTask< TopicRecorderComponent >::pointer_type queueTask
bool isRecording(const Ice::Current &c=Ice::emptyCurrent) override
void startRecording(const int maxDuration, const Ice::Current &c=Ice::emptyCurrent) override
void setOutputFilename(const std::string &newFilename, const Ice::Current &c=Ice::emptyCurrent) override
void onDisconnectComponent() override
Hook for subclass.
std::map< std::string, GenericTopicSubscriberPtr > topicsSubscribers
void stopRecording(const Ice::Current &c=Ice::emptyCurrent) override
TopicRecorderListenerInterfacePrx topicRecoderListener
void onConnectComponent() override
Pure virtual hook for the subclass.
PropertyDefinitionsPtr createPropertyDefinitions() override
std::filesystem::path outputfilePath
void onExitComponent() override
Hook for subclass.
std::string getDefaultName() const override
Retrieve default name of component.
TopicWriterInterfacePtr writer
std::shared_ptr< std::ofstream > log
TopicRecorderProperties(std::string prefix)
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< TopicWriterInterface > TopicWriterInterfacePtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.