sets/city/cargo-train: Add speed control project.

This commit is contained in:
Laurens Valk
2021-11-12 16:28:22 +01:00
parent e2f22524bc
commit 9fd29435f1
3 changed files with 99 additions and 0 deletions
@@ -0,0 +1,49 @@
---
title: "Train speed control"
maintainer:
user: "pybricks"
name: "The Pybricks Team"
image:
local: "train-load.jpg"
video:
youtube: "Qc7sIkzEgIc"
description:
"Make a train drive at a constant speed, independent of load and battery
level."
building_instructions:
external:
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6245902.pdf
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6245905.pdf
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6245917.pdf
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6245924.pdf
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6245926.pdf
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6245931.pdf
code: "#program"
---
## Design modifications
Build any train using the standard instructions. Mount the
[color distance sensor][colordistancesensor] in the frame, as shown in the
video. Connect the motor to port A and connect the sensor to port B.
## Program
This program makes the train drive at a constant speed. It works by counting
the tracks using the Color and Distance Sensor. The motor "power" is
automatically increased if the counted position is below the target position,
and reduced if it is too far ahead. The target position steadily increases
over time. This makes the train follow the target at the same speed.
In this video, there's a white surface underneath the tracks. If your
background is different, you can change the reflection values
accordingly, as shown in the comments below. You could also adapt the script
so it responds to different colors instead of reflected light intensity.
{% include copy-code.html %}
```python
{% include_relative main.py %}
```
[colordistancesensor]: https://docs.pybricks.com/en/latest/pupdevices/colordistancesensor.html
@@ -0,0 +1,50 @@
from pybricks.pupdevices import DCMotor, ColorDistanceSensor
from pybricks.tools import StopWatch
from pybricks.parameters import Port
# Initialize the motor and the sensor.
motor = DCMotor(Port.A)
sensor = ColorDistanceSensor(Port.B)
# These are the sensor reflection values in this setup.
# Adapt them to match your ambient light conditions.
LIGHT = 57
DARK = 16
# Threshold values. We add a bit of hysteresis to make
# sure we skip extra changes on the edge of each track.
hysteresis = (LIGHT - DARK) / 4
threshold_up = (LIGHT + DARK) / 2 + hysteresis
threshold_down = (LIGHT + DARK) / 2 - hysteresis
# Initial position state.
on_track = True
position = 0
# Desired drive speed in mm per second.
SPEED = 300
# It's two studs (16 mm) for each position increase.
MM_PER_COUNT = 16
# Start a timer.
watch = StopWatch()
while True:
# Measure the reflection.
reflection = sensor.reflection()
# If the reflection exceeds the threshold, increment position.
if (reflection > threshold_up and on_track) or (reflection < threshold_down and not on_track):
on_track = not on_track
position += 1
# Compute the target position based on the time.
target_count = watch.time() / 1000 * SPEED / MM_PER_COUNT
# The duty cycle is the position error times a constant gain.
duty = 2*(target_count - position)
# Apply the duty cycle.
motor.dc(duty)
Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB