ev3dev / ev3dev-lang Goto Github PK
View Code? Open in Web Editor NEW(deprecated) language bindings for ev3dev sensors, motors, LEDs, etc.
License: GNU General Public License v2.0
(deprecated) language bindings for ev3dev sensors, motors, LEDs, etc.
License: GNU General Public License v2.0
I suggest that the specification should allow null values for INPUT_AUTO
and OUTPUT_AUTO
, and that the constructors should not be required to check for the empty string if a null value can be used instead.
In languages where the empty string is not "falsy" (in my case Ruby) it makes for a cleaner implementation to not have to check for it but instead rely on the truthiness of the parameter. It isn't much extra code that is needed to do the check, but using common idioms of the implementation language makes the intent more clear.
I tried writing my own app and when in device::connect I get an exception which causes _path.clear() to execute and therefore think the motors are not connected. Not sure why this is. I tried the drive-test and ev3dev-lang-test apps as well and the same problem. I upgraded to the latest version v0.6 of ev3dev with no change. I checked my sys/class/tacho-motor files and they are there. Do you know why this would happen?
Hello,
I've just tested ev3dev-lang-demo and ev3dev-lang-test connecting a Hitechnic angle sansor (http://www.ev3dev.org/docs/sensors/hitechnic-nxt-angle-sensor/)
The demo executable recognized it as , but without accumulated angle function. Is it possible to add it ?
I tried to add the line in ev3dev-lang-test:
test_sensor<i2c_sensor>("ht-nxt-angle");
So how can I add this device in ev3dev-lang-test ?
There is an issue with the current specification of led::trigger
and led::triggers
attributes. These differ from the rest of attributes/attribute sets (like motor::command
and motor::commands
) in the sense that single sysfs file is used to expose both possible values of the trigger as well as the current value:
$ cat /sys/class/leds/ev3-right0\:red\:ev3dev/trigger
[none] mmc0 timer heartbeat default-on transient legoev3-battery-charging-or-full legoev3-battery-charging legoev3-battery-full legoev3-battery-charging-blink-full-solid rfkill0
$ echo timer > /sys/class/leds/ev3-right0\:red\:ev3dev/trigger
compare this with
$ cat /sys/class/tacho-motor/motor0/commands
run-forever run-to-abs-pos run-to-rel-pos run-timed run-direct stop reset
$ echo run-forever > /sys/class/tacho-motor/motor0/command
The cpp API does provide a way to access such attributes, but there is currently no way this can be described in the spec.json file.
We could introduce another attribute type in the specification for such attributes (I think led::trigger
is the only example so far), something like string selector
, and then update the templates for each of the bindings. What do you think?
I can't seem to get the motors to do anything with the C++ language bindings. This includes trying to use the demo to run/stop motors. I've connected 3 motors to my EV3 (two large tacho and one medium tacho). Am I missing something basic? I tried fiddling with the modes a bit to get something to happen, with no luck. At least to start with, I'm just trying to get a motor to spin indefinitely.
I've also tried simply echoing stuff into the files in /sys/class/tach-motor/motorn/... Nothing seems to happen.
Everything else seems to work, I can read the position from the tacho (it changes if I manually rotate the axle).
FYI, I have release the 3.16.1-8-ev3dev kernel which includes many renames. Changelog.
Also, I would highly recommend adding the lego-port
class to the next iteration of the spec.
Currently, If I run the autogen script in a clone of the repo, the changes are made to the submodule clone inside the main repo. If I then commit it, pushing it gets complicated because I need to manually specify the branch to pushed from a detached HEAD. If It then turns out that there are remote changes that I haven't pulled yet, it gets even more complicated.
Is there something that we can do to improve this? As far as I know, the submodules are our only option if we want to keep the core code in separate repos. So, do we want to add an option on the autogen script to specify the repo root to use (so that you could point it to a normal clone)? Or is there a better option that I'm not thinking of?
They simply doesn't work. "Can't import PIL package" or something. I tried installing PIL through pip, but it says it is incompatible with ev3dev.
Tried installing Pillow, failed (memory error at 99%).
So, what do I do? Or does this mean current state of Python binding is not stable enough to use?
Also, currently it is not clear if I should use Python binding contained in this repo or in https://github.com/topikachu/python-ev3 (it was updated quite a while ago, but I've seen at least one project successfully using it). I, for the record, tried the one that doesn't use virtualenv. Must I do the other way around?
Similar to how it is implemented in the remote_control
class.
Hello,
Just to confirm before testing servomotors, should I connect NXTServo-V3 above (motor out port) or below (sensor in port) to the ev3brick, because it is notice to not connect to motor port (doing so may damage NXTServo-V3) ?
I tested using sensor port following this page http://www.ev3dev.org/docs/sensors/mindsensors.com-8-channel-servo-controller/
ev3dev-lang-demo recognized it writing:
(1) ms-8ch-servo (device ms-8ch-servo, port in1, mode V3)
but the value is only voltage ?
Choice: 1
*** ms-8ch-servo (V3) actions ***
(s)how modes
(c)hange mode
(v)alue
(m)onitor
(b)ack
Choice: v
value is 0.037 V
Can I move the servo using ev3dev-lang-demo ?
It'd be nice to be able to cross compile C++ without brickstrap. I'm not sure if it's just my setup (running brickstrap on Ubuntu in a virtualbox) but compilation is really slow, and it's a pretty heavyweight setup for something that seems like it should be a lot simpler.
I spent some time trying to cross compile without brickstrap. The biggest challenge is the fact that ev3dev.cpp includes some sys/ headers that really need to come from brickstrap. There are two real dependencies here:
The dependency on dirent.h can be removed by assuming that every file will be named "patternN" where N is an integer. It's a little dirty because if you unplug/replug motors/sensors very often, N gets large, so trying to open files 0 through N might be expensive. This is a change I can tolerate locally... but it might be worth considering making the file name allocation in the drivers (I'm not sure exactly how this happens) allocates the name with the smallest available N. Then it would make the change to avoid depending on dirent a no-brainer.
mmap/munmap is harder. There is already an #ifdef in lcd::init to only do it if mmap is there. Fixing the compiler errors just means adding an equivalent to lcd::deinit. Of course, this is a pretty lame "solution" since it is basically disabling the lcd.
Once these dependencies are removed, I think it's only a matter of getting a working compiler for the arm target and a corresponding C/C++ standard library. The C standard library should work because it is loaded from a shared object on the EV3. That said, this is easier said than done. I've not been able to successfully build a binary with clang yet (much easier to cross compile with clang than gcc, at least in theory).
Is this something you have explored yet? I plan to continue trying to get this to work, but maybe you have already gotten farther than me?
I have almost completed a preliminary draft of the spec for motors and sensors. It can be found here: https://github.com/fdetro/ev3dev-lang/blob/language-binding-unification/wrapper-specification.md.
For this first version, I tried to mostly do direct mappings of sysfs properties to object properties. I am looking for feedback on what I have written so far, and I also have a few questions about finishing the feature set so that we can get to a version that we can implement.
Here are my questions:
Once we answer these questions and tidy up the spec, we should be able to start implementing this in code.
There are a number of places where the docs say a "space separated list". This is copied from the sysfs documentation, but in ev3dev-lang, these are actually arrays of strings.
Creating new sensor using new ev3dev.Sensor();
returns:
Error: ENOENT, no such file or directory '/sys/class/lego-sensor/sensor1/name'
It looks like there is no name value anymore.
Here is workaround to make sensor work. In module/bin/index.js ev3dev/nstead of line:
var typeName = fs.readFileSync(path.join(rootPath, "name")).toString().trim();
I put this:
var typeName = '';
The second error is no dp value:
Error: ENOENT, no such file or directory '/sys/class/lego-sensor/sensor1/dp'
The example script returns this inside getFloatValue()
function. I tried this on gyro sensor.
Also, small thing, the package on npm
repository is outdated, using the sensor shows error which were already fixed on Github.
Hi all,
I'm quite new using ev3dev, so please don't be too hard on me.
I have installed ev3dev and executed the CPP samples. The ev3dev-lang-test program seems to detect properly my motors and my touch sensor, though it doesn't detect my EV3 color sensor. I also tried a NXT color sensor, without more success...
Am I the only one having this issue?
Thanks!
Hello,
I tried to used the tacho motor in position (or hold) mode with the newest system image (20-5-2015). I set position_sp
to 2000, and then run the run-to-pos-abs
command. The motor didn't move. So I tried to set the PID constants. It is impossible to write or read from files hold_pid/k*. All operations fails with "Operation not supported". I think it is a bug. Could you look at it, please?
Hi,
I am looking at converting the python bindings to using the autogen scripts. For now I am just trying to run the existing scripts. Unfortunately, the usage instructions do not work for me: https://gist.github.com/ddemidov/3b97a533a149491c7006
Do I need anything else for autogen to work?
Hi,
I'm trying to get node.js bindings working on ev3dev. I found out that examples/test-motor-sensor.js does not work. See below. Has the folder been renamed or the interface to motor sensors changed? I am assuming this example should work with the large/medium EV3 motors.
I am using latest self-compiled js bindings.
alah@ev3dev:~/work/ev3-js-tests$ nodejs test-motor-sensor.js
Motor --------------
dutyCycle: 0
dutyCycleSp: 0
portName: outA
position: 0
positionSp: 0
pulsesPerSecond: 0
pulsesPerSecondSp: 0
rampDownSp: 0
rampUpSp: 0
regulationMode: off
run: 0
runMode: forever
speedRegulationP: 1000
state: idle
stopMode: coast
stopModes: coast,brake,hold
timeSp: 0
type: tacho
Setting motor properties...
Running motor...
--------------------
Sensor -------------
{ [Error: ENOENT, no such file or directory '/sys/class/lego-sensor/']
errno: 34,
code: 'ENOENT',
path: '/sys/class/lego-sensor/',
syscall: 'readdir' }
Error: You must be connected to a device before you can read from it.
at Sensor.Device.readProperty (/home/alah/work/index.js:98:19)
at Sensor.Device.readString (/home/alah/work/index.js:87:26)
at Sensor.Device.getString (/home/alah/work/index.js:94:21)
at Sensor.Object.defineProperty.get [as portName] (/home/alah/work/index.js:768:25)
at i (/home/alah/work/ev3-js-tests/test-motor-sensor.js:31:38)
at Array.forEach (native)
at Object.<anonymous> (/home/alah/work/ev3-js-tests/test-motor-sensor.js:30:3)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
Happy that there are instructions in the R bindings readme.
Miss the package names that apt
recognizes.
Started with:
apt-get -s install R Rserve
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package R
E: Unable to locate package Rserve
web search lead me to try apt-get -s install r-base r-base-dev rserve
Still rserve
not found, also not found r-serve
Do I need to update my package list or any other trick?
And another question: any specific version of R needed for compatibility with these bindings?
I'm currently adjusting my cpp code to the autogen stuff and see some inconsistencies with the command
attributes that break my test code:
dcMotor
has attributes command
and commands
, but command
is read-onlyservoMotor
has only attribute command
, here read-writeIs this a bug in the spec or can @dlech comment on this?
In the "Using motors" guide, three different values for stop_mode
are described. But the stop_modes
attribute is never explained. Is it a dynamic value, that might change between different motors, or could I rely on the values from the documentation?
I'm toying with a Ruby implementation where I define attributes through special methods on the parent Device class. Those methods (rw
and ro
) each take an attribute name as its first parameter, and optionally either a class or an Enumerable (Array, Range or similar) as a second parameter. That second parameter is used to decide how to translate between the ev3dev string representation and the internal Ruby representation, but for enumerables also what values are acceptable. For the stop_mode
attribute I've used an array with the three known valid values for stop_modes
, but I'm wondering if it should rather depend on the return value of stop_modes
? (Which would be much harder to implement with this generalized attribute "macro" as it's not known at the time of the method definition.)
Over the past few moths, development on the ev3dev-lang bindings has generally stalled. @fdetro and I have both been busy, which has caused our bindings to become out-of-date (as mentioned in ev3dev/ev3dev#228 and ev3dev/ev3dev#265).
If we can get all of our bindings transferred to the auto-generation script system, it won't take very much effort to adapt to kernel changes and add more features. @fdetro: Might you have a chance to work on this over the next few weeks? If not, I might be able to take a shot at it, but I am not very good at C++ or lua. Is there anyone else who has some time available to try to update these two libraries (perhaps @andrewstarks made some progress after posting the above issue)?
CC @ddemidov and @bmegli: Do you guys have some time to do the same and try to get your bindings (R and Python) switched over, or manually update them if you would rather do that? I understand that this can require a large time commitment, but I hope that using autogen should expedite the process.
FYI, I have added two new attributes to the msensor class that will be included in the next kernel release. See ev3dev/ev3-kernel@32d6b41.
I've finally decided to follow through releasing the code for the project I've been working on with ev3dev, but it's now pretty seriously out of date. I've updated most of my code, but I'm stumped on something really simple: How do you tell if a motor is running or not? I see there is stop_command
to get the stop command, but I don't see the equivalent of command
, if that is even the right way to do this.
Now that we have finished all the initial features, we are getting to the point that we can start working on less-vital items. Some of the features that we have been discussing are:
So, what do we think we want to include in the next version (Maybe a v1)?
@dlech Are there big interface changes coming to the sensor drivers that we should be planning around?
Hello,
Thanks for your cpp code example, I'd like to test it in our robot.
Could you please detail which release of ev3dev do you use? Do you have installed/upgraded some extras (kernel, module, ...)?
Regards,
Christophe.
Hi,
This is not a really issue. ^^
I create a python project python-ev3 running on ev3dev.
Are you willing to take a look?
Thanks
Sensors are not correctly recognized by cpp bindings ev3dev-lang/cpp in ev3dev-jessie-2014-10-07 with stock kernel 3.16.1.
The reason is:
-lack of type_id property in msensor
And the code in ev3dev.cpp, lines 174/175:
ifstream is((strDir+"/type_id").c_str());
if (is.is_open())
can't be executed properly (enter the if and search for the matching sensor)
Possible workaround:
-use name property (eg. name "ev3-uart-33" for infrared instead of type_id "33")
Also:
There is no type_id in sysfs Attributes in specification for msensor class so it seems that the fix is necessary.
Specification for msensor class:
http://www.ev3dev.org/docs/sensors/msensor-class/
I have merged the vala bindings into the ev3devKit library. So, my question is: do you want to keep it as a part of ev3dev-lang or let it just be its own library?
Not sure how to indicate the version I am refering to..
So this might do latest commit 88195325bb
I saw the same in earlier version.
Part of ev3dev.lua:
function Motor:init(port, motor_type)
for i = 0, 9 do
self._path = sys_motor.."tacho-motor"..i.."/"
If I read this correctly this sets the path starting at tacho-motor0
up to tacho-motor9
The numeric suffix is increased for each "new" connected motor or sensor.
For an EV3 brick that runs for some time, that may be not enough.
There may be a good way to just determine what directories really are present instead of scanning a lot.
I know lua since a few days, so this may well be rubbish, but maybe something like this might do:
-- start empty
paths={}
searchpath="/sys/class/tacho-motor/motor*/"
devLookup(searchpath)
searchpath="/sys/class/dc-motor/motor*/"
devLookup(searchpath)
-- "do" each path
for i = 1,table.getn(paths) do
self._path = paths[i].."/"
The procedure:
-- General function
function devLookup(path) -- result will be inserted in the list "paths"
-- returns the 'basename' and the 'basedir'
function getBases(filename)
return string.gsub(filename, "(.*/)(.*)", "%2") or filename,
string.gsub(filename, "(.*/)(.*)", "%1")
end
-- Open directory: look for directorie(s), save data in p.
local p = io.popen('find '..path..' -maxdepth 0 -type d')
for file in p:lines() do
-- drop the trailing slash:
prefix = string.sub(file,1, string.len(file)-1)
base, path = getBases(prefix)
-- extract the NUMERIC part of the directory name:
i, j = string.find(base, "%d+")
baseprefix = string.sub (base, 1, i-1)
thispath = path..baseprefix..string.sub (base, i, j)
table.insert(paths, thispath)
end
end
The /sys/class/dc-motor/motor*/
above is used at kernel 3.16.1-6-ev3dev
I know that @ddemidov has been adding some great features like motor helper functions to the Python lib, and would like to get those implemented in all of our libraries in the repo. @ddemidov can you provide a list of the features that you think should be added to our specification? You have already blazed the trail and figured out how various methods of exposing these APIs can work, so I'd love some of that insight when we are implementing them cross-language.
I got bus error when dpkg-reconfigure locales. I used the default settings - en_US .... Anyone can help me? Thanks.
Currently, we don't really have any documentation... on anything. Although I don't think that we should set up any full-fledged docs until we have the core code stabilized, I think each wrapper should have some basic "install and build" instructions.
I would like to suggest that we include a README.md
file in each sub-folder that has basic info on using the library that lives in that folder. GitHub will display it when you open the folder, and READMEs are pretty much the convention for specifying what info people should read.
What do you think?
Hello,
I've just tested this test, and it seems all buttons are always UP when I display the value.
Can you try if you have the same problem ?
Best regards,
Christophe
I'd like to get rid of hard coded string constants like these.
irsens.set_mode(ev3dev::infrared_sensor::mode_proximity);
to this:
irsens.set_mode("IR-PROX");
In case of python possible string values are easily checked in interactive python shell:
>>> irsens.modes
['IR-CAL', 'IR-PROX', 'IR-REM-A', 'IR-REMOTE', 'IR-S-ALT', 'IR-SEEK']
>>> irsens.mode = 'IR-REMOTE'
taho-motor
class.irsens.set_mode(ev3dev::motor::position_mode_absolute);
So I'd like to get rid of most of the strings constants at least in public API. What do you think?
CC @fdetro.
During several tests, including your test program, I couldn't figure out to see my motors (medium or large) connected.
Basically I cannot use motors.
Good for sensors after upgrade to kernel 3.16.1-6.
Thank you for your attention.
I would like to use the vala bindings for ev3dev/ev3dev#169 (so you can expect a pull request to update it to the current kernel). It would be nice if each language had its own submodule so that I can clone only the language that I want to use instead of having to clone everything.
For now though, I am going to try this: http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/
Unless I'm missing something, there's no easy way to get the valuen
attribute for the sensor
class.
What I would propose for now is that the sensor
class gets 8 additional attributes, one for each valuen
where n runs from 0 to 7
Eventually, it would be neat if we could have a mapping from the value name to n - depending on the mode.
It seems really inconsistent which of the "mode" attributes get a "modes". Motors get stop_modes
, but no run_modes
, regulation_modes
or position_modes
, and Sensors get both mode
and modes
.
Is there a reason for this? Is it seen that stop_modes
is necessary but other "modes" aren't?
I have only checked this from Python API for now:
>>> from ev3dev import *
>>> led.red_right.trigger = 'timer'
>>> led.red_right.set_on_delay(200) # Both of these
>>> led.red_right.set_off_delay(200) # work as expected
>>> led.red_right.flash(200)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-7-2c6e48ea06cd> in <module>()
----> 1 led.red_right.flash(200)
RuntimeError: No such device
>>> led.red_right.set_on_delay(200)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-8-e18c136e252c> in <module>()
----> 1 led.red_right.set_on_delay(200)
RuntimeError: No such device
Currently in the spec, we say that any error should prevent further use of a device object by resetting the connected
property. After giving it some thought, I think this behavior should be changed. There are multiple property files that are designed to return an error to communicate information (ex. the msensor command
), so I think that errors should cause the call to stop but allow the program to keep running.
I don't know why I included this originally, but now that it's in there I am opening an issue to communicate this change before I actually modify anything.
In wrapper-specification.md
:
Depending on the language, names will be slightly different (ex. "touchSensor" or "TouchSensor" or "touch-sensor") so that they fit the language's naming conventions.
Yet this does not document what specific names can or should be used in a specific language.
I would have expexted something like:
FAKE table
Property Name | cpp | js | lua | vala | R | Type | Accessibility | Description |
---|---|---|---|---|---|---|---|---|
Duty Cycle | DutyCycle | Duty_Cycle | dutyCycle | DutyCycle | dutyCycle() | Number | Read | |
Duty Cycle | DutyCycleSp | Duty_Cycle_Sp | dutyCycleSp | DutyCycleSp | DutyCycleSp() | Number | Read |
Now it the wrapper specification:
Property Name | Type | Accessibility | Description |
---|---|---|---|
Duty Cycle | Number | Read | |
Duty Cycle SP | Number | Read/Write |
Would this doc be best placed per language or as I first expected in the wrapper specification?
I have a minor suggestion regarding the stop commands, at least in the C++ API. I'm finding the API to be a bit confusing, set_stop_command
feels a lot like a command to actually stop. However, it seems that set_stop_command
is actually more analogous to the old set_stop_mode
function, while the stop command actually stops. This might just be a matter of changing the documentation to describe this a bit more.
In line 89 in file ev3dev-lang-test.cpp should be:
test_motor < large_motor > ("large");
instead of:
test_motor < medium_motor > ("large");
The autogen/spec.json incorrectly names the hold/speed regulation parameters. See the current driver docs here and here.
Currently, the ev3dev.org docs are generated based on data placed in the source files of the ev3dev drivers in the lego-linux-drivers repo. The comments in the source files are translated into the documentation pages via @dlech's Python script.
I was thinking that this is similar in concept to what we are doing with our own JSON spec system, only we manually update our spec based on those docs changes. I was wondering what the technical limitations would be for us to generate our spec off of the same source (the comments in those source files). Basically, my query comes down to this:
My hope would be that, if I could get my script to pull from that data, we wouldn't be left with nearly as many little discrepancies between the kernel functionality and what I put into the spec.
This is not a bug, but a general observation:
It looks like most implementations of ev3dev language bindings choose to reopen sysfs files each time anew, rather then caching an open filehandle (open once, seek to the beginning before reading).
While reopen approach is much "safer" - it has a serious performance penalty.
Unfortunately my primary experience is with language bindings not in this repo, but I believe the above applies to lesser or higher degree to all implementations.
In a small python test using cached filehandle is over x3.5 faster, and golang test with 3 concurrent readers showed x10 performance improvement.
In the C++ API header, the PID(K) parameters are set to change attributes with a lowercase p/i/d/k, but the attributes in the recent kernels are named with an uppercase P/I/D/K.
This is where I'm going to keep track of the languages that we have implemented or want to implement. Feel free to edit/comment on this.
This table includes what we have already discussed, along with a few of my own additions:
Language | State | Comment |
---|---|---|
C++ | Up-to-date | |
Lua | Temporarily removed (new version in progress) | |
JavaScript | Up-to-date | |
Python | Up-to-date | |
Vala | Removed in favor of ev3devKit | |
R | Removed | |
Bash / Command-line tool | Proposed | Implementing a basic subset of the spec in a command-line tool would make an easy way to test and use the motors from the command line. This could even be included in future ev3dev images if we did it correctly. |
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.