Giter Site home page Giter Site logo

ev3dev's People

Contributors

dlech avatar hlubek avatar kortschak avatar undeaddemidov 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ev3dev's Issues

Code does not compile on platforms other than Linux

I'm developing code on OS X and the package does not compile locally because of the unix.Poll dependency. This is generally not an issue because of cross compilation, but code completion and other local tools do not work correctly.

There should be a build tag for the code that uses the unix dependency in a separate file, so it has a bogus implementation for other platforms.

I got that working and will push a PR soon.

proposal: add package to allow controlling BuWizz batteries

The BuWizz battery is a promising device that allows control of LEGO motors and other power functions by Bluetooth. It can be controlled (currently) via an app available for ios and android.

The developers claim that the communication protocol will be opened. However, there is little indication that this is happening. When it does, add a package that allows a BT-enabled EV3 device to control paired BuWizz bricks.

How a project is meant to be compiled to run on the brick?

I know I can set flags to configure target architecture for a compiled app.
I want to develop on my main Mac machine, then compile and transfer compiled files into the brick.

What options should I use to compile for EV3 on a Mac?

ev3dev: unify fbdev handling functions

The code for fbdev handling in ev3 and evb are essentially identical. This code should be moved to ev3dev (back again) in a way that only keeps the device-specific code in the ev3 and evb packages.

ev3dev: not all sensors will return commands attribute

I'm writing something with the mindsensors 9dof and sensor initialisation fails with failed to find sensor: ev3dev: failed to read sensor0 commands attribute /sys/class/lego-sensor/sensor0/commands: read /sys/class/lego-sensor/sensor0/commands: operation not supported at ev3dev.go:533 github.com/ev3go/ev3dev.attributeOf because reading from commands returns ENOTSUP (I had had this in tests previously - probably because I noticed this).

To avoid this, allow ENOTSUP failure to be ignored on initialisation.

all: purge opaque errors from suite

The ev3go/ev3dev package was easy to start with errors.New and fmt.Errorf, but it makes mechanical error handling difficult. So add three (?) error interface types and relevant implementations:

Interfaces

type ValidValuer interface {
    ValidValues() []string
}
type ValidRanger interface {
    ValidRange() (min, max int)
}
type ValidDurationRanger interface {
    ValidDurationRange() (min, max time.Duration)
}

Implementation example

type NegativeDuration time.Duration

func (d NegativeDuration) Error() string {
    if d >= 0 {
        panic(fmt.Sprintf("ev3dev: invalid negative duration: %v", d))
    }
    return fmt.Sprintf("ev3dev: invalid duration: %v (must be positive)", time.Duration(d))
}

func (d NegativeDuration) ValidDurationRange() (min, max time.Duration) {
    if d >= 0 {
        panic(fmt.Sprintf("ev3dev: invalid negative duration: %v", d))
    }
    return 0, MaxInt64
}

ev3dev: data race in sensor tests

New to go1.8.1; go1.7.4 passes.

WARNING: DATA RACE
Write at 0x00c4200de1e1 by goroutine 32:
  github.com/ev3go/ev3dev_test.(*sensorDirect).Truncate()
      /home/daniel/src/github.com/ev3go/ev3dev/sensor_test.go:333 +0x1a6
  github.com/ev3go/sisyphus.(*RW).Setattr()
      /home/daniel/src/github.com/ev3go/sisyphus/rw_node.go:194 +0x13a
  bazil.org/fuse/fs.(*Server).handleRequest()
      /home/daniel/src/bazil.org/fuse/fs/serve.go:945 +0x3e2d
  bazil.org/fuse/fs.(*Server).serve()
      /home/daniel/src/bazil.org/fuse/fs/serve.go:878 +0x5e5
  bazil.org/fuse/fs.(*Server).Serve.func1()
      /home/daniel/src/bazil.org/fuse/fs/serve.go:425 +0x7f

