#include extern const AP_HAL::HAL& hal; void fatal(const char *msg) { ::printf("%s",msg); ::printf("\n"); exit(1); } char *xstrdup(const char *string) { char *ret = strdup(string); if (ret == NULL) { perror("strdup"); fatal("strdup failed"); } return ret; } void MsgHandler::add_field_type(char type, size_t size) { size_for_type_table[(type > 'A' ? (type-'A') : (type-'a'))] = size; } uint8_t MsgHandler::size_for_type(char type) { return size_for_type_table[(uint8_t)(type > 'A' ? (type-'A') : (type-'a'))]; } void MsgHandler::init_field_types() { add_field_type('b', sizeof(int8_t)); add_field_type('c', sizeof(int16_t)); add_field_type('e', sizeof(int32_t)); add_field_type('f', sizeof(float)); add_field_type('h', sizeof(int16_t)); add_field_type('i', sizeof(int32_t)); add_field_type('n', sizeof(char[4])); add_field_type('B', sizeof(uint8_t)); add_field_type('C', sizeof(uint16_t)); add_field_type('E', sizeof(uint32_t)); add_field_type('H', sizeof(uint16_t)); add_field_type('I', sizeof(uint32_t)); add_field_type('L', sizeof(int32_t)); add_field_type('M', sizeof(uint8_t)); add_field_type('N', sizeof(char[16])); add_field_type('Z', sizeof(char[64])); } struct MsgHandler::format_field_info *MsgHandler::find_field_info(const char *label) { for(uint8_t i=0; i strlen(f.format)) { free(labels); printf("too few field times for labels %s (format=%s) (labels=%s)\n", f.name, f.format, f.labels); exit(1); } uint8_t field_type = f.format[label_offset]; uint8_t length = size_for_type(field_type); add_field(next_label, field_type, msg_offset, length); arg = NULL; msg_offset += length; label_offset++; } if (label_offset != strlen(f.format)) { free(labels); printf("too few labels for format (format=%s) (labels=%s)\n", f.format, f.labels); } free(labels); } bool MsgHandler::field_value(uint8_t *msg, const char *label, char *ret, uint8_t retlen) { struct format_field_info *info = find_field_info(label); if (info == NULL) { ::printf("No info for (%s)\n",label); exit(1); } uint8_t offset = info->offset; if (offset == 0) { return false; } memset(ret, '\0', retlen); memcpy(ret, &msg[offset], (retlen < info->length) ? retlen : info->length); return true; } bool MsgHandler::field_value(uint8_t *msg, const char *label, Vector3f &ret) { const char *axes = "XYZ"; uint8_t i; for(i=0; i remaining) { // null termination break; } if (pos != buffer) { *pos++ = ','; } memcpy(pos, field_info[k].label, label_length); pos += label_length; } } } MsgHandler::~MsgHandler() { for (uint8_t k=0; kstop_clock(timestamp_usec); } void MsgHandler::location_from_msg(uint8_t *msg, Location &loc, const char *label_lat, const char *label_long, const char *label_alt) { loc.lat = require_field_int32_t(msg, label_lat); loc.lng = require_field_int32_t(msg, label_long); loc.alt = require_field_int32_t(msg, label_alt); loc.options = 0; } void MsgHandler::ground_vel_from_msg(uint8_t *msg, Vector3f &vel, const char *label_speed, const char *label_course, const char *label_vz) { uint32_t ground_speed; int32_t ground_course; require_field(msg, label_speed, ground_speed); require_field(msg, label_course, ground_course); vel[0] = ground_speed*0.01f*cosf(radians(ground_course*0.01f)); vel[1] = ground_speed*0.01f*sinf(radians(ground_course*0.01f)); vel[2] = require_field_float(msg, label_vz); } void MsgHandler::attitude_from_msg(uint8_t *msg, Vector3f &att, const char *label_roll, const char *label_pitch, const char *label_yaw) { att[0] = require_field_int16_t(msg, label_roll) * 0.01f; att[1] = require_field_int16_t(msg, label_pitch) * 0.01f; att[2] = require_field_uint16_t(msg, label_yaw) * 0.01f; } void MsgHandler::require_field(uint8_t *msg, const char *label, char *buffer, uint8_t bufferlen) { if (! field_value(msg, label, buffer, bufferlen)) { char all_labels[256]; string_for_labels(all_labels, 256); ::printf("Field (%s) not found; options are (%s)\n", label, all_labels); exit(1); } } float MsgHandler::require_field_float(uint8_t *msg, const char *label) { float ret; require_field(msg, label, ret); return ret; } uint8_t MsgHandler::require_field_uint8_t(uint8_t *msg, const char *label) { uint8_t ret; require_field(msg, label, ret); return ret; } int32_t MsgHandler::require_field_int32_t(uint8_t *msg, const char *label) { int32_t ret; require_field(msg, label, ret); return ret; } uint16_t MsgHandler::require_field_uint16_t(uint8_t *msg, const char *label) { uint16_t ret; require_field(msg, label, ret); return ret; } int16_t MsgHandler::require_field_int16_t(uint8_t *msg, const char *label) { int16_t ret; require_field(msg, label, ret); return ret; } void MsgHandler::wait_timestamp_from_msg(uint8_t *msg) { uint32_t timestamp; require_field(msg, "TimeMS", timestamp); wait_timestamp(timestamp); }