Skip to content

Commit

Permalink
Merge pull request #15 from AlexanderBarbie/main
Browse files Browse the repository at this point in the history
updated docker compose files and added github actions
  • Loading branch information
AlexanderBarbie authored Jun 11, 2024
2 parents a75eff0 + f5574b9 commit dae7743
Show file tree
Hide file tree
Showing 21 changed files with 609 additions and 300 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/build-arm64v8.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: PiCar-X Main Build

on: [push, pull_request]

jobs:
build:
runs-on: self-hosted, rpi4

steps:
- uses: actions/checkout@v2

- name: Build with Docker Compose
run: |
TAG=arm64v8 docker-compose -f docker-compose-core.yml build
# - name: Run pytest in Docker container
# run: |
# docker-compose -f docker-compose-core.yml run --rm app pytest

# - name: Start roslaunch in Docker container
# run: |
# docker-compose -f docker-compose-core.yml run --rm app roslaunch

- name: Push to Docker Hub
run: |
TAG=arm64v8 docker-compose -f docker-compose-core.yml push
29 changes: 25 additions & 4 deletions PiCar-X/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
FROM git.geomar.de:11411/open-source/arches/arches_core:1-0-0
ARG TAG=latest

FROM ${TAG:+${TAG}/}ros:noetic as rosnoetic
WORKDIR /root/catkin_ws/
RUN apt update -y \
&& apt-get install -y python3-pip python3-setuptools python3-catkin-tools wget unzip curl nano \
&& apt-get clean \
&& update-ca-certificates -f \
&& pip3 install --upgrade pip \
&& pip3 install pytest pytest-cov avro \
&& mkdir -p ./src/arches


FROM rosnoetic as adtf
RUN wget -c https://git.geomar.de/open-source/arches/arches_msgs/-/archive/master/arches_msgs-master.tar.gz -O - | tar -xz \
&& mv arches_msgs-master ./src/arches/arches_msgs \
&& wget -c https://git.geomar.de/open-source/arches/arches_core/-/archive/main/arches_core-main.tar.gz -O - | tar -xz \
&& mv arches_core-main ./src/arches/arches_core

RUN /bin/bash -c "source /opt/ros/noetic/setup.bash && catkin config --isolate-devel --install && catkin build" \
&& touch /root/.bashrc \
&& echo "source /opt/ros/noetic/setup.bash" >> /root/.bashrc

FROM adtf
ENV ASSET_NAME ''

COPY ./core ./src/core
COPY ./ros/picarx_msgs ./src/picarx_msgs

RUN pip3 install -e ./src/core/picarx \
&& /bin/bash -c "source /opt/ros/noetic/setup.bash && catkin build"

ENTRYPOINT [ "/root/catkin_ws/src/arches/arches_core/ENTRYPOINT.sh" ]

3 changes: 3 additions & 0 deletions PiCar-X/core/dtp/env/picarx-arm32v7.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ROS_MASTER_URI=http://picarx:11311
ROS_HOST_PORT=11311
TAG=arm64v8
3 changes: 3 additions & 0 deletions PiCar-X/core/dtp/env/picarx-arm64v8.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ROS_MASTER_URI=http://picarx:11311
ROS_HOST_PORT=11311
TAG=arm64v8
38 changes: 38 additions & 0 deletions PiCar-X/core/picarx/src/picarx/drivers/tests/unittests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import pytest
from picarx.interfaces.actuators import TravelDirection, MotorSide
from picarx.drivers.dcmotor import AbstractDCMotorDriver

class TestAbstractDCMotorDriver:
@pytest.fixture
def dcmotor(self):
return AbstractDCMotorDriver("test_motor", 1, 2, motor_side=MotorSide.LEFT)

def test_name(self, dcmotor):
assert dcmotor.name == "test_motor"

def test_direction_pin(self, dcmotor):
assert dcmotor.direction_pin == 1

def test_pwm_pin(self, dcmotor):
assert dcmotor.pwm_pin == {'channel': 2, 'i2c_port': '\dev\i2c-1'}

def test_motor_side(self, dcmotor):
assert dcmotor.motor_side == MotorSide.LEFT

def test_direction(self, dcmotor):
assert dcmotor.direction == TravelDirection.FORWARD

def test_speed(self, dcmotor):
assert dcmotor.speed is None

def test_drive_with_speed(self, dcmotor):
dcmotor.drive_with_speed(50)
assert dcmotor.speed == 50

