Giter VIP home page Giter VIP logo

ev3dev-lang-rust's Introduction

Rust language bindings for ev3dev

Build Latest version

Notice

To use this project with the BrickPi platform the corresponding feature has to be enabled. The features ev3, brickpi and brickpi3 are mutual exclusive.

[dependencies]
ev3dev_lang_rust = { version="0.13.0" default-features=false, features=["brickpi"] }

Usage

extern crate ev3dev_lang_rust;

use ev3dev_lang_rust::Ev3Result;
use ev3dev_lang_rust::motors::{LargeMotor, MotorPort};
use ev3dev_lang_rust::sensors::ColorSensor;

fn main() -> Ev3Result<()> {

    // Get large motor on port outA.
    let large_motor = LargeMotor::get(MotorPort::OutA)?;

    // Set command "run-direct".
    large_motor.run_direct()?;

    // Run motor.
    large_motor.set_duty_cycle_sp(50)?;

    // Find color sensor. Always returns the first recognized one.
    let color_sensor = ColorSensor::find()?;

    // Switch to rgb mode.
    color_sensor.set_mode_rgb_raw()?;

    // Get current rgb color tuple.
    println!("Current rgb color: {:?}", color_sensor.get_rgb()?);

    Ok(())
}

There is a template repository that contains all the required configurations for cross-compilation and performance/binary-size optimizations for this "Hello World" example.

Supported features

  • Motors:
    • LargeMotor [lego-ev3-l-motor, lego-nxt-motor]
    • MediumMotor [lego-ev3-m-motor]
    • TachoMotor: Useful wrapper around LargeMotor and MediumMotor to make common functions easier to use
  • Sensors:
    • ColorSensor [lego-ev3-color]
    • CompassSensor [ht-nxt-compass]
    • GyroSensor [lego-ev3-gyro]
    • InfraredSensor [lego-ev3-ir]
    • IrSeekerSensor [ht-nxt-ir-seek-v2]
    • LightSensor [lego-nxt-light]
    • TouchSensor [lego-ev3-touch, lego-nxt-touch]
    • UltrasonicSensor [lego-ev3-us, lego-nxt-us]
  • Utility
    • Button: Provides access to the integrated buttons on the ev3 brick
    • Led: Provides access to the integrated led's on the ev3 brick
    • PowerSupply: Provides access to the power supply information
    • Screen: Provides access to the integrated display of the ev3 brick
    • sound: Provides access to the integrated speakers of the ev3 brick

Cross compilation for the ev3 robot - using musl toolchain

  1. Install the armv5te-musl toolchain

    rustup target add armv5te-unknown-linux-musleabi
  2. Create .cargo/config.toml with the following content

    [build]
    target = "armv5te-unknown-linux-musleabi"
    
    [target.armv5te-unknown-linux-musleabi]
    linker = "rust-lld"
  3. Build binary

    cargo build --release

    The --release flag is optional. However, it can speed up the execution time by a factor of 30. The target binary is now in target/armv5te-unknown-linux-musleabi/release/{application_name}.

Cross compilation for the ev3 robot - using docker

If you need to cross compile other dependencies (eg. openssl or paho-mqtt) it is much easier to use a complete cross compile toolchain. For this you can use the provided docker image pixix4/ev3dev-rust:latest.

  1. Setup a docker environment

  2. Create .cargo/config.toml with the following content

    [build]
    target = "armv5te-unknown-linux-gnueabi"
    
    [target.armv5te-unknown-linux-gnueabi]
    linker = "/usr/bin/arm-linux-gnueabi-gcc"
  3. Build binary

    docker run --rm -it -v $(pwd):/build -w /build pixix4/ev3dev-rust:latest \
       cargo build --release

    The --release flag is optional. However, it can speed up the execution time by a factor of 30. The target binary is now in target/armv5te-unknown-linux-gnueabi/release/{application_name}.

    If you do this you will notice that each build gets stuck at Updating crates.io index for a long time. To speed up this step you can use the vendoring mechanic of cargo.

    cargo vendor

    Execute the above command and add this additional config to .cargo/config.

    [source.crates-io]
    replace-with = "vendored-sources"
    
    [source.vendored-sources]
    directory = "vendor"

