** Drone config in the Application category.
** App config encapsulates config an application may require.
**
** Create a new application by means of:
**
** syntax: fantom
** drone.config.app("My App Name")
**
** Future code may then access the same app by **not** passing an app name:
**
** syntax: fantom
** drone.config.app.combinedYawMode = true
**
const class DroneAppConfig {
private const Log _log := Drone#.pod.log
private const DroneConfig _config
** Creates a new 'DroneAppConfig' instance for the given Drone.
** Note this class holds no state.
new make(Drone drone) {
this._config = DroneConfig(drone)
}
// ---- Identity ----
** The current application ID.
**
** Corresponds to the 'CUSTOM:application_id' configuration key.
Int id {
get { _config._appId }
private set { }
}
** The current application's name.
**
** Corresponds to the 'CUSTOM:application_desc' configuration key.
Str name {
get { getConfig("CUSTOM:application_desc") }
private set { }
}
** Deletes this application data from the drone.
Void deleteMe() {
id := id
if (id == DroneConfig.defId) {
_log.warn("Will not delete default data!") // don't know what might happen if we try this!?
return
}
_config._delApp("-${id.toHex(8)}")
}
** Deletes **ALL** application data from the drone.
** Use with caution.
Void deleteAll() {
_log.warn("Deleting ALL application data!")
_config._delApp("-all")
}
// ---- Other Cmds ----
** Allows the drone to send other packets of NavData.
**
** Use the flag values of the `NavOption` enum to add / or flags values together. Example:
**
** syntax: fantom
** drone.config.session.app.navDataOptions = NavOption.demo.flag + NavOption.visionDetect.flag
**
** To receive all option data:
**
** syntax: fantom
** drone.config.session.app.navDataOptions = 0x0FFF_FFFF
**
** Corresponds to the 'GENERAL:navdata_options' configuration key.
Int navDataOptions {
get { getConfig("GENERAL:navdata_options").toInt }
set { setConfig("GENERAL:navdata_options", it.toStr) }
}
** If 'true' then roll commands ('moveLeft()' & 'moveRight()') generate roll + yaw based turns
** so the drone banks like an aeroplane / leans into the corners.
** This is an easier control mode for racing games.
**
** Note, unlike other SDKs, to enable 'combinedYawMode' you need only set this config to 'true'.
** The move commands are automatically updated for you.
**
** Corresponds to the 'CONTROL:control_level' configuration key.
Bool combinedYawMode {
get { getConfig("CONTROL:control_level").toInt.and(0x02) > 0 }
set { setConfig("CONTROL:control_level", (it ? 0x02 : 0).or(0x01).toStr) }
}
** Sets the bitrate of the video transmission (kilobits per second) when 'videoBitrateControlMode'
** is set to 'MANUAL'. Typical values range from 500 to 4000 kbps.
**
** Can only be set with a non-default application ID. Throws an Err if this is not the case.
**
** Corresponds to the 'VIDEO:bitrate' configuration key.
Int videoBitrate {
get { getConfig("VIDEO:bitrate").toInt }
set {
_checkId("change video bitrate")
setConfig("VIDEO:bitrate", it.toStr)
}
}
** Enables the automatic bitrate control of the video stream. Enabling this configuration reduces
** bandwidth used by the video stream under bad Wi-Fi conditions, reducing the commands latency.
**
** 0 = DISABLED - Bitrate set to videoMaxBitrate session config
** 1 = DYNAMIC - Video bitrate varies between [250 - videoMaxBitrate] kbps
** 2 = MANUAL - Video stream bitrate is fixed to videoBitrate
**
** Can only be set with a non-default application ID. Throws an Err if this is not the case.
**
** Corresponds to the 'VIDEO:bitrate_control_mode' configuration key.
Int videoBitrateControlMode {
get { getConfig("VIDEO:bitrate_control_mode", false)?.toInt ?: 0}
set {
_checkId("change video bitrate control")
setConfig("VIDEO:bitrate_control_mode", it.toStr)
}
}
** The bitrate (kilobits per second) of the recording stream, both for USB and WiFi record.
**
** Corresponds to the 'VIDEO:bitrate_storage' configuration key.
Int videoBitrateStorage {
get { getConfig("VIDEO:bitrate_storage").toInt }
private set { }
}
** Dumps all fields to debug string.
Str dump(Bool dumpToStdOut := true) {
fields := typeof.fields.findAll { it.isPublic && it.parent == this.typeof }
names := (Str[]) fields.map { it.name.toDisplayName }
width := names.max |p1, p2| { p1.size <=> p2.size }.size
values := fields.map |field, i| { names[i].padr(width, '.') + "..." + field.get(this).toStr }
dump := values.join("\n")
dump = "APP CONFIG\n==========\n" + dump + "\n\n"
if (dumpToStdOut)
echo(dump)
return dump
}
@NoDoc
override Str toStr() { dump }
internal Void _checkId(Str what) {
if (id == DroneConfig.defId)
throw Err("Can not ${what} with default application ID: $id")
}
private Str? getConfig(Str key, Bool checked := true) {
_config.drone.configMap[key] ?: (checked ? throw UnknownKeyErr(key) : null)
}
private Void setConfig(Str key, Obj val) {
_config.sendConfig(key, val)
}
}