def test_start(self, dcmotor):
with pytest.raises(NotImplementedError):
dcmotor.start()

def test_stop(self, dcmotor):
with pytest.raises(NotImplementedError):
dcmotor.stop()
2 changes: 1 addition & 1 deletion PiCar-X/core/picarx/src/picarx/gpio.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ def start_watchdog(self):
self.running = True
try:
while reactor.running:
time.sleep(1)
time.sleep(1/50)
finally:
observer.stop()
observer.join()
Expand Down
53 changes: 53 additions & 0 deletions PiCar-X/core/picarx/tests/test_gpio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import unittest
from unittest.mock import patch, mock_open, MagicMock, call
import builtins
import os
import weakref
from picarx.gpio import GPIO, Value, Pin, Direction, Edge, Active
from twisted.internet import reactor
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class TestGPIO(unittest.TestCase):

@patch('builtins.open', new_callable=mock_open)
@patch.object(reactor, 'callInThread')
@patch.object(FileSystemEventHandler, 'on_modified')
@patch('os.path.exists', return_value=True)
@patch('weakref.finalize', return_value=MagicMock())
def test_set_value_gpio(self, mock_weakref, mock_os, mock_watchdog, mock_reactor, mock_file):
pin= GPIO().setup(17, direction=Direction.OUT, callback=None)
pin.value = Value.HIGH.value
mock_file.assert_called_with(Pin.SYSFS_GPIO_PIN_VALUE.format(17), 'w')
mock_file().write.assert_called_with(str(1))
mock_os.assert_called_once()
mock_weakref.assert_called_once()

@patch('builtins.open', new_callable=mock_open)
@patch.object(reactor, 'callInThread')
@patch.object(FileSystemEventHandler, 'on_modified')
@patch('os.path.exists', return_value=True)
@patch('weakref.finalize', return_value=MagicMock())
def test_set_value_pin(self, mock_weakref, mock_os, mock_watchdog, mock_reactor, mock_file):
pin = Pin(17)
pin.value = 1
mock_file.assert_called_with(Pin.SYSFS_GPIO_PIN_VALUE.format(17), 'w')
mock_file().write.assert_called_with(str(1))
mock_os.assert_called_once()
mock_weakref.assert_called_once()

@patch('builtins.open', new_callable=mock_open, read_data="1")
@patch.object(reactor, 'callInThread')
@patch.object(FileSystemEventHandler, 'on_modified')
@patch('os.path.exists', return_value=True)
@patch('weakref.finalize', return_value=MagicMock())
def test_read_value_pin(self, mock_weakref, mock_os, mock_watchdog, mock_reactor, mock_file):
pin = Pin(17)
self.assertEqual(pin.value, 1)
mock_file.assert_called_with(Pin.SYSFS_GPIO_PIN_VALUE.format(17), 'r')
mock_os.assert_called_once()
mock_weakref.assert_called_once()


if __name__ == '__main__':
unittest.main()
10 changes: 10 additions & 0 deletions PiCar-X/docker-compose-core.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
picarx-core-build:
build:
dockerfile: Dockerfile
context: .
image: abarbie/picarx:${TAG}

networks:
default:
driver: bridge
79 changes: 47 additions & 32 deletions PiCar-X/docker-compose-ds.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
version: '3'

services:
picarx-dt:
build: .
image: picarx/core:latest
image: abarbie/picarx:${TAG}
environment:
- ROS_HOSTNAME=picarx-dt
- ROS_MASTER_URI=http://picarx-dt:11313
Expand All @@ -12,8 +10,12 @@ services:
ports:
- 11313:11313
command: roscore -p 11313
networks:
- picarx
healthcheck:
test: [ "CMD-SHELL", "curl $${ROS_MASTER_URI} || exit 1" ]
interval: 5s
timeout: 1s
retries: 5
start_period: 1s

mosquitto:
container_name: mqtt-server
Expand All @@ -23,14 +25,16 @@ services:
volumes:
- ./core/dtp/config:/root/catkin_ws/mosquitto
command: mosquitto -c /root/catkin_ws/mosquitto/mosquitto.conf -p 1883
networks:
- picarx
depends_on:
picarx-dt:
condition: service_healthy