Optimize binary size

  • Enable "fat" link time optimizations and strip debug symbols: By default rust only performs lto for each crate individually. To enable global lto (which result in a much more aggressive dead code elimination) add the following additional config to your Cargo.toml. This also removes additional debug symbols from the binary. With this you can reduce the binary size of the "Hello World" example by more than 90%.

    [profile.release]
    lto = true
    strip = "debuginfo"

    The strip option requires rust 1.59.0. If you are using an older version you can do this manually with docker:

    # Run in interactive docker shell
    docker run -it --rm -v $(PWD):/build/ -w /build pixix4/ev3dev-rust
    /usr/bin/arm-linux-gnueabi-strip /build/target/armv5te-unknown-linux-gnueabi/release/{application_name}
    
    # Run directly (e.g. via Makefile)
    docker run --rm -v $(PWD):/build/ -w /build pixix4/ev3dev-rust \
         /usr/bin/arm-linux-gnueabi-strip /build/target/armv5te-unknown-linux-gnueabi/release/{application_name}

Editor support

If you have problems with code completion or inline documentation with rust analyzer it may help to enable to following settings:

{
  "rust-analyzer.cargo.loadOutDirsFromCheck": true,
  "rust-analyzer.procMacro.enable": true
}

(Example from VSCode settings.json)

Docs.rs documentation

To build the complete documentation (including the screen feature) use:

RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --features ev3,screen

ev3dev-lang-rust's People

Contributors

janf-04 avatar justsomerandomusername avatar massiminoiltrace avatar pixix4 avatar tomthecoder2 avatar voragain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ev3dev-lang-rust's Issues

cross-compilation instructions are confusing

