1
0
Fork 0

Added new logging module.

This commit is contained in:
david 2002-03-12 16:29:00 +00:00
parent 9ff8951be6
commit c22018db05
5 changed files with 260 additions and 0 deletions

75
docs-mini/README.logging Normal file
View file

@ -0,0 +1,75 @@
Logging in FlightGear
---------------------
[Note: JSBSim also has its own independent logging facilities, which
are not discussed here.]
FlightGear can log any property values at any interval to one or more
CSV files (which can be read and graphed using spreadsheets like
Gnumeric or Excel). Logging is defined in the '/logging' subbranch of
the main property tree; under '/logging', each '/log' subbranch
defines a separate log with its own output file and interval. Here is
a simple example that logs the rudder and aileron settings every
second (1000ms) to the file steering.csv:
<logging>
<log>
<filename>steering.csv</filename>
<interval-ms>1000</interval-ms>
<entry>
<title>Rudder</title>
<property>/controls/rudder</property>
</entry>
<entry>
<title>Ailerons</title>
<property>/controls/aileron</property>
</entry>
</log>
</logging>
Each 'log' subbranch contains an optional 'filename' property
(defaults to "fg_log.csv"), an optional 'interval-ms' property
(defaults to 0, which logs every frame), and a series of 'entry'
subbranches.
Each 'entry' subbranch contains a 'property' property specifying the
name of the property to be logged, and an optional 'title' property
specifying the title to use in the CSV file (defaults to the full path
of the property). The elapsed time in milliseconds since the start of
the simulation is always included as the first entry with the title
"Time", so there is no need to include it explicitly.
Here's a sample of the logging output for the above log:
Time,Rudder,Ailerons
6522,0.000000,0.000000
7668,-0.000000,0.000000
8702,-0.000000,0.000000
9705,-0.000000,0.000000
10784,-0.000000,0.000000
11792,-0.000000,0.000000
12808,-0.000000,-0.210000
13826,-0.000000,-0.344000
14881,-0.000000,-0.066000
15901,-0.000000,-0.806000
16943,-0.000000,-0.936000
17965,-0.000000,-0.534000
19013,-0.000000,-0.294000
20044,-0.000000,0.270000
21090,-0.000000,-1.000000
22097,-0.000000,-0.168000
Note that the requested interval is only a minimum; most of the time,
the actual interval is slightly longer than the requested one.
The easiest way for an end-user to define logs is to put the log in a
separate XML file (usually under the user's home directory), then
refer to it using the --config option, like this:
fgfs --config=log-config.xml
The output log files are always relative to the current directory.
--
David Megginson, 2002-03-12

View file

@ -47,6 +47,7 @@ fgfs_SOURCES = \
fg_props.cxx fg_props.hxx \
fgfs.cxx fgfs.hxx \
globals.cxx globals.hxx \
logger.cxx logger.hxx \
model.cxx model.hxx \
options.cxx options.hxx \
splash.cxx splash.hxx \

View file

@ -116,6 +116,7 @@
#include "fg_props.hxx"
#include "options.hxx"
#include "globals.hxx"
#include "logger.hxx"
#include "viewmgr.hxx"
#if defined(FX) && defined(XMESA)
@ -779,6 +780,14 @@ bool fgInitSubsystems( void ) {
fgEVENT::FG_EVENT_READY, 30000 );
////////////////////////////////////////////////////////////////////
// Initialize the logger.
////////////////////////////////////////////////////////////////////
globals->set_logger(new FGLogger);
globals->get_logger()->init();
globals->get_logger()->bind();
////////////////////////////////////////////////////////////////////
// Initialize the local time subsystem.
////////////////////////////////////////////////////////////////////

110
src/Main/logger.cxx Normal file
View file

@ -0,0 +1,110 @@
// logger.cxx - log properties.
// Written by David Megginson, started 2002.
//
// This file is in the Public Domain, and comes with no warranty.
#include "logger.hxx"
#include <fstream>
SG_USING_STD(ofstream);
SG_USING_STD(endl);
#include <string>
SG_USING_STD(string);
#include <simgear/debug/logstream.hxx>
#include "fg_props.hxx"
////////////////////////////////////////////////////////////////////////
// Implementation of FGLogger
////////////////////////////////////////////////////////////////////////
FGLogger::FGLogger ()
{
}
FGLogger::~FGLogger ()
{
}
void
FGLogger::init ()
{
SGPropertyNode * logging = fgGetNode("/logging");
if (logging == 0)
return;
vector<SGPropertyNode *> children = logging->getChildren("log");
for (int i = 0; i < children.size(); i++) {
_logs.push_back(Log());
Log &log = _logs[_logs.size()-1];
SGPropertyNode * child = children[i];
string filename = child->getStringValue("filename", "fg_log.csv");
log.interval_ms = child->getLongValue("interval-ms", 0);
log.output = new ofstream(filename.c_str());
if (!log.output) {
SG_LOG(SG_INPUT, SG_ALERT, "Cannot write log to " << filename);
continue;
}
vector<SGPropertyNode *> entries = child->getChildren("entry");
(*log.output) << "Time";
for (int j = 0; j < entries.size(); j++) {
SGPropertyNode * entry = entries[j];
SGPropertyNode * node =
fgGetNode(entry->getStringValue("property"), true);
log.nodes.push_back(node);
(*log.output) << ','
<< entry->getStringValue("title", node->getPath());
}
(*log.output) << endl;
}
}
void
FGLogger::bind ()
{
}
void
FGLogger::unbind ()
{
}
void
FGLogger::update (int dt)
{
long elapsed_ms = globals->get_elapsed_time_ms();
for (int i = 0; i < _logs.size(); i++) {
if ((elapsed_ms - _logs[i].last_time_ms) >= _logs[i].interval_ms) {
_logs[i].last_time_ms = elapsed_ms;
(*_logs[i].output) << globals->get_elapsed_time_ms();
for (int j = 0; j < _logs[i].nodes.size(); j++) {
(*_logs[i].output) << ',' << _logs[i].nodes[j]->getStringValue();
}
(*_logs[i].output) << endl;
}
}
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGLogger::Log
////////////////////////////////////////////////////////////////////////
FGLogger::Log::Log ()
: output(0),
interval_ms(0),
last_time_ms(-99999999999999L)
{
}
FGLogger::Log::~Log ()
{
delete output;
}
// end of logger.cxx

65
src/Main/logger.hxx Normal file
View file

@ -0,0 +1,65 @@
// logger.hxx - log properties.
// Written by David Megginson, started 2002.
//
// This file is in the Public Domain, and comes with no warranty.
#ifndef __LOGGER_HXX
#define __LOGGER_HXX 1
#ifndef __cplusplus
# error This library requires C++
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/exception.hxx>
#include <simgear/misc/props.hxx>
#include <iostream>
SG_USING_STD(ostream);
#include <vector>
SG_USING_STD(vector);
#include "fgfs.hxx"
/**
* Log any property values to any number of CSV files.
*/
class FGLogger : public FGSubsystem
{
public:
FGLogger ();
virtual ~FGLogger ();
// Implementation of FGSubsystem
virtual void init ();
virtual void bind ();
virtual void unbind ();
virtual void update (int dt);
private:
/**
* A single instance of a log file (the logger can contain many).
*/
struct Log {
Log ();
virtual ~Log ();
vector<SGPropertyNode *> nodes;
ostream * output;
long interval_ms;
long last_time_ms;
};
vector<Log> _logs;
};
#endif // __LOGGER_HXX