LightSensor¶
__init__(self, position=(0, 0), name='light', color_sensitivity=None, **kwargs)
special
¶
A light sensor for sensing bulbs.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
position |
Tuple[int, int] |
the position of the sensor in centimeters relative to the center of the robot. |
(0, 0) |
name |
str |
the name of the device |
'light' |
color_sensitivity |
Color |
the name of the color that the sensor is sensitive to. None means that it is sensitive to all colors. |
None |
Source code in robots/devices/lightsensors.py
def __init__(self, position=(0, 0), name="light",
color_sensitivity=None, **kwargs):
"""
A light sensor for sensing bulbs.
Args:
position (Tuple[int, int]): the position of the
sensor in centimeters relative to the center
of the robot.
name (str): the name of the device
color_sensitivity (Color): the name of the color
that the sensor is sensitive to. None means
that it is sensitive to all colors.
"""
config = {
"position": position,
"name": name,
"color_sensitivity": color_sensitivity,
}
config.update(kwargs)
self._watcher = None
self.robot = None
self.initialize()
self.from_json(config)
draw(self, backend)
¶
Draw the device on the backend.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
backend |
Backend |
an aitk drawing backend |
required |
Source code in robots/devices/lightsensors.py
def draw(self, backend):
"""
Draw the device on the backend.
Args:
backend (Backend): an aitk drawing backend
"""
backend.lineWidth(1)
backend.set_stroke_style(BLACK)
if self.color_sensitivity is not None:
backend.set_fill_style(self.color_sensitivity)
else:
backend.set_fill_style(YELLOW)
backend.draw_circle(self.position[0], self.position[1], 2)
from_json(self, config)
¶
Set the settings from a device config.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config |
dict |
a config dictionary |
required |
Source code in robots/devices/lightsensors.py
def from_json(self, config):
"""
Set the settings from a device config.
Args:
config (dict): a config dictionary
"""
valid_keys = set([
"position", "name", "class", "color_sensitivity"
])
self.verify_config(valid_keys, config)
if "name" in config:
self.name = config["name"]
if "color_sensitivity" in config:
if config["color_sensitivity"] is not None:
self.color_sensitivity = Color(config["color_sensitivity"])
else:
self.color_sensitivity = None
config["color_sensitivity"] = self.color_sensitivity
if "position" in config:
self.position = config["position"]
# Get location of sensor, doesn't change once position is set:
self.dist_from_center = distance(0, 0, self.position[0], self.position[1])
self.dir_from_center = math.atan2(-self.position[0], self.position[1])
get_brightness(self)
¶
Get the light brightness reading from the sensor.
Source code in robots/devices/lightsensors.py
def get_brightness(self):
"""
Get the light brightness reading from the sensor.
"""
return self.value
get_widget(self, title='Light Sensor:')
¶
Return the dynamically updating widget.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
title |
str |
title of sensor |
'Light Sensor:' |
Source code in robots/devices/lightsensors.py
def get_widget(self, title="Light Sensor:"):
"""
Return the dynamically updating widget.
Args:
title (str): title of sensor
"""
from ..watchers import AttributesWatcher
if self.robot is None or self.robot.world is None:
print("ERROR: can't watch until added to robot, and robot is in world")
return None
if self._watcher is None:
self._watcher = AttributesWatcher(
self, "name", "value", title=title, labels=["Name:", "Light:"]
)
self.robot.world._watchers.append(self._watcher)
return self._watcher.widget
initialize(self)
¶
Internal method to set all settings to default values.
Source code in robots/devices/lightsensors.py
def initialize(self):
"""
Internal method to set all settings to default values.
"""
self.type = "light"
self.name = "light"
self.color_sensitivity = None
self.value = 0.0
# FIXME: add to config
self.multiplier = 1000 # CM
self.position = [0, 0]
self.dist_from_center = distance(0, 0, self.position[0], self.position[1])
self.dir_from_center = math.atan2(-self.position[0], self.position[1])
set_position(self, position)
¶
Set the position of the light sensor with respect to the center of the robot.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
position |
List[int, int] |
represents [x, y] in CM from center of robot |
required |
Source code in robots/devices/lightsensors.py
def set_position(self, position):
"""
Set the position of the light sensor with respect to the center of the
robot.
Args:
position (List[int, int]): represents [x, y] in CM from
center of robot
"""
if len(position) != 2:
raise ValueError("position must be of length two")
self.position = position
# Get location of sensor, doesn't change once position is set:
self.dist_from_center = distance(0, 0, self.position[0], self.position[1])
self.dir_from_center = math.atan2(-self.position[0], self.position[1])
to_json(self)
¶
Save the internal settings to a config dictionary.
Source code in robots/devices/lightsensors.py
def to_json(self):
"""
Save the internal settings to a config dictionary.
"""
config = {
"class": self.__class__.__name__,
"position": self.position,
"name": self.name,
"color_sensitivity": str(self.color_sensitivity) if self.color_sensitivity is not None else None,
}
return config
update(self, draw_list=None)
¶
Update the device.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
draw_list |
list |
optional. If given, then the method can add to it for drawing later. |
None |
Source code in robots/devices/lightsensors.py
def update(self, draw_list=None):
"""
Update the device.
Args:
draw_list (list): optional. If given, then the
method can add to it for drawing later.
"""
self.value = 0
# Location of sensor:
p = rotate_around(
self.robot.x,
self.robot.y,
self.dist_from_center,
self.robot.a + self.dir_from_center + math.pi / 2,
)
for bulb in self.robot.world._get_light_sources(all=True): # for each light source:
if bulb.robot is self.robot:
# You can't sense your own bulbs
continue
if ((self.color_sensitivity is not None) and
(self.color_sensitivity != bulb.color)):
# If sensitivity is set, if bulb doesn't match
# skip it
continue
z, brightness, light_color = ( # noqa: F841
bulb.z,
bulb.brightness,
bulb.color,
)
x, y = bulb.get_position(world=True)
angle = math.atan2(x - p[0], y - p[1])
dist = distance(x, y, p[0], p[1])
ignore_robots = []
if bulb.robot is not None:
ignore_robots.append(bulb.robot)
if self.robot is not None:
ignore_robots.append(self.robot)
hits = self.robot.cast_ray(p[0], p[1], angle, dist, ignore_robots=ignore_robots)
if self.robot.world.debug and draw_list is not None:
draw_list.append(("draw_circle", (p[0], p[1], 2), {}))
draw_list.append(("draw_circle", (x, y, 2), {}))
for hit in hits:
draw_list.append(("set_fill_style", (PURPLE,), {}))
draw_list.append(("draw_circle", (hit.x, hit.y, 2), {}))
if len(hits) == 0: # nothing blocking! we can see the light
# Maximum value of 100.0 with defaults:
self.value += (normal_dist(dist, 0, brightness) / math.pi) / brightness
self.value = min(self.value, 1.0)
if draw_list is not None:
draw_list.append(("strokeStyle", (PURPLE, 1), {}))
draw_list.append(("draw_line", (x, y, p[0], p[1]), {}))
watch(self, title='Light Sensor:')
¶
Create a dynamically updating view of this sensor.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
title |
str |
title of sensor |
'Light Sensor:' |
Source code in robots/devices/lightsensors.py
def watch(self, title="Light Sensor:"):
"""
Create a dynamically updating view
of this sensor.
Args:
title (str): title of sensor
"""
widget = self.get_widget(title=title)
return display(widget)