Previous read at 0x00c4200de1e1 by goroutine 16:
  reflect.typedmemmove()
      /home/daniel/go/src/runtime/mbarrier.go:253 +0x0
  reflect.packEface()
      /home/daniel/go/src/reflect/value.go:112 +0x11c
  reflect.valueInterface()
      /home/daniel/go/src/reflect/value.go:955 +0x18c
  reflect.deepValueEqual()
      /home/daniel/go/src/reflect/deepequal.go:132 +0x3a6
  reflect.deepValueEqual()
      /home/daniel/go/src/reflect/deepequal.go:84 +0xaf0
  reflect.DeepEqual()
      /home/daniel/go/src/reflect/deepequal.go:190 +0x2bb
  github.com/ev3go/ev3dev_test.TestSensor.func7()
      /home/daniel/src/github.com/ev3go/ev3dev/sensor_test.go:875 +0x57d
  testing.tRunner()
      /home/daniel/go/src/testing/testing.go:657 +0x107

Goroutine 32 (running) created at:
  bazil.org/fuse/fs.(*Server).Serve()
      /home/daniel/src/bazil.org/fuse/fs/serve.go:426 +0x695
  github.com/ev3go/sisyphus.Serve.func1()
      /home/daniel/src/github.com/ev3go/sisyphus/sisyphus.go:47 +0x68

Goroutine 16 (running) created at:
  testing.(*T).Run()
      /home/daniel/go/src/testing/testing.go:697 +0x543
  github.com/ev3go/ev3dev_test.TestSensor()
      /home/daniel/src/github.com/ev3go/ev3dev/sensor_test.go:902 +0x12da
  testing.tRunner()
      /home/daniel/go/src/testing/testing.go:657 +0x107

High level API

Hi there

What do you think about a higher level api?
I felt like leaning go and stared to port my python linefollower to go.
I got to this: https://github.com/vogtp/ev3bot
Not yet a linefollower and probably horrible go code...
... but it might be a starting point for a high level api.

have fun
Patrick

Sound support

It would be nice to have sound support. Tone/beep is easy to implement using the Linux input subsystem (evdev). Since we don't want to use cgo, we would have to call an external process (e.g. aplay for PCM playback.

ev3dev-stretch

How do you plan on handling breaking driver changes in ev3dev-stretch? For example, port names and LED names have changed.

ev3dev: cache invariant values for sensors

Similar to #53, sensors have sysfs attributes that never change and could be cached.

address, commands, driver_name, fw_version, modes.

Additionally, some values only change when the mode changes. It is fairly safe to make the assumption that no one will change the mode outside of your program (but technically, not a 100% guarantee). These values could be cached when the mode is set.

bin_data_format, decimals, mode, num_values, units

Difficult motol control

I am new to both EV3 and Go. I just wanted to play a bit with motor control (large motor on outB). While it was easily in Python...

#!/usr/bin/env python3
from time import sleep
from ev3dev.ev3 import *

motor_left = LargeMotor('outB')
motor_left.run_direct(duty_cycle_sp=100)
sleep(0.5)
motor_left.run_direct(duty_cycle_sp=0)

The same went shockingly difficult in Go...

package main

import (
	"time"
	"github.com/ev3go/ev3dev"
)

func main() {
	const driver = "lego-ev3-l-motor"
	m, err := ev3dev.TachoMotorFor("outB", driver)
	if err != nil {
		panic(err)
	}
	err = m.Command("reset").Err()
	if err != nil {
		panic(err)
	}
	err = m.SetPolarity("normal").Err()
	if err != nil {
		panic(err)
	}
	maxSpeed, err := m.MaxSpeed()
	if err != nil {
		panic(err)
	}
	err = m.SetSpeedSetpoint(maxSpeed).Err()
	if err != nil {
		panic(err)
	}
	err = m.Command("run-forever").Err()
	if err != nil {
		panic(err)
	}
	time.Sleep(500 * time.Millisecond)
	err = m.Command("stop").Err()
	if err != nil {
		panic(err)
	}
}

I can write a Python run_direct-like function in Go, of course. But I wonder whether there is such a function, that I could use out-of-the-box.

ev3dev: consider allowing fluent style

If each device type holds an err error field and has an Err() error method, then setters can return the device pointer. Attribute reader and writer methods would return early if the err field if non-nil, so a call to Err should reset the err field to nil.

ev3dev: add tests

This depends on providing some basic read/write VFS functionality for mocking the sysfs (golang.org/x/tools/godoc/vfs would work but is read only).

ev3dev: add IsConnected function

This adds functionality that is specified in the ev3dev.org API for the base device class.

func IsConnected(d Device) (bool, error) provides the capacity to query whether the Device is still connected (the API specification actually caches this AFAICS, so this is a difference, but I think determining the value at call time is more sensible).

Am I doing this right?

I'm inexperienced in go, so I thought I would share my first ev3go program and see what you think.

package main

import (
	"log"

	"strconv"

	"image/color"

	"os/exec"

	"github.com/ev3go/ev3"
	"github.com/ev3go/ev3dev"
)

const (
	top    = 30
	bottom = 100
	left   = 70
	right  = 110
)

func main() {
	// configure the LEGO EV3 IR sensor on input port 1 in IR-SEEK mode
	irSensor, err := ev3dev.SensorFor("in1", "lego-ev3-ir")
	if err != nil {
		log.Fatal(err)
	}
	irSensor.SetMode("IR-SEEK")

	// configure LEGO EV3 Large motor in output port A
	motor, err := ev3dev.TachoMotorFor("outA", "lego-ev3-l-motor")
	if err != nil {
		log.Fatal(err)
	}

	// init poller so we can monitor buttons
	buttonPoller := ev3dev.ButtonPoller{}

	// init the LCD so we can draw stuff
	ev3.LCD.Init(true)
	defer ev3.LCD.Close()

	motor.Command("run-direct")
	beaconPresent := false

	for {
		// read the channel 1 heading value from the IR sensor
		v0, _ := irSensor.Value(0)
		heading, _ := strconv.Atoi(v0)

		// motor rotation is in the same direction as heading, so this will
		// cause the motor to rotate towards the beacon
		motor.SetDutyCycleSetpoint(heading)

		v1, _ := irSensor.Value(1)
		distance, _ := strconv.Atoi(v1)

		// sound feedback when beacon is in or out of range
		if beaconPresent && distance == -128 {
			beaconPresent = false
			exec.Command("beep", "-f", "400", "-n", "-f", "200").Start()
		} else if !beaconPresent && distance != -128 {
			beaconPresent = true
			exec.Command("beep", "-f", "200", "-n", "-f", "400").Start()
		}

		// Draw a bar graph to indicate how far away the beacon is. The closer
		// the beacon, the taller the graph.
		for x := left; x < right; x++ {
			for y := top; y < bottom; y++ {
				if y > top+distance {
					ev3.LCD.Set(x, y, color.Black)
				} else {
					ev3.LCD.Set(x, y, color.White)
				}
			}
		}

		// check for button presses
		b, err := buttonPoller.Poll()
		if err != nil {
			log.Fatal(err)
		}
		if (b & ev3dev.Back) == ev3dev.Back {
			// exit the program
			break
		}
		if (b & ev3dev.Middle) == ev3dev.Middle {
			speak := exec.Command("espeak", "--stdout", "-a", "200", "-s", "100",
				"Don't press that button")
			play := exec.Command("aplay", "-q")
			play.Stdin, _ = speak.StdoutPipe()
			speak.Start()
			play.Start()
		}
	}
}

ev3dev: test Wait

This was going to go into the testing PR, but that has been going on too long.

ev3dev: prevent more than one device handle per physical port

While we can make things race free from the perspective of the code, there are still possibilities for physical racing. We should not allow this, so make it impossible to hold more than one Device to any single physical port, with flexibility for the LegoPort type which should not prevent other device types from attaching to the port they are controlling.

ev3dev: consider factoring out evdev code into new package and expanding

There is ad hoc evdev implementation in ev3dev. This may want to be expanded in the future. A third party evdev package does already exist, but it is cgo dependent which makes its use in this context difficult; compiling programs for controlling and ev3 will either be done using cross compilation which precludes cgo, or will be done on the ev3 itself which will be slow. So if an evdev package is implemented it needs to be pure Go.

How to install?

I have encountered an install issue that has raised this error

