Commit bcacd84c authored by m.baxter's avatar m.baxter

Initial

parent 52c1d877
File added
File added
File added
__all__ = ['ev3dev', 'lego','mindsensors']
from ev3 import ev3dev
from ev3 import lego
from ev3 import mindsensors
This diff is collapsed.
"""
A simple condition-based event loop.
"""
import time
class EventLoop(object):
"""The event loop.
"""
def __init__(self):
self._events = []
self._closed = False
def register_condition(self, condition, target, repeat=False, count=-1):
"""Register `target` to be called when ``condition()`` evaluates to
true.
If `repeat` is false, `target` will only be called once for a serie
of polls where `condition` evaluates to true, e.g. when a button is
pressed.
If `count` is a positive number, the condition will be automatically
unregistered after been called this many times.
Returns an ID that can be used to unregister the condition.
"""
self._events.append(Event(condition, target, repeat, count))
return len(self._events) - 1
def register_value_change(self, getter, startvalue, target, count=-1):
"""Register `target` to be called when evaluating ``getter()``
returns a new value. `startvalue` is the starting value to check
against.
If `count` is a positive number, `target` will be called
periodically this many times before it will be disabled.
Returns an ID that can be used to unregister the timer.
"""
self._events.append(ValueChangeEvent(
getter, startvalue, target, count))
return len(self._events) - 1
def register_timer(self, seconds, target, count=1):
"""Register `target` to be called when the given number of seconds
has passed.
If `count` is a positive number, `target` will be called
periodically this many times before it will be disabled.
Returns an ID that can be used to unregister the timer.
"""
target_time = time.time() + seconds
condition = lambda: time.time() >= target_time
return self.register_condition(condition, target, False, count)
def register_poll(self, poller, callback):
"""Register `callback` to be called on every ``poller()`` evaluation.
Returns an ID that can be used to unregister this poll event.
"""
self._events.append(PollEvent(
poller, callback))
return len(self._events) - 1
def unregister(self, id):
"""Ungegister condition with the given id."""
del self._events[id]
def start(self, time_delta = 0.1):
"""Starts the event loop."""
self._loop(time_delta)
def stop(self):
"""Stops event loop."""
self._closed = True
def _loop(self, time_delta = 0.1):
"""The event loop."""
while not self._closed:
for i in range(len(self._events) - 1, -1, -1):
self._events[i].evaluate()
if self._events[i]._count == 0:
self.unregister(i)
time.sleep(time_delta)
class Event(object):
"""The base Event class.
"""
def __init__(self, condition, target, repeat=False, count=-1):
self._condition = condition
self._target = target
self._repeat = repeat
self._count = count
self._previous_evaluation = False
self._evaluation = False
def poll(self):
"""Returns true if condition is satisfied, otherwise
false. `evaluation` is the evaluated condition."""
return self._evaluation and (
self._repeat or not self._previous_evaluation)
def evaluate(self):
"""Evaluate the condition. If it evaluates to true, `target` is
called and the count number is decreased."""
self._evaluation = self._condition()
if self.poll():
self._target(self)
if self._count >= 0:
self._count -= 1
self._previous_evaluation = self._evaluation
evaluation = property(
lambda self: self._evaluation,
doc='The value from the most resent evaluation of the condition.')
previous_evaluation = property(
lambda self: self._previous_evaluation,
doc='The value from the previous evaluation of the condition.')
repeat = property(
lambda self: self._repeat,
lambda self, value: setattr(self, '_repeat', bool(value)),
doc="Whether to call target every time `condition` is true, even "
"if it haven't changed since last poll.")
count = property(
lambda self: self._count,
lambda self, value: setattr(self, '_count', int(value)),
doc='Remaining number of times this event can be fired before it is '
'automatically unregistered.')
class ValueChangeEvent(Event):
def __init__(self, getter, startvalue, target, count=-1):
Event.__init__(self, getter, target, count=count)
self._previous_evaluation = startvalue
def poll(self):
return self._evaluation != self._previous_evaluation
class PollEvent(Event):
def __init__(self, poller, callback):
Event.__init__(self, poller, callback, count=-1)
def poll(self):
return True
from .ev3dev import LegoSensor, Motor
class TouchSensor(LegoSensor):
def __init__(self, port=-1):
# Both lego-nxt-touch and lego-ev3-touch support auto
LegoSensor.__init__(self, port, name='lego-ev3-touch')
@property
def is_pushed(self):
self.mode = 'TOUCH'
return bool(self.value0)
class LightSensor(LegoSensor):
def __init__(self, port=-1):
LegoSensor.__init__(self, port, name='lego-nxt-light')
@property
def reflect(self):
self.mode = 'REFLECT'
# Reflected light intensity (0 to 100)
return self.value0/10.0
@property
def ambient(self):
self.mode = 'AMBIENT'
# Ambient light intensity (0 to 100)
return self.value0/10.0
class SoundSensor(LegoSensor):
def __init__(self, port=-1):
LegoSensor.__init__(self, port, name='lego-nxt-sound')
@property
def db(self):
self.mode = 'DB'
# Sound pressure level (0 to 1000)
return self.value0/10.0
@property
def dba(self):
self.mode = 'DBA'
# Sound pressure level (0 to 1000)
return self.value0/10.0
class ColorSensor(LegoSensor):
colors = (None, 'black', 'blue', 'green',
'yellow', 'red', 'white', 'brown')
def __init__(self, port=-1):
LegoSensor.__init__(self, port, name='lego-ev3-color')
@property
def rgb(self):
"""Raw color components; (`r`, `g`, `b`). Values between 0 and 1020(??).
All leds rapidly cycle, appears white."""
self.mode = 'RGB-RAW'
return self.value0, self.value1, self.value2
@property
def color(self):
"""Integer between 0 and 7 indicating the color. See the `colors`
attribute for color names.
All leds rapidly cycle, appears white."""
self.mode = 'COL-COLOR'
return self.value0
@property
def reflect(self):
"""Reflected intensity in percent (int). Red led is on."""
self.mode = 'COL-REFLECT'
return self.value0
@property
def ambient(self):
"""Ambient intensity in percent (int). Red led is off."""
self.mode = 'COL-AMBIENT'
return self.value0
@property
def ref_raw(self):
"""Raw reflected intensity; (`r`, `b`). Values between 0 and 1020(??).
Red led is on."""
self.mode = 'REF-RAW'
return self.value0, self.value1
class InfraredSensor(LegoSensor):
def __init__(self, port=-1):
LegoSensor.__init__(self, port, name='lego-ev3-ir')
class REMOTE:
"""Button values for the `remote` property."""
NONE = 0
RED_UP = 1
RED_DOWN = 2
BLUE_UP = 3
BLUE_DOWN = 4
RED_UP_AND_BLUE_UP = 5
RED_UP_AND_BLUE_DOWN = 6
RED_DOWN_AND_BLUE_UP = 7
RED_DOWN_AND_BLUE_DOWN = 8
BAECON_MODE_ON = 9
RED_UP_AND_RED_DOWN = 10
BLUE_UP_AND_BLUE_DOWN = 11
@property
def remote(self):
"""IR remote control mode. A tuple of recieved value for each of the 4
channels.
"""
self.mode = 'IR-REMOTE'
return self.value0, self.value1, self.value2, self.value3
@property
def remote_bin(self):
self.mode = 'IR-REM-A'
return self.value0
@property
def prox(self):
"""Proximity mode. Distance in percent (100% is about 70cm)."""
self.mode = 'IR-PROX'
return self.value0
@property
def seek(self):
"""IR Seeker mode. A list of (`heading`, `distance`) pairs for each of
the 4 channels.
When looking in the same direction as the sensor, `heading` =
-25 is far left and `heading` = +25 is far right.
`distance` is the distance in percent (100% is about 70cm).
Channels with no baecon returns (0, 128).
"""
self.mode = 'IR-SEEK'
return [(self.value0, self.value1),
(self.value2, self.value3),
(self.value4, self.value5),
(self.value6, self.value7)]
class GyroSensor(LegoSensor):
def __init__(self, port=-1):
LegoSensor.__init__(self, port, name='lego-ev3-gyro')
@property
def ang(self):
self.mode = 'GYRO-ANG'
return self.value0
@property
def rate(self):
self.mode = 'GYRO-RATE'
return self.value0
@property
def ang_and_rate(self):
self.mode = 'GYRO-G&A'
return self.value0, self.value1
class UltrasonicSensor(LegoSensor):
def __init__(self, port=-1):
LegoSensor.__init__(self, port, name='lego-ev3-us')
@property
def dist_cm(self):
self.mode = 'US-DIST-CM'
return self.value0/10.0
@property
def dist_in(self):
self.mode = 'US-DIST-IN'
return self.value0/10.0
@property
def listen(self):
self.mode = 'US-LISTEN'
return bool(self.value0)
@property
def si_cm(self):
self.mode_force_flush('US-SI-CM')
return self.value0/10.0
@property
def si_in(self):
self.mode_force_flush('US-SI-IN')
return self.value0/10.0
class LargeMotor(Motor):
def __init__(self, port=''):
Motor.__init__(self, port, _type='lego-ev3-l-motor')
class MediumMotor(Motor):
def __init__(self, port=''):
Motor.__init__(self, port, _type='lego-ev3-m-motor')
from .ev3dev import I2CS
from .ev3dev import LegoSensor
class MindSensorI2CS(I2CS):
@property
def version(self):
return self.read_byte_array_as_string(0x00, 8)
@property
def vendor_id(self):
return self.read_byte_array_as_string(0x08, 8)
@property
def device_id(self):
return self.read_byte_array_as_string(0x10, 8)
@I2CS.create_i2c_property(
command=(0x41, {'read_only': False}),
button_set_1 = 0x42,
button_set_2= 0x43,
x_left= 0x44,
y_left= 0x45,
x_right= 0x46,
y_right= 0x47,
up= 0x4A,
right= 0x4B,
down= 0x4C,
left= 0x4D,
l2= 0x4E,
r2= 0x4F,
l1= 0x50,
r1= 0x51,
triangle= 0x52,
circle= 0x53,
cross= 0x54,
square= 0x55)
class PSPNxV4(MindSensorI2CS):
def __init__(self, port, addr=0x01):
I2CS.__init__(self, port, addr)
self.command = 0x49
class AbsoluteIMU(LegoSensor):
# Is this too tricky to create property?
def __init__(self, port=-1):
LegoSensor.__init__(self, port, name='ms-absolute-imu')
self._mode = ''
@property
def version(self):
return self.fw_version
@property
def compass_cal_start(self):
self.write_value('command', 'BEGIN-COMP-CAL')
@property
def compass_cal_end(self):
self.write_value('command', 'END-COMP-CAL')
@property
def acc_2g(self):
self.write_value('command', 'ACCEL-2G')
@property
def acc_4g(self):
self.write_value('command', 'ACCEL-4G')
@property
def acc_8g(self):
self.write_value('command', 'ACCEL-8G')
@property
def acc_16g(self):
self.write_value('command', 'ACCEL-16G')
@property
def x_acc(self):
self.mode = 'ACCEL'
return self.value0
@property
def y_acc(self):
self.mode = 'ACCEL'
return self.value1
@property
def z_acc(self):
self.mode = 'ACCEL'
return self.value2
@property
def x_tilt(self):
self.mode = 'TILT'
return self.value0
@property
def y_tilt(self):
self.mode = 'TILT'
return self.value1
@property
def z_tilt(self):
self.mode = 'TILT'
return self.value2
@property
def x_raw_magnetic(self):
self.mode = 'MAG'
return self.value0
@property
def y_raw_magnetic(self):
self.mode = 'MAG'
return self.value1
@property
def z_raw_magnetic(self):
self.mode = 'MAG'
return self.value2
@property
def x_gyro(self):
self.mode = 'GYRO'
return self.value0
@property
def y_gyro(self):
self.mode = 'GYRO'
return self.value1
@property
def z_gyro(self):
self.mode = 'COMPASS'
return self.value0
@property
def compass(self):
self.mode = 'GYRO'
return self.value2
class MagicWand(MindSensorI2CS):
val = 0xff
# port = 1..4 , matching the EV3 input port where the magic wand is
# connected
def __init__(self, port, addr=0x38):
MindSensorI2CS.__init__(self, port, addr)
def put_data(self, v):
self.val = v
MindSensorI2CS.write_byte(self, v)
# turns all leds on
def led_all_on(self):
self.put_data(0x00)
# turns all leds off
def led_all_off(self):
self.put_data(0xff)
# turns a specific led on. leds are indexed 1..8
def led_on(self, num):
self.put_data(self.val & (0xff - (1 << (num - 1))))
# turns a specific led off. leds are indexed 1..8
def led_off(self, num):
self.put_data(self.val | (1 << (num - 1)))
#!/bin/bash
sudo iptables -P FORWARD ACCEPT
sudo iptables -A POSTROUTING -t nat -j MASQUERADE -s 10.42.0.0/24
...@@ -4,7 +4,7 @@ import socketserver ...@@ -4,7 +4,7 @@ import socketserver
import socket import socket
import os import os
import sys import sys
import ev3dev.ev3 as ev3 import ev3dev as ev3
if len(sys.argv) != 2: if len(sys.argv) != 2:
def eprint(*args, **kwargs): def eprint(*args, **kwargs):
...@@ -118,6 +118,8 @@ class TCPServer(socketserver.TCPServer): ...@@ -118,6 +118,8 @@ class TCPServer(socketserver.TCPServer):
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_address) self.socket.bind(self.server_address)
httpd = TCPServer(("", int(sys.argv[1])), Handler) httpd = TCPServer(("", int(float(sys.argv[1]))), Handler)
print ('EV3 ready.') print ('EV3 ready.')
print ('http://snap.berkeley.edu/snapsource/snap.html#open:http://localhost:1330/snap-ev3')
httpd.serve_forever() httpd.serve_forever()
import sys
print(sys.path)
sys.path.insert(0, "/ev3script")
print("AFTER")
print(sys.path)
import sys
sys.path.remove("/home/isaac/Documents/ev3script")
import sys
print (sys.path)
#!/bin/bash
#snap interface to the lego mindstorms robot installation
#Runs python script to append the required files to the pythonpath
python pathappend.py
ifconfig
sudo ifconfig enp0s26u1u4 10.42.0.1 up
ifconfig
#Runs the program
python snap-ev3.py
...@@ -50,5 +50,4 @@ os.system('scp listen.py %s@%s:' % (EV3_USER, EV3_IP)) ...@@ -50,5 +50,4 @@ os.system('scp listen.py %s@%s:' % (EV3_USER, EV3_IP))
#os.system('ssh %s@%s -- nohup python3 listen.py %d &' % (EV3_USER, EV3_IP, EV3_PORT)) #os.system('ssh %s@%s -- nohup python3 listen.py %d &' % (EV3_USER, EV3_IP, EV3_PORT))
httpd = TCPServer(("", SNAP_PORT), Handler) httpd = TCPServer(("", SNAP_PORT), Handler)
print "http://snap.berkeley.edu/snapsource/snap.html#open:http://localhost:1330/snap-ev3"
httpd.serve_forever() httpd.serve_forever()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment