npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mavlink-mappings-gen

v0.0.10

Published

Command-line utility to generate node-mavlink compatible message definitions from official XML definitions

Downloads

3,122

Readme

node-mavlink-gen

A powerful source code generator for node-mavlink-compatible classes. Uses the same code that powers the mavlink-mappings package used by node-mavlink.

Usage

It's really easy to get going!

$ npx node-mavlink-gen@latest minimal.xml

(You can get the minimal.xml file from here)

After you run the command the generator will read all the files you specified in the command line and generate source code for each module. If you have specified multiple files those will instead be written to their respective files.

Getting a colored output

There is a way to easily get the code syntax highlighted using the source-highlight utility:

$ npx node-mavlink-gen minimal.xml | source-highlight -s javascript -f esc256 | less -r

Generating custom definitions

Sometimes the vast number of messages just isn't enough and a new message could make all the difference.

You may consider writing the a class definition by hand, which is definitely possible but it may be a tedious and error-prone process. To ease the pain the entire generator is exposed for anyone to use:

Generating based on XML source

One thing that will allow you to basically generate all definitions in one go is to base them on a mavlink xml definition file. For a list of supported features look at the original XML definitions. At the moment minimal, common, development, ardupilotmega, asluav, icarus, storm32, ualberta and uavionix definitions are recognized by the generator.

async function generateAll(input: string, output: Writer, moduleName: string = '')

Generating based on data

This is a much more tedious process but it allows you to use something completely different to read the definitions from. There are a few interfaces that you'll have to get familiar with (like EnumDef, MessageDef and CommandTypeDef) but after you'll get them the generator should produce valid definitions.

This is how the generateAll() function does it:

const { enumDefs, messageDefs, commandTypeDefs } = await new XmlDataSource().parse(input)

const enums = processEnums(output, enumDefs)
const messages = processMessages(output, messageDefs)
const commands = processCommands(output, moduleName, commandTypeDefs)
processRegistries(output, messages, commands)

return { enums, messages, commands }

Debugging issues

Disclaimer:

The generator is basically available as-is. There is, and never will be, any support for anything else that doesn't work at the moment. If you want to have a problem fixed that impacts you - create a PR, I promise I'll look at it. If you have a feature request - create a PR that implements that feature.

With that out of the way let's see what can we do to understand the problems we might encounter.

Going single

If only part of the generation fails the entire generated content is lost. But there is hope! You can process each enum, message and command separately:

Generating a single enum

function generateEnum(output: Writer, enum: {
  name: string
  description: string[]
  values: {
    name: string
    value: string
    description: string[]
    hasLocation: boolean
    isDestination: boolean
    params: {
      name: string
      label: string
      description: string
      index: string
      units: string
      minValue: string
      maxValue: string
      increment: string
    }[]
  }[]
  source: {
    name: string
  }
})

Generating a single message

function generateMessage(output: Writer, message: {
  id: string
  name: string
  description: string[]
  magic?: number
  payloadLength?: number
  source: {
    name: string
  }
  deprecated?: {
    description: string
    since: string
    replacedBy: string
  }
  fields: {
    name: string
    description: string[]
    fieldSize: number
    extension: boolean
    arrayLength: number
    fieldType: string
    size: number
    units: string
    type: string
    source: {
      name: string
    }
  }[]
})

Generating a single command

function generateCommand(output: Writer, command: {
  description: string[],
  hasLocation: boolean,
  isDestination: boolean,
  field: string,
  name: string,
  params: {
    name: string,
    index: string,
    description: string[]
    label: string
    units: string
    minValue: string
    maxValue: string
    increment: string
  }[]
  source: {
    commonPrefix?: string
  }
})

Generating other elements separately

Pretty much every single part of the code can be generated in separation to everything else. Use that to understand better the inputs and the generated output. Functions like generateEnumValueParams(...) or generateMessageDefinitionFields() are there for you to use in those cases where you just don't get what's going on.

Generating magic number (aka crc_extra) value

Writing a definition of a message manually is an intense task at best. The one thing that is the least straightforward is the generation of a proper crc_extra (referred by node-mavlink as magic value) value:

function calculateCrcExtra(messageSourceName: string, fields: {
  extension: boolean
  itemType: string
  fieldSize: number
  arrayLength?: number
  source: { type: string, name: string }
}[])

Generating registry for magic numbers

A registry of magic numbers (aka crc_extra) can also be generated:

  fs.writeFileSync('magic-numbers.ts', generateMagicNumbers(magicNumbers))