-
Notifications
You must be signed in to change notification settings - Fork 4
/
fg-tape-data-source.c
162 lines (135 loc) · 4.25 KB
/
fg-tape-data-source.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
* SPDX-FileCopyrightText: 2021 Samuel Cuella <samuel.cuella@gmail.com>
*
* This file is part of SoFIS - an open source EFIS
*
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <stdio.h>
#include <stdlib.h>
#include "data-source.h"
#include "fg-tape-data-source.h"
/*private struct*/
typedef struct{
double latitude;
double longitude;
double altitude;
float roll;
float pitch;
float heading;
float slip_rad;
float airspeed; //kts
float vertical_speed; //vertical speed //feets per second
float rpm;
float fuel_flow;
float oil_temp;
float oil_press;
float cht;
float fuel_px;
float fuel_qty;
}TapeRecord;
static bool fg_tape_data_source_frame(FGTapeDataSource *self, uint32_t dt);
static FGTapeDataSource *fg_tape_data_source_dispose(FGTapeDataSource *self);
static DataSourceOps fg_tape_data_souce_ops = {
.frame = (DataSourceFrameFunc)fg_tape_data_source_frame,
.dispose = (DataSourceDisposeFunc)fg_tape_data_source_dispose
};
FGTapeDataSource *fg_tape_data_source_new(char *filename, int start_pos)
{
FGTapeDataSource *self;
self = calloc(1, sizeof(FGTapeDataSource));
if(self){
if(!fg_tape_data_souce_init(self, filename, start_pos)){
data_source_free(DATA_SOURCE(self));
return NULL;
}
}
return self;
}
FGTapeDataSource *fg_tape_data_souce_init(FGTapeDataSource *self, char *filename, int start_pos)
{
int found;
if(!data_source_init(DATA_SOURCE(self), &fg_tape_data_souce_ops))
return NULL;
self->tape = fg_tape_new_from_file(filename);
if(!self->tape)
return NULL;
// fg_tape_dump(tape);
//
found = fg_tape_get_signals(self->tape, self->signals,
"/position[0]/latitude-deg[0]",
"/position[0]/longitude-deg[0]",
"/position[0]/altitude-ft[0]",
"/orientation[0]/roll-deg[0]",
"/orientation[0]/pitch-deg[0]",
"/orientation[0]/heading-deg[0]",
"/orientation[0]/side-slip-rad[0]",
"/velocities[0]/airspeed-kt[0]",
"/velocities[0]/vertical-speed-fps[0]",
"/engines[0]/engine[0]/rpm[0]",
"/engines[0]/engine[0]/fuel-flow-gph[0]",
"/engines[0]/engine[0]/oil-temperature-degf[0]",
"/engines[0]/engine[0]/oil-pressure-psi[0]",
"/engines[0]/engine[0]/cht-degf[0]",
"/engines[0]/engine[0]/fuel-px-psi[0]",
"/consumables[0]/fuel[0]/tank[0]/level-gal_us[0]",
NULL
);
printf("TapeRecord: found %d out of %d signals\n",found, 16);
self->position = start_pos * 1000; /*Starting position in the tape*/
self->playing= true;
return self;
}
static FGTapeDataSource *fg_tape_data_source_dispose(FGTapeDataSource *self)
{
if(self->tape)
fg_tape_free(self->tape);
return self;
}
static bool fg_tape_data_source_frame(FGTapeDataSource *self, uint32_t dt)
{
TapeRecord record;
int rv;
if(dt != 0 && dt < (1000/25)) //One update per 1/25 second
return false;
if(!self->playing)
return false;
self->position += dt;
rv = fg_tape_get_data_at(self->tape, self->position / 1000.0, 16, self->signals, &record);
if(rv <= 0)
return false; /*Error or end of tape*/
data_source_set_location(
DATA_SOURCE(self), &(LocationData){
.super.latitude = record.latitude,
.super.longitude = record.longitude,
.altitude = record.altitude
}
);
data_source_set_dynamics(
DATA_SOURCE(self), &(DynamicsData){
.airspeed = record.airspeed,
.vertical_speed = record.vertical_speed,
.slip_rad = record.slip_rad
}
);
data_source_set_attitude(
DATA_SOURCE(self), &(AttitudeData){
.roll = record.roll,
.pitch = record.pitch,
.heading = record.heading
}
);
data_source_set_engine_data(
DATA_SOURCE(self), &(EngineData){
.rpm = record.rpm,
.fuel_flow = record.fuel_flow,
.oil_temp = record.oil_temp,
.oil_press = record.oil_press, /*TODO: All to _px*/
.cht = record.cht,
.fuel_px = record.fuel_px,
.fuel_qty = record.fuel_qty
}
);
DATA_SOURCE(self)->has_fix = true;
return true;
}