From 8b0cbdc57af1d27faa9579b20c5fecf89b16b78a Mon Sep 17 00:00:00 2001 From: Piv Date: Tue, 8 Sep 2020 19:28:53 +0930 Subject: [PATCH 01/12] Start adding esp32 sketch --- esp32/README.md | 23 +++++++++++++++++++++++ esp32/esp.ino | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 esp32/README.md create mode 100644 esp32/esp.ino diff --git a/esp32/README.md b/esp32/README.md new file mode 100644 index 0000000..051ac24 --- /dev/null +++ b/esp32/README.md @@ -0,0 +1,23 @@ +This module includes an arduino sketch designed to run on the ESP32. + +The sketch takes simple input from serial (ESP32 microusb port), and converts the input to a duty cycle that can be used on servos. + +The protocol specification is as follows, assuming an array of bytes: + + +| Byte Number | Value Description | +| :---------- | ----------: | +| 0 | 0 if Calibrating a servo. Higher values indicates channel number to set duty cycle on. | +| 1 | If byte 0 = 0: number of servos to calibrate. Else, the new duty cycle value for the channel specified in byte 0. | + +The table below describes the byte format for calibrating a servo. This array of bytes can be repeated for the given number of servos in byte 1: + +| Byte Number | Value Description | +| :---------- | ----------: | +| 0 | Servo channel to set (this will be byte 0 when setting duty cycle, so don't use 0). | +| 1 | The pin number to setup | +| 2 | The frequency for the pin | + +The min/max pulse widths are hardcoded to 1000us/2000us respectively. + +At the end of each loop, the entire array will be read, to flush any data that may cause issues later. \ No newline at end of file diff --git a/esp32/esp.ino b/esp32/esp.ino new file mode 100644 index 0000000..428916b --- /dev/null +++ b/esp32/esp.ino @@ -0,0 +1,37 @@ +#include +#include "Servo.h" + +std::map servos; + +void setup() +{ + Serial.begin(115200); +} + +void setupServos(uint8_t *calibrationValues, uint8_t size) +{ + // We assume there are 3 bytes per servo. Ignore if there aren't. + if (size % 3 == 0) + { + for (int i = 0; i < size; i += 3) + { + servos.insert(std::make_pair(calibrationValues[i], new Servo())) + } + } +} + +void loop() +{ + uint8_t *header = new uint8_t[2]; + Serial.readBytes(header, 2); + + if (header[0] == 0) + { + uint8_t *calibration = new uint8_t[3 * header[1]]; + Serial.readBytes(calibration, header[1]); + setupServos(); + delete calibration; + } + + delete header; +} \ No newline at end of file From 756e2741bed42f726b2f8d25eeb4f430346232b6 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Tue, 8 Sep 2020 21:01:44 +0930 Subject: [PATCH 02/12] Move to platformIO for ESP32 --- esp32/.gitignore | 5 ++++ esp32/.vscode/extensions.json | 7 +++++ esp32/include/README | 39 ++++++++++++++++++++++++++++ esp32/lib/README | 46 +++++++++++++++++++++++++++++++++ esp32/platformio.ini | 15 +++++++++++ esp32/{esp.ino => src/main.cpp} | 8 +++--- esp32/test/README | 11 ++++++++ 7 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 esp32/.gitignore create mode 100644 esp32/.vscode/extensions.json create mode 100644 esp32/include/README create mode 100644 esp32/lib/README create mode 100644 esp32/platformio.ini rename esp32/{esp.ino => src/main.cpp} (81%) create mode 100644 esp32/test/README diff --git a/esp32/.gitignore b/esp32/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/esp32/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/esp32/.vscode/extensions.json b/esp32/.vscode/extensions.json new file mode 100644 index 0000000..0f0d740 --- /dev/null +++ b/esp32/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/esp32/include/README b/esp32/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/esp32/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/esp32/lib/README b/esp32/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/esp32/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/esp32/platformio.ini b/esp32/platformio.ini new file mode 100644 index 0000000..5a014b7 --- /dev/null +++ b/esp32/platformio.ini @@ -0,0 +1,15 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32doit-devkit-v1] +platform = espressif32 +board = esp32doit-devkit-v1 +framework = arduino +lib_deps = roboticsbrno/ServoESP32@^1.0.3 diff --git a/esp32/esp.ino b/esp32/src/main.cpp similarity index 81% rename from esp32/esp.ino rename to esp32/src/main.cpp index 428916b..a01dbc1 100644 --- a/esp32/esp.ino +++ b/esp32/src/main.cpp @@ -1,3 +1,5 @@ +#include + #include #include "Servo.h" @@ -8,14 +10,14 @@ void setup() Serial.begin(115200); } -void setupServos(uint8_t *calibrationValues, uint8_t size) +void setupServos(uint8_t size, uint8_t *calibrationValues) { // We assume there are 3 bytes per servo. Ignore if there aren't. if (size % 3 == 0) { for (int i = 0; i < size; i += 3) { - servos.insert(std::make_pair(calibrationValues[i], new Servo())) + servos.insert(std::make_pair(calibrationValues[i], new Servo())); } } } @@ -29,7 +31,7 @@ void loop() { uint8_t *calibration = new uint8_t[3 * header[1]]; Serial.readBytes(calibration, header[1]); - setupServos(); + setupServos(header[1], calibration); delete calibration; } diff --git a/esp32/test/README b/esp32/test/README new file mode 100644 index 0000000..b94d089 --- /dev/null +++ b/esp32/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html From b72781e32295c10dcb511f218c09ae141706ed51 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Tue, 8 Sep 2020 21:23:21 +0930 Subject: [PATCH 03/12] Initial PlatformIO code. --- esp32/README.md | 1 - esp32/src/main.cpp | 32 ++++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/esp32/README.md b/esp32/README.md index 051ac24..a206c6b 100644 --- a/esp32/README.md +++ b/esp32/README.md @@ -16,7 +16,6 @@ The table below describes the byte format for calibrating a servo. This array of | :---------- | ----------: | | 0 | Servo channel to set (this will be byte 0 when setting duty cycle, so don't use 0). | | 1 | The pin number to setup | -| 2 | The frequency for the pin | The min/max pulse widths are hardcoded to 1000us/2000us respectively. diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp index a01dbc1..e189f14 100644 --- a/esp32/src/main.cpp +++ b/esp32/src/main.cpp @@ -3,7 +3,14 @@ #include #include "Servo.h" -std::map servos; +// Min/max widths, used to calculate min/max duty cycles. +#define MIN_PULSE_WIDTH 1000 +#define MAX_PULSE_WIDTH 2000 + +#define MIN_ANGLE 0 +#define MAX_ANGLE 255 + +std::map servos; void setup() { @@ -15,13 +22,22 @@ void setupServos(uint8_t size, uint8_t *calibrationValues) // We assume there are 3 bytes per servo. Ignore if there aren't. if (size % 3 == 0) { - for (int i = 0; i < size; i += 3) + for (int i = 0; i < size; i += 2) { - servos.insert(std::make_pair(calibrationValues[i], new Servo())); + Servo *newServo = new Servo(); + newServo->attach(calibrationValues[i + 1], calibrationValues[i], MIN_ANGLE, MAX_ANGLE, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); + servos.insert(std::make_pair(calibrationValues[i], newServo)); } } } +void modifyServo(uint8_t channel, uint8_t newAngle) +{ + if(servos.count(channel) > 0){ + servos[channel]->write(newAngle); + } +} + void loop() { uint8_t *header = new uint8_t[2]; @@ -29,11 +45,15 @@ void loop() if (header[0] == 0) { - uint8_t *calibration = new uint8_t[3 * header[1]]; + uint8_t *calibration = new uint8_t[2 * header[1]]; Serial.readBytes(calibration, header[1]); setupServos(header[1], calibration); - delete calibration; + delete [] calibration; + } + else + { + modifyServo(header[0], header[1]); } - delete header; + delete [] header; } \ No newline at end of file From 45ba68f4aadd9743d449e90a31b8ce4c133bcfd7 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Tue, 8 Sep 2020 21:40:09 +0930 Subject: [PATCH 04/12] Add esp32 build to gitlab ci --- .gitlab-ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 92c1571..95004c1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,6 +15,14 @@ build_pycar_docker: - echo ${DOCKER_PASSWORD} | docker login vato.ddns.net:8083 --username ${DOCKER_USERNAME} --password-stdin - docker build -f pycar/Dockerfile --build-arg PYPI_USERNAME=${PYPI_USERNAME} --build-arg PYPI_PASSWORD=${PYPI_PASSWORD} -t vato.ddns.net:8082/pycar:latest pycar +build_esp32: + image: vato.ddns.net:8083/shaguarger/platformio + stage: build + script: + - cd esp32 + - platformio ci --board=env:esp32doit-devkit-v1 + - cd .. + deploy_pycar: image: vato.ddns.net:8083/python-infra:buster stage: deploy From 1f4ed129f1919bc9372ae484716ff799f5a7e41c Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Tue, 8 Sep 2020 21:44:11 +0930 Subject: [PATCH 05/12] Fix board in ci build --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 95004c1..1582510 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,7 +20,7 @@ build_esp32: stage: build script: - cd esp32 - - platformio ci --board=env:esp32doit-devkit-v1 + - platformio ci --board=esp32doit-devkit-v1 - cd .. deploy_pycar: From 8fafc46ec4d53f413f72711bb90e577626d21e53 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Tue, 8 Sep 2020 21:46:50 +0930 Subject: [PATCH 06/12] Add src variable to ci build --- .gitlab-ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1582510..f67d11f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,9 +19,8 @@ build_esp32: image: vato.ddns.net:8083/shaguarger/platformio stage: build script: - - cd esp32 - platformio ci --board=esp32doit-devkit-v1 - - cd .. + variables: {PLATFORMIO_CI_SRC: 'esp32/src/main.cpp'} deploy_pycar: image: vato.ddns.net:8083/python-infra:buster From 1276947aa462f91516d0e29fb4bc4f11b4a98af5 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Tue, 8 Sep 2020 21:51:25 +0930 Subject: [PATCH 07/12] Change working directory for library dependencies in ci build. --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f67d11f..cb07873 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,8 +19,9 @@ build_esp32: image: vato.ddns.net:8083/shaguarger/platformio stage: build script: + - cd esp32 - platformio ci --board=esp32doit-devkit-v1 - variables: {PLATFORMIO_CI_SRC: 'esp32/src/main.cpp'} + variables: {PLATFORMIO_CI_SRC: 'src/main.cpp'} deploy_pycar: image: vato.ddns.net:8083/python-infra:buster From fc3607316dabe24dab1bf9a0b582280321fce86e Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Tue, 8 Sep 2020 22:03:54 +0930 Subject: [PATCH 08/12] Fix script to point to platformio project file. --- .gitlab-ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cb07873..01469c4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,9 +19,7 @@ build_esp32: image: vato.ddns.net:8083/shaguarger/platformio stage: build script: - - cd esp32 - - platformio ci --board=esp32doit-devkit-v1 - variables: {PLATFORMIO_CI_SRC: 'src/main.cpp'} + - platformio ci --project-conf esp32/platformio.ini esp32 deploy_pycar: image: vato.ddns.net:8083/python-infra:buster From c97df7bbaa2ea2cd177b8101b58bc7d8a76b8720 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Sat, 12 Sep 2020 15:49:01 +0930 Subject: [PATCH 09/12] Add Esp32 (serial) vehicle to pycar --- .vscode/launch.json | 3 +- esp32/README.md | 8 +++- .../src/car/control/gpio/abstract_vehicle.py | 26 ++++++++++++ pycar/src/car/control/gpio/factory.py | 15 +++++-- pycar/src/car/control/gpio/mockvehicle.py | 27 +++--------- .../gpio/recording_vehicle_decorator.py | 21 ++-------- pycar/src/car/control/gpio/serial_vehicle.py | 42 +++++++++++++++++++ pycar/src/car/control/gpio/vehicle.py | 3 +- 8 files changed, 99 insertions(+), 46 deletions(-) create mode 100644 pycar/src/car/control/gpio/abstract_vehicle.py create mode 100644 pycar/src/car/control/gpio/serial_vehicle.py diff --git a/.vscode/launch.json b/.vscode/launch.json index 3704543..eaf57ba 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,8 @@ "request": "launch", "module": "car", "env": { - "CAR_VEHICLE": "CAR_MOCK", + "CAR_VEHICLE": "VEHICLE_MOCK", + // "CAR_VEHICLE": "VEHICLE_SERIAL", // "CAR_LIDAR": "/dev/tty.usbserial-0001", "CAR_LIDAR": "LIDAR_MOCK" } diff --git a/esp32/README.md b/esp32/README.md index a206c6b..2f54f1b 100644 --- a/esp32/README.md +++ b/esp32/README.md @@ -10,6 +10,8 @@ The protocol specification is as follows, assuming an array of bytes: | 0 | 0 if Calibrating a servo. Higher values indicates channel number to set duty cycle on. | | 1 | If byte 0 = 0: number of servos to calibrate. Else, the new duty cycle value for the channel specified in byte 0. | +When setting the duty cycle, the current min angle is 0, and the max angle is 255, which allows the entire byte to be used for setting the duty cycle. + The table below describes the byte format for calibrating a servo. This array of bytes can be repeated for the given number of servos in byte 1: | Byte Number | Value Description | @@ -19,4 +21,8 @@ The table below describes the byte format for calibrating a servo. This array of The min/max pulse widths are hardcoded to 1000us/2000us respectively. -At the end of each loop, the entire array will be read, to flush any data that may cause issues later. \ No newline at end of file +At the end of each loop, the entire array will be read, to flush any data that may cause issues later. + +Upcoming (TODO): +- Use bit shift to allow 12 bits to be used for the duty cycle range, as there can only be a max of 16 channels anyway (4 bits). +- Consider protobuf or msgpack for serialisation format, for more advanced use cases, and more maintainable communication formats (currently changing the message format will require changes to the entire protocol) \ No newline at end of file diff --git a/pycar/src/car/control/gpio/abstract_vehicle.py b/pycar/src/car/control/gpio/abstract_vehicle.py new file mode 100644 index 0000000..8028d85 --- /dev/null +++ b/pycar/src/car/control/gpio/abstract_vehicle.py @@ -0,0 +1,26 @@ +from abc import ABC, abstractmethod, abstractproperty + +class AbstractVehicle(ABC): + + @abstractmethod + @property + def throttle(self): + pass + + @abstractmethod + @throttle.setter + def throttle(self): + pass + + @abstractmethod + @property + def steering(self): + pass + + @abstractmethod + @steering.setter + def throttle(self): + pass + + def stop(self): + pass \ No newline at end of file diff --git a/pycar/src/car/control/gpio/factory.py b/pycar/src/car/control/gpio/factory.py index 505e2aa..df9a795 100644 --- a/pycar/src/car/control/gpio/factory.py +++ b/pycar/src/car/control/gpio/factory.py @@ -1,18 +1,25 @@ +from car.control.gpio.abstract_vehicle import AbstractVehicle +from car.control.gpio.serial_vehicle import SerialVehicle from .mockvehicle import MockVehicle import os -def get_vehicle(motor_pin=19, steering_pin=18): +# TODO: Remove need for motor/steering pin, instead retrieve from env variable. +# TODO: Dependency injectino in python? +def get_vehicle(motor_pin=19, steering_pin=18) -> AbstractVehicle: ENV_CAR = None if 'CAR_VEHICLE' not in os.environ else os.environ['CAR_VEHICLE'] - if ENV_CAR == "CAR_2D": + if ENV_CAR == "VEHICLE_2D": try: from .vehicle import Vehicle return Vehicle(motor_pin, steering_pin) except ImportError: print( 'Could not import CAR_2D vehicle. Have you installed the GPIOZERO package?') - elif ENV_CAR == "CAR_MOCK": - return MockVehicle(motor_pin, steering_pin) + elif ENV_CAR == "VEHICLE_MOCK": + return MockVehicle() + elif ENV_CAR == "VEHICLE_SERIAL": + # TODO: Pins in environment variables. + return SerialVehicle() else: print('No valid vehicle found. Have you set the CAR_VEHICLE environment variable?') return None diff --git a/pycar/src/car/control/gpio/mockvehicle.py b/pycar/src/car/control/gpio/mockvehicle.py index b5a08d3..79d37dd 100644 --- a/pycar/src/car/control/gpio/mockvehicle.py +++ b/pycar/src/car/control/gpio/mockvehicle.py @@ -1,10 +1,11 @@ -# A dummy vehicle class to use when -class MockVehicle: - def __init__(self, motor_pin=19, servo_pin=18): - self.motor_pin = motor_pin - self.steering_pin = servo_pin +# A dummy vehicle class to use when testing/not connected to a real device. +from car.control.gpio.abstract_vehicle import AbstractVehicle + + +class MockVehicle(AbstractVehicle): + def __init__(self): print('Using Mock Vehicle') @property @@ -23,21 +24,5 @@ class MockVehicle: def steering(self, value): self._steering = value - @property - def motor_pin(self): - return self._motor_pin - - @motor_pin.setter - def motor_pin(self, value): - self._motor_pin = value - - @property - def steering_pin(self): - return self._steering_pin - - @steering_pin.setter - def steering_pin(self, value): - self._steering_pin = value - def stop(self): self.throttle = 0 diff --git a/pycar/src/car/control/gpio/recording_vehicle_decorator.py b/pycar/src/car/control/gpio/recording_vehicle_decorator.py index 1b839f6..1dc3784 100644 --- a/pycar/src/car/control/gpio/recording_vehicle_decorator.py +++ b/pycar/src/car/control/gpio/recording_vehicle_decorator.py @@ -1,11 +1,12 @@ import datetime +from .abstract_vehicle import AbstractVehicle -class VehicleRecordingDecorator: +class VehicleRecordingDecorator(AbstractVehicle): def __init__(self, vehicle): """ A decorator for a vehicle object to record the changes in steering/throttle. - This will be recorded to memory, and will save to the given file when save is called. + This will be recorded to memory, and will save to the given file when save_data is called. Parameters ---------- @@ -66,21 +67,5 @@ class VehicleRecordingDecorator: 's,' + str(value) + ',' + datetime.datetime.now().isoformat(sep=' ', timespec='seconds')) self._vehicle.steering = value - @property - def motor_pin(self): - return self._vehicle.motor_pin - - @motor_pin.setter - def motor_pin(self, value): - self._vehicle.motor_pin = value - - @property - def steering_pin(self): - return self._vehicle.steering_pin - - @steering_pin.setter - def steering_pin(self, value): - self._vehicle.steering_pin = value - def stop(self): self.throttle = 0 diff --git a/pycar/src/car/control/gpio/serial_vehicle.py b/pycar/src/car/control/gpio/serial_vehicle.py new file mode 100644 index 0000000..48dad07 --- /dev/null +++ b/pycar/src/car/control/gpio/serial_vehicle.py @@ -0,0 +1,42 @@ +from .abstract_vehicle import AbstractVehicle +from serial import Serial + +STEERING_CHANNEL = 1 +THROTTLE_CHANNEL = 2 + + +class SerialVehicle(AbstractVehicle): + + def __init__(self, serial_port='/dev/ttyUSB0', steering_pin=12, throttle_pin=14): + self.serial_port = Serial(port=serial_port, baudrate=115200) + + # Initialise the channels and pins on esp32. + self._init_esp32_pwm(steering_pin, throttle_pin) + self.throttle = 0 + self.steering = 0 + + @property + def throttle(self) -> float: + return self.throttle + + @throttle.setter + def throttle(self, new_throttle: float): + self.throttle = new_throttle + self._set_servo_value(THROTTLE_CHANNEL, new_throttle) + + @property + def steering(self) -> float: + return self.steering + + @steering.setter + def steering(self, new_steering: float): + self.steering = new_steering + self._set_servo_value(STEERING_CHANNEL, new_steering) + + def _set_servo_value(self, channel, value): + # Scale the value to a byte, as 0-255 is the angle range for the esp32 servo. + self.serial_port.write(bytes[channel, (value + 1) / 2 * 255]) + + def _init_esp32_pwm(self, steering_pin, throttle_pin): + self.serial_port.write(bytes([0, 2, STEERING_CHANNEL, + steering_pin, THROTTLE_CHANNEL, throttle_pin])) diff --git a/pycar/src/car/control/gpio/vehicle.py b/pycar/src/car/control/gpio/vehicle.py index 00d3de4..56fe093 100644 --- a/pycar/src/car/control/gpio/vehicle.py +++ b/pycar/src/car/control/gpio/vehicle.py @@ -1,3 +1,4 @@ +from .abstract_vehicle import AbstractVehicle from gpiozero import Servo, Device from gpiozero.pins.pigpio import PiGPIOFactory import subprocess @@ -29,7 +30,7 @@ def _is_pin_valid(pin): # two servos for controls (e.g. drone, dog) -class Vehicle: +class Vehicle(AbstractVehicle): def __init__(self, motor_pin=19, servo_pin=18): subprocess.call(['pigpiod']) Device.pin_factory = PiGPIOFactory() From cbe2a48f0c0cb1a58e284a1ca68d01a03aeef7d4 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Sat, 12 Sep 2020 16:25:43 +0930 Subject: [PATCH 10/12] Update other config files. --- .gitignore | 4 ++- .idea/codeStyles/Project.xml | 18 +++++++++++++ .idea/gradle.xml | 3 ++- SwiftyCar/Package.resolved | 50 ++++++++++++++++++++++++------------ 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index fa18d1a..a0581ec 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,6 @@ SwiftyCar/Sources/SwiftyCar/car xcuserdata/ .settings .project -.classpath \ No newline at end of file +.classpath + +.vscode/settings.json \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 681f41a..0d15693 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,5 +1,23 @@ + + + +