node-djiparsetxt
Version:
command-line application that reads a DJI '.txt' file and outputs a json.
457 lines • 20.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PARSER_TABLE = exports.bignum_convert_buffer = void 0;
var bignum = require("bignum");
var binary_parser_1 = require("binary-parser");
var Version_1 = require("../common/Version");
var InterpretationTable_1 = require("./InterpretationTable");
var radiants2degree = function (val) { return val * 57.2958; };
function bignum_convert_buffer(buffer) {
return bignum.fromBuffer(buffer, { endian: "little", size: 8 });
}
exports.bignum_convert_buffer = bignum_convert_buffer;
exports.PARSER_TABLE = {
header: {
instance: null,
factory: function () {
var parser = new binary_parser_1.Parser()
.uint32le("header_record_size_lo")
.uint32le("header_record_size_hi")
.uint32be("file_version");
var dummy = { parser: parser };
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
parsed.file_version = new Version_1.Version(parsed.file_version);
return parsed;
};
return dummy;
},
},
base_record: {
instance: null,
factory: function () {
return new binary_parser_1.Parser()
.uint8("type")
.uint8("length")
.buffer("data", {
length: "length",
})
.uint8("marker");
},
},
start_record: {
instance: null,
factory: function () {
return new binary_parser_1.Parser().uint8("type").uint8("length");
},
},
details: {
instance: null,
factory: function () {
var parser = new binary_parser_1.Parser()
.buffer("city_part", { length: 20, formatter: function (val) { return val.toString("ascii").replace(/\0/g, ""); } })
.buffer("street", { length: 20, formatter: function (val) { return val.toString("ascii").replace(/\0/g, ""); } })
.buffer("city", { length: 20, formatter: function (val) { return val.toString("ascii").replace(/\0/g, ""); } })
.buffer("area", { length: 20, formatter: function (val) { return val.toString("ascii").replace(/\0/g, ""); } })
.uint8("is_favorite")
.uint8("is_new")
.uint8("needs_upload")
.uint32le("record_line_count")
.skip(4)
.buffer("timestamp", { length: 8 })
.doublele("longitude", { formatter: radiants2degree })
.doublele("latitude", { formatter: radiants2degree })
.floatle("total_distance")
.uint32le("total_time", {
formatter: function (time) { return time / 1000; },
})
.floatle("max_height")
.floatle("max_hor_speed")
.floatle("max_vert_speed")
.uint32le("photo_count")
.uint32le("video_time")
// TODO: finish implementing parser for diff versions
.skip(137)
.string("aircraft_name", { length: 32, formatter: function (val) { return val.replace(/\0/g, ""); } })
.string("aircraft_sn", { length: 16, formatter: function (val) { return val.replace(/\0/g, ""); } })
.string("camera_sn", { length: 16, formatter: function (val) { return val.replace(/\0/g, ""); } })
.string("rc_sn", { length: 16, formatter: function (val) { return val.replace(/\0/g, ""); } })
.string("battery_sn", { length: 16, formatter: function (val) { return val.replace(/\0/g, ""); } })
.uint8("app_type")
.buffer("app_version", { length: 3 });
var dummy = { parser: parser };
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
parsed.app_type = InterpretationTable_1.DETAILS_APP_TYPE[parsed.app_type] || InterpretationTable_1.NO_MATCH;
var timestamp = bignum_convert_buffer(parsed.timestamp);
parsed.timestamp = new Date(parseInt(timestamp.toString())).toISOString();
parsed.app_version = new Version_1.Version(parsed.app_version);
return parsed;
};
return dummy;
},
},
osd_record: {
// todo: deal with file versions
instance: null,
factory: function () {
var dummy = {
parser: new binary_parser_1.Parser()
.doublele("longitude", { formatter: radiants2degree })
.doublele("latitude", { formatter: radiants2degree })
.int16le("height", {
formatter: function (val) { return val * 0.1; },
})
.int16le("x_speed", {
formatter: function (val) { return val * 0.1; },
})
.int16le("y_speed", {
formatter: function (val) { return val * 0.1; },
})
.int16le("z_speed", {
formatter: function (val) { return val * 0.1; },
})
.int16le("pitch", {
formatter: function (val) { return val * 0.1; },
})
.int16le("roll", {
formatter: function (val) { return val * 0.1; },
})
.int16le("yaw", {
formatter: function (val) { return val * 0.1; },
})
.bit1("rc_state")
.bit7("fly_state")
.uint8("fly_command")
.bit3("go_home_status")
.bit1("is_swave_work")
.bit1("is_motor_up")
.bit2("ground_or_sky")
.bit1("can_ioc_work")
.bit1("unknown")
.bit2("mode_channel")
.bit1("is_imu_preheated")
.bit1("unknown")
.bit2("voltage_warning")
.bit1("is_vision_used")
.bit2("battery_type")
.bit4("gps_level")
.bit1("wave_error")
.bit1("compass_error")
.bit1("is_accelerator_over_range")
.bit1("is_vibrating")
.bit1("is_barometer_dead_in_air")
.bit1("is_motor_blocked")
.bit1("is_not_enough_force")
.bit1("is_propeller_catapult")
.bit1("is_go_home_height_modified")
.bit1("is_out_of_limit")
.uint8("gps_num")
.uint8("flight_action")
.uint8("motor_start_failed_cause")
.bit3("unknown")
.bit1("waipoint_limit_mode")
.bit4("non_gps_cause")
.uint8("battery")
.uint8("swave_height")
.uint16le("fly_time")
.uint8("motor_revolution")
.skip(2)
.uint8("flyc_version")
.uint8("drone_type")
.uint8("imu_init_fail_reason"),
};
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
parsed.fly_state = InterpretationTable_1.OSD_RECORD_FLYCSTATE[parsed.fly_state] || InterpretationTable_1.NO_MATCH;
parsed.fly_command = InterpretationTable_1.OSD_RECORD_FLYCCOMMAND[parsed.fly_command] || InterpretationTable_1.NO_MATCH;
parsed.ground_or_sky = InterpretationTable_1.OSD_RECORD_GROUND_OR_SKY[parsed.ground_or_sky] || InterpretationTable_1.NO_MATCH;
parsed.go_home_status = InterpretationTable_1.OSD_RECORD_GO_HOME_STATUS[parsed.go_home_status] || InterpretationTable_1.NO_MATCH;
parsed.battery_type = InterpretationTable_1.OSD_RECORD_BATTERY_TYPE[parsed.battery_type] || InterpretationTable_1.NO_MATCH;
parsed.flight_action = InterpretationTable_1.OSD_RECORD_FLIGHT_ACTION[parsed.flight_action] || InterpretationTable_1.NO_MATCH;
parsed.motor_start_failed_cause = InterpretationTable_1.OSD_RECORD_MOTOR_START_FAILED_CAUSE[parsed.motor_start_failed_cause] || InterpretationTable_1.NO_MATCH;
parsed.non_gps_cause = InterpretationTable_1.OSD_RECORD_NON_GPS_CAUSE[parsed.non_gps_cause] || InterpretationTable_1.NO_MATCH;
parsed.imu_init_fail_reason = InterpretationTable_1.OSD_RECORD_IMU_INIT_FAIL_REASON[parsed.imu_init_fail_reason] || InterpretationTable_1.NO_MATCH;
parsed.drone_type = InterpretationTable_1.OSD_RECORD_DRONE_TYPE[parsed.drone_type] || InterpretationTable_1.NO_MATCH;
return parsed;
};
return dummy;
},
},
custom_record: {
instance: null,
factory: function () {
var dummy = {
parser: new binary_parser_1.Parser()
.skip(2)
.floatle("hspeed")
.floatle("distance")
.buffer("updateTime", { length: 8 }),
};
// override the parse method to also convert the buffer
// into a bignum obj
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
var updateTime = bignum_convert_buffer(parsed.updateTime);
parsed.updateTime = new Date(parseInt(updateTime.toString())).toISOString();
return parsed;
};
return dummy;
},
},
rc_record: {
instance: null,
factory: function () {
// todo: implement data transformations
return new binary_parser_1.Parser()
.int16le("aileron", {
formatter: function (val) { return (val - 1024) / 0.066; },
})
.int16le("elevator", {
formatter: function (val) { return (val - 1024) / 0.066; },
})
.int16le("throttle", {
formatter: function (val) { return (val - 1024) / 0.066; },
})
.int16le("rudder", {
formatter: function (val) { return (val - 1024) / 0.066; },
})
.int16le("gimbal", {
formatter: function (val) { return (val - 1024) / 0.066; },
})
.bit2("unknown")
.bit5("wheel_offset")
.bit1("unknown")
.bit2("unknown")
.bit2("mode")
.bit1("go_home")
.bit3("unknown")
.bit3("unknown")
.bit1("custom2")
.bit1("custom1")
.bit1("playback")
.bit1("shutter")
.bit1("record");
},
},
gimbal_record: {
instance: null,
factory: function () {
var dummy = {
parser: new binary_parser_1.Parser()
.int16le("pitch", { formatter: function (val) { return val / 10; } })
.int16le("roll", { formatter: function (val) { return val / 10; } })
.int16le("yaw", { formatter: function (val) { return val / 10; } })
.bit2("mode")
.bit6("unknown")
.int8("roll_adjust", { formatter: function (val) { return val / 10; } })
.int16le("yaw_angle", { formatter: function (val) { return val / 10; } })
.bit1("is_pitch_in_limit")
.bit1("is_roll_in_limit")
.bit1("is_yaw_in_limit")
.bit1("is_auto_calibration")
.bit1("auto_calibration_results")
.bit1("unknown")
.bit1("is_stuck")
.bit1("unknown")
.bit1("is_single_click")
.bit1("is_triple_click")
.bit1("is_double_click")
.bit1("unknown")
.bit4("version"),
};
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
parsed.mode = InterpretationTable_1.GIMBAL_MODE[parsed.mode] || InterpretationTable_1.NO_MATCH;
return parsed;
};
return dummy;
},
},
home_record: {
instance: null,
factory: function () {
var dummy = {
parser: new binary_parser_1.Parser()
.doublele("longitude", { formatter: radiants2degree })
.doublele("latitude", { formatter: radiants2degree })
.int16le("height", { formatter: function (val) { return val / 10; } })
.bit1("has_go_home")
.bit3("go_home_status")
.bit1("is_dyn_home_point_enabled")
.bit1("aircraft_head_direction")
.bit1("go_home_mode")
.bit1("is_home_record")
.bit3("ioc_mode")
.bit1("ioc_enabled")
.bit1("is_beginners_mode")
.bit1("is_compass_celeing")
.bit2("compass_cele_status")
.uint16le("go_home_height")
.int16le("course_lock_angle", {
formatter: function (val) { return val / 10; },
})
.uint8("data_recorder_status")
.uint8("data_recorder_remain_capacity")
.uint16le("data_recorder_remain_time")
.uint16le("data_recorder_file_index"),
};
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
parsed.ioc_mode = InterpretationTable_1.HOME_IOC_MODE[parsed.ioc_mode] || InterpretationTable_1.NO_MATCH;
return parsed;
};
return dummy;
},
},
deform_record: {
instance: null,
factory: function () {
var dummy = {
parser: new binary_parser_1.Parser()
.bit2("unknown")
.bit2("deform_mode")
.bit3("deform_status")
.bit1("is_deform_protected"),
};
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
parsed.deform_status = InterpretationTable_1.DEFORM_STATUS[parsed.deform_status] || InterpretationTable_1.NO_MATCH;
parsed.deform_mode = InterpretationTable_1.DEFORM_MODE[parsed.deform_mode] || InterpretationTable_1.NO_MATCH;
return parsed;
};
return dummy;
},
},
center_battery_record: {
instance: null,
factory: function () {
return new binary_parser_1.Parser()
.uint8("relative_capacity")
.uint16le("current_pv", { formatter: function (val) { return val / 1000; } })
.uint16le("current_capacity")
.uint16le("full_capacity")
.uint8("life")
.uint16le("loop_num")
.uint32le("error_type")
.uint16le("current", { formatter: function (val) { return val / 1000; } })
.uint16le("voltage_cel_1", { formatter: function (val) { return val / 1000; } })
.uint16le("voltage_cel_2", { formatter: function (val) { return val / 1000; } })
.uint16le("voltage_cel_3", { formatter: function (val) { return val / 1000; } })
.uint16le("voltage_cel_4", { formatter: function (val) { return val / 1000; } })
.uint16le("voltage_cel_5", { formatter: function (val) { return val / 1000; } })
.uint16le("voltage_cel_6", { formatter: function (val) { return val / 1000; } })
.uint16le("serial_no")
.uint16le("product_date", {
formatter: function (val) {
return {
year: ((val & 0xfe00) >> 9) + 1980,
month: (val & 0x01e0) >> 5,
day: val & 0x001f,
};
},
})
.uint16le("temperature", { formatter: function (val) { return val / 100; } })
.uint8("conn_status");
},
},
smart_battery_record: {
instance: null,
factory: function () {
var dummy = {
parser: new binary_parser_1.Parser()
.uint16le("useful_time")
.uint16le("go_home_time")
.uint16le("land_time")
.uint16le("go_home_battery")
.uint16le("landing_battery")
.uint32le("safe_fly_radius")
.floatle("volume_console")
.uint32le("status")
.uint8("go_home_status")
.uint8("go_home_countdown")
.uint16le("voltage", { formatter: function (val) { return val / 1000; } })
.uint8("battery")
.bit1("low_warning_go_home")
.bit7("low_warning")
.bit1("serious_low_warning_landing")
.bit7("serious_low_warning")
.uint8("voltage_percent"),
};
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
parsed.status = InterpretationTable_1.SMART_BATTERY_STATUS[parsed.status] || InterpretationTable_1.NO_MATCH;
parsed.go_home_status = InterpretationTable_1.SMART_BATTERY_GO_HOME_STATUS[parsed.go_home_status] || InterpretationTable_1.NO_MATCH;
return parsed;
};
return dummy;
},
},
app_tip_record: {
instance: null,
factory: function () {
return new binary_parser_1.Parser().string("tip", { zeroTerminated: true });
},
},
app_warn_record: {
instance: null,
factory: function () {
return new binary_parser_1.Parser().string("warn", { zeroTerminated: true });
},
},
recover_record: {
instance: null,
factory: function () {
// todo: implement versioning for this record
var dummy = {
parser: new binary_parser_1.Parser()
.uint8("drone_type")
.uint8("app_type")
.buffer("app_version", { length: 3 })
.string("aircraft_sn", { length: 10 })
.string("aircraft_name", { length: 24 })
.skip(22)
.string("camera_sn", { length: 10 })
.string("rc_sn", { length: 10 })
.string("battery_sn", { length: 10 }),
};
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
parsed.app_type = InterpretationTable_1.RECOVERY_APP_TYPE[parsed.app_type] || InterpretationTable_1.NO_MATCH;
parsed.drone_type = InterpretationTable_1.RECOVERY_DRONE_TYPE[parsed.drone_type] || InterpretationTable_1.NO_MATCH;
var appVer = parsed.app_version;
parsed.app_version = appVer[2] + "." + appVer[1] + "." + appVer[0];
return parsed;
};
return dummy;
},
},
app_gps_record: {
instance: null,
factory: function () {
return new binary_parser_1.Parser()
.doublele("latitude", { formatter: radiants2degree })
.doublele("longitude", { formatter: radiants2degree })
.floatle("accuracy");
},
},
firmware_record: {
instance: null,
factory: function () {
var dummy = {
parser: new binary_parser_1.Parser()
.skip(2)
.buffer("version", { length: 3 })
.skip(109)
};
dummy.parse = function (buf) {
var parsed = dummy.parser.parse(buf);
var version = parsed.version;
parsed.version = version[2] + "." + version[1] + "." + version[0];
return parsed;
};
return dummy;
},
},
};
//# sourceMappingURL=BinaryParserTable.js.map