quirkycort / ev3dev-sim Goto Github PK
View Code? Open in Web Editor NEWBrowser based simulator for ev3dev-lang-python
License: GNU General Public License v3.0
Browser based simulator for ev3dev-lang-python
License: GNU General Public License v3.0
I notice in the ev3dev
docs an example of getting the robot to speak using simple text to speech:
from ev3dev2.sound import Sound
sound = Sound()
sound.speak('Welcome to the E V 3 dev project!')
Could this be implemented using the browser
In a Jupyter notebook, this would be something like:
from IPython.display import Javascript
txt = 'hello'
Javascript(f'speechSynthesis.speak(new SpeechSynthesisUtterance("{txt}"))')
I think offline is in your TODO list, but it doesn't seem to work right now. When I try and run code, it gives the following error:
ImportError: No module named ev3dev2 on line 5
Any workaround at this time?
While testing, I noticed that if you do not use any sensor values in the python program, the browser will completely freeze. Do you happen to know of any workarounds for this?
I plan to use this nice simulator for an online teaching due to a coronavirus containment period.
I notice that a short ev3dev python script example:
from ev3dev2.sensor import *
from ev3dev2.sensor.lego import UltrasonicSensor
ultrasonic = UltrasonicSensor(INPUT_1)
while True:
print('Ultrasonic: ' + str(ultrasonic.distance_centimeters))
locks the browser tab.
A solution seems to be , as implemented for the other sensors, to add
time.sleep(SENSOR_DELAY)
in all the ultrasonic sensor function of sensors/lego.py.
Best regards
From the About page in the demo, I got the impression that the motors stopped immediately. But If I run the following:
from ev3dev2.motor import OUTPUT_B, OUTPUT_C
from ev3dev2.motor import MoveTank, SpeedPercent
tank_drive = MoveTank(OUTPUT_B, OUTPUT_C)
def print_wheel_positions():
print('Left wheel position: {}'.format(tank_drive.left_motor.position))
print('Right wheel position: {}'.format(tank_drive.right_motor.position))
print_wheel_positions()
left_speed = right_speed = SpeedPercent(20)
for i in range(5):
tank_drive.on_for_degrees(left_speed, right_speed, 360)
print("After {} rotation:".format(i))
print_wheel_positions()
I get a report:
Left wheel position: 0
Right wheel position: 0
After 0 rotation:
Left wheel position: 385
Right wheel position: 385
After 1 rotation:
Left wheel position: 770
Right wheel position: 770
After 2 rotation:
Left wheel position: 1155
Right wheel position: 1155
After 3 rotation:
Left wheel position: 1540
Right wheel position: 1540
After 4 rotation:
Left wheel position: 1925
Right wheel position: 1925
I was expecting the position to report increments of 360 degrees? If I increase the speed, then the position
count is increased even further at each step?
It would be useful to be able to zoom in an out on the canvas on occasions when the robot speeds out of site.
Being able to click on the robot and drag it to a new location would also be handy, as would a pen-up / pen-down feature to track the path taking by the robot.
A call to on_for_seconds() will block indefinitely.
In this small example, the robot motion will never end.
from ev3dev2.motor import LargeMotor, OUTPUT_C
lm = LargeMotor(OUTPUT_C)
lm.on_for_seconds(speed=50, seconds=4)
lm.off()
I will try soon to solve the issue with the missed timeout of this function.
Hi Cort,
I am having an issue with the robot moving expected distances.
Here is the simplest program:
from ev3dev2.motor import MoveSteering, OUTPUT_B, OUTPUT_C
steering_drive = MoveSteering(OUTPUT_B, OUTPUT_C)
steering_drive.on_for_rotations(0, 50, 1)
With the default robot configuration (56 mm diameter wheels) I would expect the robot to move 175.84 mm in one rotation. However, it moves about double according to the click and measure line. Am I going wrong somewhere?
Edit: Same issue with on_for_degrees() as well as if using TankSteering
Edit Edit: Changing in ev3DevSim line 435ish:
wheel.pos += dist;
to
wheel.pos += dist * 2;
Makes it work like I think it should. I don't know why though...
I came across your simulator and it looks really helpful. My team is using the pybricks setup from Lego in ev3dev. Any chance I can work with you to add that to this simulator?
I'm not sure how mature it is yet, but https://github.com/blockpy-edu/BlockMirror, from the developers of BlockPy, offers "[a]n interface for dual block/text representation with Blockly".
This allows users to toggle between a code view and a blockly style blocks view, and edit either.
It's based on CodeMirror and also makes use of the Skulpt parser.
I was wondering how easy it would be to switch out your editor with the BlockMirror editor to allow novices users to code your simulator using the blockly editor to begin with and then slowly toggle themselves to using the code editor?
I started having a look at getting ev3devsim
running as an ipywidget
in a Jupyter notebook here but fell at an early hurdle not being able to load external packages into the Skulpt environment (I think).
It did get me thinking about how ev3devsim
might work in a notebook context though.
Firstly, the ace
editor could be replaced by Jupyter code cell magic that allows code to be entered into a notebook code cell and then run in the simulator.
Through state synchronisation between the widget JS environment and the notebook py environment, there would also be an opportunity to retrieve data from the simulator so that it could be plotted / charted in a fully blown Python environment within the notebook. (It might also be useful if a live data stream were available / displayed within the notebook as the simulator runs but that would be one to pursue after a simple data export I think?)
The "upload image" only working with google chrome can be fixed by simply moving this option (and the associated js code) in a button :
index.html
<!-- <option>Upload Image (2362x1143px)...</option> -->
<option hidden>Custom Image</option>
</select>
<button id="uploadMapBtn">Upload Image (2362x1143px)</button> <!-- the new button -->
<button id="robotConfiguratorOpen">Configure Robot</button>
document.getElementById('uploadMapBtn').addEventListener('click', function() {
var hiddenElement = document.createElement('input');
hiddenElement.type = 'file';
hiddenElement.accept = 'image/*';
console.log(hiddenElement);
hiddenElement.dispatchEvent(new MouseEvent('click'));
hiddenElement.addEventListener('change', function(e){
var reader = new FileReader();
reader.onload = function() {
sim.loadBackground(this.result);
sim.clearObstacles();
sim.clearObstaclesLayer();
};
reader.readAsDataURL(e.target.files[0]);
});
var select = document.getElementById('map');
select.selectedIndex = select.options.length - 1;
});
Tested with safari, firefox.
If I am correct, the issue was that hiddenElement.dispatchEvent(new MouseEvent('click')); required a real previous click of the user to be active in the other browser.
On another topic, i will now see if the robot configurator is flexible enough to freely choose the 4 sensor types connected to the robot.
I may need 3 ultrasonic sensors connected to the ev3 to solve a labyrinth considering an inaccurate odometry. I will issue a pull request, if I have to update the robot configuration code. Best regards
Hi there!
This is based on a problem posed at the end of one of my university lectures. The problem posed was to draw any regular polygon, given the number of sides. The tutor came up with a way of solving this by using differential rotation, which I understood but felt could be simplified. To that end I came up with the following:
sides = 4
if sides < 3:
print("A regular polygon must have 3 or more sides.");
ANGLE = 360 / sides
FORWARD_SPEED_PC = SpeedPercent(60)
for side in range(sides):
# Go straight, for 0.5 seconds.
tank_drive.on_for_seconds(FORWARD_SPEED_PC,
FORWARD_SPEED_PC,
1)
# Turn by the external angle, this will make
# the internal angle correct for the shape.
tank_drive.on_for_degrees(SpeedPercent(0),
SpeedPercent(100),
ANGLE)
The code is simple enough, with one obvious problem: it doesn't work. Not only does it not work as I would expect... it produces a result I can't even explain. The I had was to simply rotate the tank by a set number of degrees (using on_for_degrees
) and then continuing with the next loop iteration.
It doesn't seem to be turning by the angle (in this case 90 degrees) at all, and I have no idea why. Does anyone have any pointers as to what is going on here? This one has me puzzled. I'll try to attach a screenshot, if I can.
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.