/*
* TimedProcessing.c
*
* This example plugin demonstrates how to use the timed processing callbacks
* to continuously record sim data to disk.
*
* This technique can be used to record data to disk or to the network. Unlike
* UDP data output, we can increase our frequency to capture data every single
* sim frame. (This example records once per second.)
*
* Use the timed processing APIs to do any periodic or asynchronous action in
* your plugin.
*
*/
#if APL
#if defined(__MACH__)
#include <Carbon/Carbon.h>
#endif
#endif
#include <stdio.h>
#include <string.h>
#include "XPLMProcessing.h"
#include "XPLMDataAccess.h"
#include "XPLMUtilities.h"
/* File to write data to. */
static FILE * gOutputFile;
/* Data refs we will record. */
static XPLMDataRef gPlaneLat;
static XPLMDataRef gPlaneLon;
static XPLMDataRef gPlaneEl;
#if APL && __MACH__
static int ConvertPath(const char * inPath, char * outPath, int outPathMaxLen);
#endif
static float MyFlightLoopCallback(
float inElapsedSinceLastCall,
float inElapsedTimeSinceLastFlightLoop,
int inCounter,
void * inRefcon);
PLUGIN_API int XPluginStart(
char * outName,
char * outSig,
char * outDesc)
{
char outputPath[255];
#if APL && __MACH__
char outputPath2[255];
int Result = 0;
#endif
strcpy(outName, "TimedProcessing");
strcpy(outSig, "xplanesdk.examples.timedprocessing");
strcpy(outDesc, "A plugin that records sim data.");
/* Open a file to write to. We locate the X-System directory
* and then concatenate our file name. This makes us save in
* the X-System directory. Open the file. */
XPLMGetSystemPath(outputPath);
strcat(outputPath, "TimedProcessing.txt");
#if APL && __MACH__
Result = ConvertPath(outputPath, outputPath2, sizeof(outputPath));
if (Result == 0)
strcpy(outputPath, outputPath2);
else
XPLMDebugString("TimedProccessing - Unable to convert path\n");
#endif
gOutputFile = fopen(outputPath, "w");
/* Find the data refs we want to record. */
gPlaneLat = XPLMFindDataRef("sim/flightmodel/position/latitude");
gPlaneLon = XPLMFindDataRef("sim/flightmodel/position/longitude");
gPlaneEl = XPLMFindDataRef("sim/flightmodel/position/elevation");
/* Register our callback for once a second. Positive intervals
* are in seconds, negative are the negative of sim frames. Zero
* registers but does not schedule a callback for time. */
XPLMRegisterFlightLoopCallback(
MyFlightLoopCallback, /* Callback */
1.0, /* Interval */
NULL); /* refcon not used. */
return 1;
}
PLUGIN_API void XPluginStop(void)
{
/* Unregister the callback */
XPLMUnregisterFlightLoopCallback(MyFlightLoopCallback, NULL);
/* Close the file */
fclose(gOutputFile);
}
PLUGIN_API void XPluginDisable(void)
{
/* Flush the file when we are disabled. This is convenient; you
* can disable the plugin and then look at the output on disk. */
fflush(gOutputFile);
}
PLUGIN_API int XPluginEnable(void)
{
return 1;
}
PLUGIN_API void XPluginReceiveMessage(
XPLMPluginID inFromWho,
int inMessage,
void * inParam)
{
}
float MyFlightLoopCallback(
float inElapsedSinceLastCall,
float inElapsedTimeSinceLastFlightLoop,
int inCounter,
void * inRefcon)
{
/* The actual callback. First we read the sim's time and the data. */
float elapsed = XPLMGetElapsedTime();
float lat = XPLMGetDataf(gPlaneLat);
float lon = XPLMGetDataf(gPlaneLon);
float el = XPLMGetDataf(gPlaneEl);
/* Write the data to a file. */
fprintf(gOutputFile, "Time=%f, lat=%f,lon=%f,el=%f.\n",elapsed, lat, lon, el);
/* Return 1.0 to indicate that we want to be called again in 1 second. */
return 1.0;
}
#if APL && __MACH__
#include <Carbon/Carbon.h>
int ConvertPath(const char * inPath, char * outPath, int outPathMaxLen)
{
CFStringRef inStr = CFStringCreateWithCString(kCFAllocatorDefault, inPath ,kCFStringEncodingMacRoman);
if (inStr == NULL)
return -1;
CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, inStr, kCFURLHFSPathStyle,0);
CFStringRef outStr = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
if (!CFStringGetCString(outStr, outPath, outPathMaxLen, kCFURLPOSIXPathStyle))
return -1;
CFRelease(outStr);
CFRelease(url);
CFRelease(inStr);
return 0;
}
#endif
Hello!
This code works great. I am a student and I am making a project for myself to save data of X-plane in .txt file. Now I am editing this code but I couldn’t figure out where to set intervals how often Plugin saves data to .txt file. I know that sim data is recorded in 1 sec and it’s written in 241 lines every time in approximately 5 sec, but I want to record just one line of data and write it to .txt file every 0.1 sec. Can anyone help me with that? Basically what I need is code that saves data to .txt file every 0.1 sec, is this even possible?
Best regards
Rok
Hi Rok Dolenc,
1) About gOutputFile = fopen(outputPath, “w”);
From http://www.cplusplus.com/reference/cstdio/fopen/
you can read: “w” write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.
-> I don’t even understand why it doesn’t overwrite, but append. Strange and not logical ..
2) Here: https://developer.x-plane.com/sdk/XPLMRegisterFlightLoopCallback/
you can read: inInterval defines when you will be called:
– Positive number to specify seconds from registration time to the next callback
– Negative number to indicate when you will be called (e.g. pass -1 to be called at the next cylcle)
– 0 to not be called; your callback will be inactive.
-> But for me the file (TimedProcessing.txt) is written about every 60/70 seconds instead of every second.
Have you found a solution?
Contact me on: foxjojofox@gmail.com
Regards.
Hi Rok Dolenc, can you contact me to: foxjojofox@gmail.com ?
Regards.