picarx-gazebo:
build:
context: .
dockerfile: ./simulation/Dockerfile
image: picarx/picarx-gazebo:latest
context: Dockerfile
dockerfile: ./simulation
target: desktop
image: abarbie/picarx/picarx-gazebo:${TAG}
env_file:
- ./core/dtp/env/simulation.env
environment:
Expand All @@ -41,33 +45,42 @@ services:
volumes:
- ./core:/root/catkin_ws/src/core
- ./simulation:/root/catkin_ws/src/simulation
command: /bin/bash -c "/root/catkin_ws/docker/wfi/wait-for-it-master/wait-for-it.sh $${ROS_MASTER_URI} -- roslaunch picarx_gazebo picarx-world.launch & /root/catkin_ws/docker/wfi/wait-for-it-master/wait-for-it.sh $${ROS_MASTER_URI} -- roslaunch picarx_control picarx_control.launch"
networks:
- picarx
command: /bin/bash -c "roslaunch picarx_gazebo picarx-world.launch & roslaunch picarx_control picarx_control.launch"
depends_on:
- picarx-dt
picarx-dt:
condition: service_healthy

shadow-dt:
image: picarx/core:latest
image: abarbie/picarx:${TAG}
env_file:
- ./core/dtp/env/picarx-dt.env
tty: true
command: /bin/bash -c "/root/catkin_ws/docker/wfi/wait-for-it-master/wait-for-it.sh $${ROS_MASTER_URI} -- roslaunch arches_core digitalshadow_dt.launch"
networks:
- picarx
command: /bin/bash -c "roslaunch arches_core digitalshadow_dt.launch"
depends_on:
picarx-dt:
condition: service_healthy

mqtt-dt:
image: git.geomar.de:11411/open-source/arches/arches_mqtt_bridge:latest
image: abarbie/picarx/arches-mqtt-bridge:${TAG}
build:
dockerfile: Dockerfile-arches-mqtt-bridge
context: ./ros
args:
- TAG=${TAG}
env_file:
- ./core/dtp/env/picarx-dt.env
tty: true
command: /bin/bash -c "/root/catkin_ws/docker/wfi/wait-for-it-master/wait-for-it.sh $${ROS_MASTER_URI} -- roslaunch arches_mqtt_bridge dt_client.launch host:=mqtt-server"
networks:
- picarx
command: /bin/bash -c "roslaunch arches_mqtt_bridge pt_client.launch host:=mqtt-server"
depends_on:
picarx:
condition: service_healthy

ackermann_skill-dt:
build: ./ros/skills/ackermann_drive
image: picarx/skills/ackermann_drive:latest
image: abarbie/picarx/skills/ackermann_drive:${TAG}
build:
dockerfile: Dockerfile
context: ./ros/skills/ackermann_drive
args:
- TAG=${TAG}
env_file:
- ./core/dtp/env/picarx-dt.env
tty: true
Expand All @@ -77,23 +90,25 @@ services:
- /dev/i2c-0:/dev/i2c-0
- ./core:/root/catkin_ws/src/core
- ./ros/skills/ackermann_drive:/root/catkin_ws/src/skills/ackermann_drive
command: /bin/bash -c "/root/catkin_ws/docker/wfi/wait-for-it-master/wait-for-it.sh $${ROS_MASTER_URI} -- roslaunch picarx_ackermann_drive ackermann_skill.launch"
networks:
- picarx
command: /bin/bash -c "roslaunch picarx_ackermann_drive ackermann_skill.launch"
depends_on:
picarx-dt:
condition: service_healthy

drive_monitor:
build: ./ros/skills/ackermann_drive
image: picarx/skills/ackermann_drive:latest
image: abarbie/picarx/skills/ackermann_drive:${TAG}
env_file:
- ./core/dtp/env/picarx-dt.env
tty: true
privileged: true
volumes:
- ./core:/root/catkin_ws/src/core
- ./ros/skills/ackermann_drive:/root/catkin_ws/src/skills/ackermann_drive
command: /bin/bash -c "/root/catkin_ws/docker/wfi/wait-for-it-master/wait-for-it.sh $${ROS_MASTER_URI} -- roslaunch picarx_ackermann_drive monitor_ds.launch"
networks:
- picarx
command: /bin/bash -c "roslaunch picarx_ackermann_drive monitor_ds.launch"
depends_on:
picarx-dt:
condition: service_healthy

networks:
picarx:
Expand Down
Loading

0 comments on commit dae7743

Please sign in to comment.