go get -v github.com/ev3go/ev3dev
github.com/ev3go/ev3dev
# github.com/ev3go/ev3dev
C:\Users\<USERNAME>\go\pkg\mod\github.com\ev3go\[email protected]\evdev.go:39:32: not enough arguments in call to syscall.Syscall
C:\Users\<USERNAME>\go\pkg\mod\github.com\ev3go\[email protected]\evdev.go:39:33: undefined: syscall.SYS_IOCTL
C:\Users\<USERNAME>\go\pkg\mod\github.com\ev3go\[email protected]\lcd.go:79:17: undefined: syscall.Mmap
C:\Users\<USERNAME>\go\pkg\mod\github.com\ev3go\[email protected]\lcd.go:79:62: undefined: syscall.PROT_READ
C:\Users\<USERNAME>\go\pkg\mod\github.com\ev3go\[email protected]\lcd.go:79:80: undefined: syscall.PROT_WRITE
C:\Users\<USERNAME>\go\pkg\mod\github.com\ev3go\[email protected]\lcd.go:79:100: undefined: syscall.MAP_SHARED
C:\Users\<USERNAME>\go\pkg\mod\github.com\ev3go\[email protected]\lcd.go:103:9: undefined: syscall.Munmap

[question] Go seven times slower in retrieving sensor values than Python?

I recently tried Go on the EV3 because I hoped it would have better performance compared to Python.

In a while loop, the robot repeatedly retrieves a sensor value (in this case, from mindsensors.com Line Leader) and thus waits until it changes to a specific value.
I converted the corresponding Python code to Go, but I noticed Go is actually seven times slower in retrieving those sensor values. Below are the two test programs I wrote to compare the performance.

ll = Sensor("in2")
ll.mode = "PID-ALL"
debug_print("Starting")
start = time.perf_counter()
for _ in range(1000):
    value = ll.value(2)
    if value == -1:
        # is on black line; the program would normally end the loop here
        pass
end = time.perf_counter()-start
debug_print(end)

Output (example): 0.9874834319999763

func main() {
    ll, err := ev3dev.SensorFor("ev3-ports:in2:i2c1", "ms-line-leader")
    if err != nil {
        log.Fatal(err)
    }
    ll.SetMode("PID-ALL")

    log.Println("Starting")
    start := time.Now()
    for i := 0; i < 1000; i++ {
        value, err := ll.Value(2)
        if err != nil {
            log.Fatal(err)
        }
        if value == "-1" {
            // is on black line
        }
    }
    end := time.Since(start)
    log.Println(end)
}

Output (example): 6.850100872s

While Python takes about 1 second on my EV3 for the loop, Go takes about 7 seconds.

The question I'm asking myself is: Am I doing something wrong here? Because I usually would expect Go to be faster, and indeed the startup time is much lower.
If not: Why is Go seven times slower? I couldn't find any major difference between how the python ev3dev2 module and the Go github.com/ev3go/ev3dev package retrieve sensor values.

PS: I think ~143 checks per second with Go are more than enough, but I'm opening this issue because I'm curious to find out what causes this. As you might have guessed, I've got little to no experience with Go.

ev3dev: add device finding function

Add functions Find(dst Device, driver string) error and FindAfter(d, dst Device, driver string) error that find a device of the given Device types such that the driver name matches the device driver.

The approach is to iterate over the dst.Path() contents and check the driver name against driver, returning the first match in the case of Find or the first match after d.String() in the directory list for FindAfter. The resulting found device is placed in dst by reflection (or a private setID method is added to Device) and its err field is set to nil.

If d is nil in FindAfter searching starts from the first directory slot associated with dst (equivalent to Find). If it is not nil, it's concrete type must match the concrete type of dst or an error is returned.

Only ev3go/ev3/ev3dev devices are supported; use of others will return a meaningful error.

MS Sensor Multiplexer

Hi,

I was wondering how the Mindsensors Sensor Multiplexer could be used in this language, including:

  • How do I create a lego port with an incorrect / undefined driver (the device must be set for each port due to lack of autodetection)?
  • What sort of address for the port do I need to use?
  • How do I get individual values from the multiplexed ports? Is it like usual?

