Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use screen AND motors ? #276

Closed
romainschmid opened this issue Dec 9, 2016 · 8 comments
Closed

Can't use screen AND motors ? #276

romainschmid opened this issue Dec 9, 2016 · 8 comments

Comments

@romainschmid
Copy link

  • **ev3dev version: 4.4.32-17-ev3dev-ev3
  • **ev3dev-lang-python version: python_ev3dev-0.8.0.post4-py2.7.egg (not sure this is what's wanted)

Hi,

I can't figure what the problem is with my code : I want to calibrate my light sensor, in order to follow a black line. I want the robot to oscillate 4 times, so that the sensor can update the max_white and max_black values.
I have succeeded using the lcd screen and the motors, but separately. If I put all my functions in the same file, it will not work, but if I use the functions in different files, the code works.
In fact, the motors will run, but the display isn't even changed from its original state, and the values are not updated.

I am not exactly sure if it's a bug somewhere, or if it's due to my very beginner level in programming.

Here is my code :

#!/usr/bin/python3
#  -*- coding: utf-8 -*-
from ev3dev.ev3 import *
from  PIL import ImageFont
from threading import Thread
from time import sleep
lcd = Screen()
globalstop = 0
ts = TouchSensor()
color_sensor = ColorSensor()
color_sensor.mode='COL-REFLECT'
motor_left = LargeMotor('outB')
motor_right = LargeMotor('outC')
f = ImageFont.truetype('/usr/share/fonts/truetype/msttcorefonts/Arial.ttf', 15)
max_white = 0
max_black = 100

def motors():
    global globalstop
    sleep(0.5)
    for i in range(4):
        if i % 2 == 0:
            motor_right.run_to_rel_pos(position_sp=180, speed_sp=200, stop_action='brake')
            motor_left.run_to_rel_pos(position_sp=-180, speed_sp=200, stop_action='brake')
            motor_right.wait_while('running')
            motor_left.wait_while('running')

        else:
            motor_right.run_to_rel_pos(position_sp=-180, speed_sp=200, stop_action='brake')
            motor_left.run_to_rel_pos(position_sp=180, speed_sp=200, stop_action='brake')
            motor_right.wait_while('running')
            motor_left.wait_while('running')
        print (i+1)
    globalstop = 1

motors = Thread(target=motors())


def display_and_update():
    global max_white, max_black, globalstop
    while globalstop == 0:
        lcd.clear()
        lcd.draw.text((10, 10), "max_white : %s" % max_white,font=f)
        lcd.draw.text((10, 40), "max_black : %s" % max_black,font=f)
        lcd.update()
        if max_white < color_sensor.value():
            max_white = color_sensor.value()
        if max_black > color_sensor.value():
            max_black = color_sensor.value()

disp_and_update = Thread(target=display_and_update())

#start the threads
motors.start()
disp_and_update.start()

#finally, output the values
print ("max_white : ", max_white, "max_black : ", max_black)

Any help appreciated !

@ddemidov
Copy link
Member

ddemidov commented Dec 9, 2016

How do you run the program?

If you do this from an ssh session, then brickman (the default interface) is still in control of the screen and is probably overwriting your changes.

If you launch the script from brickman, the script should get a separate virtual screen and will have full control of it.

It is also possible to get the separate screen from the command line with sudo chvt <n> where <n> is replaced by the virtual terminal you want to switch to. You can use this to switch between Brickman on tty1 and a text login on tty2. (see #222 (comment))

EDIT: another link: #194 (comment)

@romainschmid
Copy link
Author

Aha, I remember reading about that. I must confess I didn't understand neither the post you mentioned nor your answer ! I am on a Mac, and not really familiar with non GUI apps, like terminal, although I'm getting better. Could you tell me where exactly I should sudo something ? On the bot, when ssh-logged, or on my computer ?

I never launch my programs on the brick directly, because I am using a nice pyCharm feature, the git repository. Like that, I don't have to chmod my files in order to launch them directly on the brick. Plus, I can let my bot on my playground, and remain on my seat !

@romainschmid
Copy link
Author

romainschmid commented Dec 9, 2016

Thank you for your help. I didn't get exactly what I wanted with the trick you showed me. It displays some kind of terminal on the bot, but what I wanted to have was to be able to display live values from the light sensor (I can do it, but in a separate program).
Although it's not exactly an issue, could you help me with this : I really don't understand something about threads : aren't they supposed to work independently, at the SAME time ?? This code might help you understand my problem :

#!/usr/bin/python3
#  -*- coding: utf-8 -*-
from ev3dev.ev3 import *
from threading import Thread

gauche = LargeMotor('outB')
droite = LargeMotor('outC')

def m_droite():
    for i in range(4):
        droite.run_to_rel_pos(position_sp=90, speed_sp=100, stop_action='brake')
        droite.wait_while('running')
        print ("gauche :", i)


def m_gauche():
    for j in range(4):
        gauche.run_to_rel_pos(position_sp=90, speed_sp=100, stop_action='brake')
        gauche.wait_while('running')
        print ("droite : ", j)


right = Thread(target=m_droite())
left = Thread(target=m_gauche())


right.start()
left.start()

Instead of making both motors turn at the same time, they do it one after the other ! Is it ok, doc ?

@ddemidov
Copy link
Member

ddemidov commented Dec 9, 2016

There is a demo project that uses threads here: https://github.com/rhempel/ev3dev-lang-python/blob/develop/demo/R3PTAR/r3ptar.py.

@romainschmid
Copy link
Author

Thanks for the link. I will check this, definitely. I've read something about threads, and it's a bit complicated for me now. I think I will have to study that .join thing...
The http://stackoverflow.com/questions/15085348/what-is-the-use-of-join-in-python-threading forum article pointed me on the way, and I've seen that in the code you mentioned.
Nice week-end, I will have to dig something nice !

@ddemidov
Copy link
Member

ddemidov commented Dec 9, 2016

Could you tell me where exactly I should sudo something ? On the bot, when ssh-logged, or on my computer ?

You need to enter this into the command prompt of the ssh session:

robot@ev3dev:~$ sudo chvt 2
[sudo] password for robot:

when you enter your password, you should see that the robot screen switched from the brickman interface to a new console with a login prompt. Ignore that prompt.

Now, when you update the screen from your python script, brickman won't be able to mess with the results. The following script works for me:

from time import sleep
import ev3dev.ev3   as ev3
import ev3dev.fonts as fonts

ir = ev3.InfraredSensor()
screen = ev3.Screen()
f = fonts.load('luBS18')

while True:
    screen.clear()
    screen.draw.text((10,10), 'Dist: {}'.format(ir.proximity), font=f)
    screen.update()
    sleep(0.25)

When you are done and want to bring the brickman interface back, enter in the ssh session:

robot@ev3dev:~$  sudo chvt 1

@WasabiFan
Copy link
Member

WasabiFan commented Dec 9, 2016

@ndward has a guide on doing this at the bottom of this page: https://sites.google.com/site/ev3python/learn_ev3_python/screen.

robot@ev3dev:~$ sudo chvt 2

@ddemidov I think (?) that virtual terminal 2 is reserved for Brickman child apps or something of that nature... I can't remember for sure though. Either way it shouldn't make any real difference.

@dlech
Copy link
Member

dlech commented Dec 10, 2016

I think (?) that virtual terminal 2 is reserved for Brickman child apps

OpenRoberta, specifically. But if openroberta.service is not running, it is free.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants