class Spektrum::Log::Flight

Represents a single recorded flight. Contains information about the model flown, duration of the flight, and all data records contained within.

Attributes

headers[R]
records[R]

Public Class Methods

new(headers, records) click to toggle source

Creates a new flight.

@param headers [Array<Header>] headers read from the file @param records [Array<Record>] records read from the file

# File lib/spektrum/log/flight.rb, line 16
def initialize(headers, records)
  @headers = headers
  @records = records
end

Public Instance Methods

altimeter_records() click to toggle source
# File lib/spektrum/log/flight.rb, line 97
def altimeter_records
  select_records AltimeterRecord
end
altimeter_records?() click to toggle source
# File lib/spektrum/log/flight.rb, line 93
def altimeter_records?
  any_records? AltimeterRecord
end
basic_data_records() click to toggle source
# File lib/spektrum/log/flight.rb, line 105
def basic_data_records
  select_records BasicDataRecord
end
basic_data_records?() click to toggle source
# File lib/spektrum/log/flight.rb, line 101
def basic_data_records?
  any_records? BasicDataRecord
end
bind_type() click to toggle source

Gets the binding type the flight was flown with.

@return [String] binding type of the flight, `DSM2`, `DSMX`, etc.

# File lib/spektrum/log/flight.rb, line 39
def bind_type
  @bind_type ||= case @headers.first.raw_data[2].unpack('C')[0]
                 when 0x01..0x02
                   'DSM2'
                 when 0x03..0x04
                   'DSMX'
                 else
                   'Unknown'
                 end
end
duration() click to toggle source

Gets the duration of the flight, in seconds.

@return [Float] duration of the flight, in seconds

# File lib/spektrum/log/flight.rb, line 24
def duration
  @duration ||= timestamp_delta / 256.0
end
empty?() click to toggle source

Determines if this flight has any data. Models without telemetry transmitted, but with logging enabled will create empty flights.

@return [Boolean] true if the flight has no records, false otherwise

# File lib/spektrum/log/flight.rb, line 32
def empty?
  @records.empty?
end
flight_log_records() click to toggle source
# File lib/spektrum/log/flight.rb, line 113
def flight_log_records
  select_records FlightLogRecord
end
flight_log_records?() click to toggle source
# File lib/spektrum/log/flight.rb, line 109
def flight_log_records?
  any_records? FlightLogRecord
end
g_force_records() click to toggle source
# File lib/spektrum/log/flight.rb, line 121
def g_force_records
  select_records GForceRecord
end
g_force_records?() click to toggle source
# File lib/spektrum/log/flight.rb, line 117
def g_force_records?
  any_records? GForceRecord
end
gps1_records() click to toggle source
# File lib/spektrum/log/flight.rb, line 129
def gps1_records
  select_records GPSRecord1
end
gps1_records?() click to toggle source
# File lib/spektrum/log/flight.rb, line 125
def gps1_records?
  any_records? GPSRecord1
end
gps2_records() click to toggle source
# File lib/spektrum/log/flight.rb, line 137
def gps2_records
  select_records GPSRecord2
end
gps2_records?() click to toggle source
# File lib/spektrum/log/flight.rb, line 133
def gps2_records?
  any_records? GPSRecord2
end
model_name() click to toggle source

Gets the name of the model for this flight.

@return [String] model name

# File lib/spektrum/log/flight.rb, line 53
def model_name
  @model_name ||= @headers.first.raw_data[8..27].unpack('Z*')[0].strip
end
model_number() click to toggle source

Gets the model's index from the transmitter.

@return [Fixnum] model number

# File lib/spektrum/log/flight.rb, line 60
def model_number
  @model_number ||= (@headers.first.raw_data[0].unpack('C')[0] + 1)
end
model_type() click to toggle source

Gets the type of model flown.

@return [String] model type

# File lib/spektrum/log/flight.rb, line 67
def model_type
  @model_type ||= case @headers.first.raw_data[1].unpack('C')[0]
                  when 0x00
                    'Fixed Wing'
                  when 0x01
                    'Helicopter'
                  else
                    'Unknown'
                  end
end
speed_records() click to toggle source
# File lib/spektrum/log/flight.rb, line 145
def speed_records
  select_records SpeedRecord
end
speed_records?() click to toggle source
# File lib/spektrum/log/flight.rb, line 141
def speed_records?
  any_records? SpeedRecord
end
telemetry_unit() click to toggle source

Gets the type of telemetry unit that sent the data.

@return [String] telemetry unit

# File lib/spektrum/log/flight.rb, line 81
def telemetry_unit
  @telemetry_unit ||= derive_telemetry_unit
end
timestamp_delta() click to toggle source

Gets the difference between the last and the first timestamps. May be zero if no records exist.

@return [Number] difference between the last and first timestamp

# File lib/spektrum/log/flight.rb, line 89
def timestamp_delta
  @timestamp_delta ||= @records.empty? ? 0.0 : (@records.last.timestamp - @records.first.timestamp)