I am trying to get HTTP and TCP connections working with the ev3dev rust langauge.
I have run into the error error: failed to run custom build command for openssl-sys v0.9.99when usingreqwest` crate.

i have tried to follow the cross-compilation instructions. but to me they are very confusing.
could someone help me understand.

way to reduce executable size

When I compile a hello world example, the file size for the executable is about 3MB, compared to a few KB in C. This is a lot for only printing hello world, but the main problem is, that transferring it over with bluetooth takes about 30s. I assume that is because large portions of the standard library are included, but not required.

Ev3Error does not implement Error

As of right now, Ev3Error does not implement std's Error trait. This makes error handling more difficult and prevents usage with existing error handling libraries (ie anyhow) as a wrapper type is need.

BrickPi

Thanks for this great library. The README mentions that this doesn't work with BrickPi. What's the reason it doesn't work and are you planning to add support?

screen errors

i copied the screen.rs example.
i get these errors

mismatched types
`Rgb<{integer}>` and `image::color::Rgb<u8>` have similar names, but are actually distinct types
perhaps two different versions of crate `image` are being used?

the trait bound `image::buffer_::ImageBuffer<image::color::Rgb<u8>, Vec<u8>>: GenericImageView` is not satisfied
the following other types implement trait `GenericImageView`:
  View<Buffer, P>
  ViewMut<Buffer, P>
  ImageBuffer<P, Container>
  DynamicImage
  image::image::SubImageInner<I>

Compilation not working (relocations in generic ELF)

When i run cargo build --release --target armv5te-unknown-linux-gnueabi it gives the following error error: linking with cc failed: exit code: 1.

I attached the full log: error.txt

I tried setting target.armv5te-unknown-linux-gnueabi.linker key in Cargo.toml but as you can see in the logs it isn't taken into account (warning: unused manifest key: target.armv5te-unknown-linux-gnueabi.linker).

How did you manage to compile something for the mindstorms ev3?

Button Event Listeners.

I noticed that the Ev3Button.proccess function says to call any button event listeners depending on if the button's state has changed.
what does this mean? because i can't find any part of ev3dev-lang-rust crate that lets you create event listeners.

I might have missed something.
but, this would be a great feature to have.

Rc<RefCell<File>> cannot be sent between threads safely

Hi,
I'm trying to use threading in my robot software. But this library uses Rc which cannot be used over thread borders. I've read that it is possible to replace Rc with Arc which is accepted from the Rust compiler to be used in concurring threads. I'm completely new to Rust and I'm using my Mindstorms Robots to learn it ;/ So I'm not able to send in a good PR.
So is this possible and a good Idea to replace this in this library?

At the moment I simply used a extra datastructure which uses Arc<Mutex<>> to exchange data between my threads. This datastructure is filled inside a thread from the corresponding sensor. So it is not really burning but annoying problem.

Example Error
Compiling run_on_console v0.1.0 (/build) error[E0277]:Rc<RefCell>cannot be sent between threads safely --> src/main.rs:56:5 | 56 | thread::spawn(move || { | ^^^^^^^^^^^^^Rc<RefCell>cannot be sent between threads safely | = help: within(String, Attribute), the trait Sendis not implemented forRc<RefCell>= note: required because it appears within the typeAttribute= note: required because it appears within the type(String, Attribute)= note: required because of the requirements on the impl ofSendforhashbrown::raw::RawTable<(String, Attribute)>= note: required because it appears within the typehashbrown::map::HashMap<String, Attribute, RandomState>= note: required because it appears within the typeHashMap<String, Attribute>= note: required because of the requirements on the impl ofSendforRefCell<HashMap<String, Attribute>>= note: required because it appears within the typeDriver= note: required because it appears within the typeUltrasonicSensor= note: required because it appears within the type[closure@src/main.rs:56:19: 62:6]``

Code which produces this Error:
fn main() { .... let ultrasonic = UltrasonicSensor::get(SensorPort::In4).unwrap(); ultrasonic.set_mode_us_dc_cm().unwrap(); let bar = Distance::new(); let mut bar1 = bar.clone(); thread::spawn(move || loop { bar1.update(ultrasonic.get_distance_centimeters().unwrap()); thread::sleep(Duration::from_millis(10)); }); ...

Make this lib more completion friendly

Hello,

I tried to use completion with this library and I had a rough time (here is a summary what I tried to do).

Did you manage to use completion with the library without macro expansion?

Thanks.

`cross` is unnecessary for building?

Hi! I just acquired an EV3 kit and wanted to write some Rust for it, and your SDK was exactly what I was looking for. I tried to build a simple Hello World program with your instructions, but I couldn't get cross working under WSL2 on Windows. I decided to try Cargo's built-in cross compilation support with musl and LLD, and to my surprise it worked without issue.

Here are the steps I took if you want to add them to the README.

  1. Install the compilation target for armv5te-unknown-linux-musleabi
rustup target add armv5te-unknown-linux-musleabi
  1. Create .cargo/config.toml under your project.
  2. Add the following lines to it:
[build]
target = "armv5te-unknown-linux-musleabi"

[target.armv5te-unknown-linux-musleabi]
linker = "rust-lld"
  1. cargo build --release

And you're done!

Cannot control EV3 motors

I have been unable to control motors on my EV3 running EV3Dev and this library. The program will continue through motor control instructions however it will not execute them.

I have tested across multiple EV3s and sets of motors using both custom and example code provided. While this will not work, EV3Dev Python works on all of these systems โ€“ so it is a problem specific to this library.

I would appreciate any help. I'm not sure what additional information to include.

Thank you in advance!

Example code does not work

I have compiled the example code and downloaded it on my EV3 and it doesn't move the motor. I have tried to use other methods of moving the motors but it is not working.

Any way to pair motors?

Apologies if this is a dumb question, but as someone new to Mindstorms and this library, I suspect there ought to be a way to pair motors together? Like, if I want to start driving, shouldn't there be a way to start both motors/wheels at the same time?

I see that the Python libraries have a MotorSet. Is that what I'm thinking it is and is there an equivalent for this library?

Can't get PID values from TachoMotor

I'm trying to work with de PID values from the tacho motor, but it seens like the atributes names are wrong:

Trying to run something like
let p = motor.get_speed_pid_kp()?; println!("{}", p);

I get the fallowing error (runing with RUST_BACKTRACE=1)

Starting: brickrun -r --directory="/home/robot/ev3_sensor_color/programas" "/home/robot/ev3_sensor_color/programas/ev3dev-color-sensor"
----------
thread 'main' panicked at 'Internal error in the attribute map', C:\Users\lucas.ms\.cargo\registry\src\github.com-1ecc6299db9ec823\ev3dev-lang-rust-0.12.0\src\driver.rs:130:14
stack backtrace:
   0: rust_begin_unwind
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/panicking.rs:143:14
   2: core::panicking::panic_display
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/panicking.rs:73:5
   3: core::panicking::panic_str
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/panicking.rs:56:5
   4: core::option::expect_failed
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/option.rs:1852:5
   5: ev3dev_lang_rust::driver::Driver::get_attribute
   6: ev3dev_color_sensor::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
----------
Exited with error code 101.

I think the get_speed_pid_kp() has the wrong attribute name, reading de ev3dev docs, it looks like the right name is 'speed_pid/Kp' instead of 'speed_pid_kp'

error: linking with `c:/msys64/mingw64/bin/arm-none-eabi-gcc.exe` failed: exit code: 1

I have been trying to compile this project with MSYS2 for a while now, but I keep getting this error:
= note: c:/msys64/mingw64/bin/../lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld.exe: warning: -z relro ignored
c:/msys64/mingw64/bin/../lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld.exe: cannot find -lgcc_s
c:/msys64/mingw64/bin/../lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld.exe: cannot find -lutil
c:/msys64/mingw64/bin/../lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld.exe: cannot find -lrt
c:/msys64/mingw64/bin/../lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld.exe: cannot find -lpthread
c:/msys64/mingw64/bin/../lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld.exe: cannot find -ldl
collect2.exe: error: ld returned 1 exit status

I know this means that the linker can't find the libraries libqcc, libutil, librt, libpthread, and libdl. I just haven't found any way to include these libraries. Any help would be greatly appreciated.

Add support for getting "raw" data

I could be wrong but currently I do not think it is possible to get the data described here through this library. Main use case would be to get a more accurate wheel position.

Unexpected beahavor when using ev3 display

So quite simply when you use draw something to the display in a program that doesn't exit the key press symbols (example ^CCA) will over write what ever you put on the display.

To reproduce you can add
loop {

}
to the bottom of the screen example and then press the arrow keys on the ev3.

I think this is caused by the tty not being in a "graphics mode" or with keyboard mode on as this is what the java bindings do in OwnedDisplay::switchToGraphicsMode and the java bindings dont have this problem.

error: linking with `cc` failed: exit code: 1

When compiling I get the error error: linking with 'cc' failed: exit code: 1.
I know it is because the .cargo/config file is not set up properly.
But there is only one .cargo/config file in my hole filesystem. Its path is "./home//.cargo/registry/src/github.com-1ecc6299db9ec823/ev3dev-lang-rust-0.9.5/.cargo/config". And I edited this one, so it shows:
[target.armv5te-unknown-linux-gnueabi] linker = "/usr/bin/arm-linux-gnueabi-gcc"
I really don`t know which file to edit or how to compile the program.
Thanks for helping ๐Ÿ‘

TachoMotor trait

The introduction of a TachoMotor trait would simplify code that has the possibility of dealing with either a large or a medium motor

Makefile errors on windows

I have been trying to use makefile for stripping as shown on the template repository. Everything builds fine but when I run make or make strip I get this error : 'rev' is not recognized as an internal or external command,
operable program or batch file.
docker run --rm -v :/build -w /build pixix4/ev3dev-rust:latest arm-linux-gnueabi-strip /build/target/armv5te-unknown-linux-musleabi/release/
arm-linux-gnueabi-strip: '/build/target/armv5te-unknown-linux-musleabi/release/': No such file
make: *** [Makefile:5: strip] Error 1
I can fix this issue by removing artifact and then replacing it with my project name but then i get this issue : 'rev' is not recognized as an internal or external command,
operable program or batch file.
docker run --rm -v :/build -w /build pixix4/ev3dev-rust:latest arm-linux-gnueabi-strip /build/target/armv5te-unknown-linux-musleabi/release/
arm-linux-gnueabi-strip: '/build/target/armv5te-unknown-linux-musleabi/release/': No such file
make: *** [Makefile:5: strip] Error 1

Any help would be greatly appreciated. Thanks in advance

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.