Thanks in advance

ev3dev: add high-level LED control

Add an ev3 package and start with high-level LED control.

Sketch:

type LED struct { ... }

func NewLED(s Side) *LED
func (l *LED) Color() (color.Color, error)
func (l *LED) SetColor(color.Color) *LED
func (l *LED) Trigger() (Trigger, error)
func (l *LED) SetTrigger(Trigger) *LED
func (l *LED) Pattern([]time.Duration) *LED
func (l *LED) Stream(<-chan time.Duration) *LEDStream
func (l *LED) Err() error

type Side byte

const (
    Left Side = 1 << iota
    Right
}

type Trigger string

const (
    None Trigger = "none"
    MMC0 ... etc
    Timer
    Heartbeat
    DefaultOn
    Transient
    BatteryChargingOrFull
    BatteryCharging
    BatteryFull
    BatteryChargingBlinkFullSolid
    RFKill0
)

type LEDStream struct { ... }

func (l *LEDStream) Waiter() <-chan error

fatal error when running example

Hello,
I am having some trouble making the example run.

What I did on my computer:

  • Set GOARCH to arm
  • Set GOARM to 5
  • Set GOOS to linux
go get github.com/ev3go/ev3dev/examples/demo 
go build github.com/ev3go/ev3dev/examples/demo 
scp demo [email protected]:/home/robot

What I did on the robot:

  • Run the demo program through the LCD interface on the brick: does nothing but displays some text for a fraction of a second
  • Run the demo program from an ssh session on the robot ./demo.
    This is what it returns:
robot@ev3dev:~$ ./demo
unexpected fault address 0xa6c92000
fatal error: fault
[signal SIGBUS: bus error code=0x2 addr=0xa6c92000 pc=0x63dd4]

goroutine 1 [running]:
runtime.throw(0xe8bd5, 0x5)
	/usr/local/go/src/runtime/panic.go:608 +0x5c fp=0x424668 sp=0x424654 pc=0x38990
runtime.sigpanic()
	/usr/local/go/src/runtime/signal_unix.go:387 +0x214 fp=0x42468c sp=0x424668 pc=0x4bfb0
runtime.memclrNoHeapPointers(0xa6c91000, 0x16400)
	/usr/local/go/src/runtime/memclr_arm.s:68 +0x58 fp=0x424690 sp=0x424690 pc=0x63dd4
github.com/ev3go/ev3dev.(*lcd).frameBuffer(0x472000, 0xf0b01, 0x472018, 0x66)
	/home/lionel/Documents/projects/go/src/github.com/ev3go/ev3dev/lcd.go:85 +0x1c0 fp=0x4246cc sp=0x424690 pc=0xb8774
github.com/ev3go/ev3dev.(*lcd).Init(0x472000, 0x1, 0x0, 0x0)
	/home/lionel/Documents/projects/go/src/github.com/ev3go/ev3dev/lcd.go:60 +0x10c fp=0x4246e4 sp=0x4246cc pc=0xb8578
main.main()
	/home/lionel/Documents/projects/go/src/github.com/ev3go/ev3dev/examples/demo/demo.go:26 +0x38 fp=0x4247c4 sp=0x4246e4 pc=0xbb970
runtime.main()
	/usr/local/go/src/runtime/proc.go:201 +0x204 fp=0x4247e4 sp=0x4247c4 pc=0x3a584
runtime.goexit()
	/usr/local/go/src/runtime/asm_arm.s:867 +0x4 fp=0x4247e4 sp=0x4247e4 pc=0x636d8

I compiled a simple hello world program to make sure the problem was not from the compilation and it worked perfectly.

Could you help me please?

Note: I am using the jessie version ev3dev-jessie-ev3-generic-2017-09-14

ev3dev: consider moving button polling and waiting into ev3

Polling and waiting are essentially high-level functions and so might be a better fit for ev3. The ev3dev Button type would then just return the /dev/input file corresponding to the button event, being a string type and defaulting to /dev/input/by-path/platform-gpio-keys.0-event when zero.

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.