end
to_kml(file_options = {}, placemark_options = {}) click to toggle source

Converts the flight into a KML document containing a placemark.

@param file_options [Hash] hash containing options for file @param placemark_options [Hash] hash containing options for placemark @return [String] KML document for the flight @see to_kml_file file options @see to_kml_placemark placemark options

# File lib/spektrum/log/flight.rb, line 163
def to_kml(file_options = {}, placemark_options = {})
  raise RuntimeError, 'No coordinates available for KML generation' unless to_kml?
  to_kml_file(file_options, placemark_options).render
end
to_kml?() click to toggle source

Determines if KML methods can be called for this flight.

@return [Boolean] true if KML can be generated for this flight, false otherwise

# File lib/spektrum/log/flight.rb, line 152
def to_kml?
  gps1_records?
end
to_kml_file(file_options = {}, placemark_options = {}) click to toggle source

Converts the flight into a KMLFile containing a placemark.

@param file_options [Hash] hash containing options for file @option file_options [String] :name name option of KML::Document @option file_options [String] :description name option of KML::Document @option file_options [String] :style_id id option of KML::Style @param placemark_options [Hash] hash containing options for placemark @return [KMLFile] file for the flight @see to_kml_placemark placemark options

# File lib/spektrum/log/flight.rb, line 177
def to_kml_file(file_options = {}, placemark_options = {})
  raise RuntimeError, 'No coordinates available for KML generation' unless to_kml?
  options = apply_default_file_options(file_options)

  kml = KMLFile.new
  kml.objects << KML::Document.new(
    :name => options[:name],
    :description => options[:description],
    :styles => [
      KML::Style.new(
        :id => options[:style_id],
        :line_style => KML::LineStyle.new(:color => '7F00FFFF', :width => 4),
        :poly_style => KML::PolyStyle.new(:color => '7F00FF00')
      )
    ],
    :features => [ to_kml_placemark(placemark_options) ]
  )
  kml
end
to_kml_placemark(options = {}) click to toggle source

Converts the flight into a KML::Placemark containing GPS coordinates.

@param options [Hash] hash containing options for placemark @option options [String] :altitude_mode altitude_mode option of KML::LineString @option options [Boolean] :extrude extrude option of KML::LineString @option options [String] :name name option of KML::Placemark @option options [String] :style_url style_url option of KML::Placemark @option options [Boolean] :tessellate tessellate option of KML::LineString @return [KML::Placemark] placemark for the flight

# File lib/spektrum/log/flight.rb, line 206
def to_kml_placemark(options = {})
  raise RuntimeError, 'No coordinates available for KML generation' unless to_kml?
  options = apply_default_placemark_options(options)

  KML::Placemark.new(
    :name => options[:name],
    :style_url => options[:style_url],
    :geometry => KML::LineString.new(
      :altitude_mode => options[:altitude_mode],
      :extrude => options[:extrude],
      :tessellate => options[:tessellate],
      :coordinates => gps1_records.map(&:coordinate).map { |c| c.join(',') }.join(' ')
    )
  )
end

Private Instance Methods

any_records?(type) click to toggle source

Determines if there are any records in this flight of the given type.

@param [Class] type type of record to check for @return [Boolean] true if there are valid records, false otherwise

# File lib/spektrum/log/flight.rb, line 228
def any_records?(type)
  @records.any? { |rec| rec.is_a?(type) && rec.valid? }
end
apply_default_file_options(options) click to toggle source
# File lib/spektrum/log/flight.rb, line 232
def apply_default_file_options(options)
  options = { :name => 'Spektrum TLM GPS Path' }.merge(options)
  options = { :description => 'Flight paths for GPS telemetry data' }.merge(options)
  options = { :style_id => 'default-poly-style' }.merge(options)
  options
end
apply_default_placemark_options(options) click to toggle source
# File lib/spektrum/log/flight.rb, line 239
def apply_default_placemark_options(options)
  options = { :altitude_mode => 'absolute' }.merge(options)
  options = { :extrude => true }.merge(options)
  options = { :name => "#{model_name} (#{duration.round(1)}s)" }.merge(options)
  options = { :style_url => '#default-poly-style' }.merge(options)
  options = { :tessellate => true }.merge(options)
  options
end
derive_telemetry_unit() click to toggle source
# File lib/spektrum/log/flight.rb, line 248
def derive_telemetry_unit
  return "None" unless basic_data_records? && flight_log_records?
  key = [basic_data_records.first.type, flight_log_records.first.type]
  types = { [0x7E, 0x7F] => 'TM1000', [0xFE, 0xFF] => 'TM1100' }
  types.fetch(key, 'Unknown')
end
select_records(type) click to toggle source
# File lib/spektrum/log/flight.rb, line 255
def select_records(type)
  @records.select { |rec| rec.is_a?(type) && rec.valid? }
end