]> git.mxchange.org Git - flightgear.git/commitdiff
Added new logging module.
authordavid <david>
Tue, 12 Mar 2002 16:29:00 +0000 (16:29 +0000)
committerdavid <david>
Tue, 12 Mar 2002 16:29:00 +0000 (16:29 +0000)
docs-mini/README.logging [new file with mode: 0644]
src/Main/Makefile.am
src/Main/fg_init.cxx
src/Main/logger.cxx [new file with mode: 0644]
src/Main/logger.hxx [new file with mode: 0644]

diff --git a/docs-mini/README.logging b/docs-mini/README.logging
new file mode 100644 (file)
index 0000000..f3be54d
--- /dev/null
@@ -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
index ad7df67edcfe62ebcd218abfc3b983c9082c4d78..6324e2245c915427f069f745bbc8ed1ea48fc668 100644 (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 \
index a78638f0b0fbe18cdf650e3d532e50973dca9b1c..3755480967700f2bd98bac580fe34ecb4df7251c 100644 (file)
 #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.
     ////////////////////////////////////////////////////////////////////
diff --git a/src/Main/logger.cxx b/src/Main/logger.cxx
new file mode 100644 (file)
index 0000000..9dfe739
--- /dev/null
@@ -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"
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// 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;
+    }
+  }
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// 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
diff --git a/src/Main/logger.hxx b/src/Main/logger.hxx
new file mode 100644 (file)
index 0000000..ef11ef7
--- /dev/null
@@ -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