6 releases
0.2.4 | Dec 26, 2018 |
---|---|
0.2.3 | Dec 3, 2018 |
0.1.0 | Nov 30, 2018 |
#20 in #subscribe
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