6 releases

0.2.4 Dec 26, 2018
0.2.3 Dec 3, 2018
0.1.0 Nov 30, 2018

#20 in #subscribe

BSD-2-Clause

23KB
497 lines

PX4 bindings for Rust

This crate provides the framework to make dynamically loadable PX4 modules in Rust. Right now, it provides bindings for the two most important APIs: Logging and uORB. It also provides the entry point for your module, and handles panics on the main thread of the module.

See the example directory for an example module.

Compiling and running

To build a PX4 module in Rust, create a crate as you would for any other application binary, and then add the following to your Cargo.toml:

[lib]
crate-type = ["cdylib"]
path = "src/module.rs"

This will turn your program into a loadable module instead of a standalone application. The resulting file will be called lib<name>.so, which you can manually rename to <name>.px4mod if you want.

To run your module, use the dyn PX4 command. Give it the full path name, followed by any arguments to your module. Note that dyn will not reload your file if you run it again. If you want to run a changed version of your module, you'll either need to restart PX4, or move/rename the file.

Entry point

Mark your entry function with #[px4_module_main]. The boilerplate code needed to set up the environment and export the function under the right name is then inserted automatically.

Your main function should take a &[&str] as argument. It may return a i32 status code, either directly, or as the error type of a Result. A panic from your main thread is caught and results in a status code of −1.

Example

use px4::px4_module_main;

#[px4_module_main]
fn my_module(args: &[&str]) -> i32 {
  0
}

Logging

As soon as your main function is entered, logging is already set up using the standard log crate. You can use the standard logging macros such as info!, warn!, and error! to log messages, equivalent to PX4_INFO (etc.) in C and C++.

Use the info_raw! macro to send raw output, equivalent to the PX4_INFO_RAW macro in C and C++. Do not use standard output or standard error for this, as the standard streams of the PX4 process are often not the ones connected to the terminal the user is looking at.

Example

use log::{info, warn};
use px4::px4_module_main;

#[px4_module_main]
fn my_module(args: &[&str]) {
  info!("Hello World!");
  warn!("A warning!");
  panic!("Bye!");
}

uORB

Message definitions can be imported from .msg files, and then subscribed to or published. See the uorb module for documentation on how to use the uORB bindings.

Example

use log::info;
use px4::{px4_module_main, px4_message};
use px4::uorb::{Publish, Subscribe};

#[px4_message("../example/msg/debug_value.msg")]
pub struct debug_value;

#[px4_module_main]
fn my_module(args: &[&str]) {

  let mut publ = debug_value::advertise();
  publ.publish(&debug_value { timestamp: 0, value: 1.0, ind: 3 }).unwrap();

  let sub = debug_value::subscribe().unwrap();
  info!("Latest debug message: {:?}", sub.get().unwrap());
}

Dependencies

~2MB
~49K SLoC