creating_a_package - autonohm/georg_at_home GitHub Wiki
- 00 Setup
- 01 Das erste Paket
- 02 verwaltetes Starten
- 03 Extra Software
- 04 Eigener Code
- 05 Eigene Launchfile
- 06 Pushen auf github
- Commits aus altem Repo übernehmen
- Tipps
In diesem Tutorial wird schritt für schritt ein Beispiel Paket für georg_at_home erstellt.
Es wird davon ausgegangen, dass eine Linux-Umgebung (zb Ubuntu oder WSL) mit funktionierender Docker Installation verwendet wird.
Zudem sollen die Paketesudo apt install nano make git tree lazygit
und das PaketghAnleitungℹ️ Lazygit auf Ubuntu ≤ 25.04 → Anleitung
Lazygit ist optional - wird verwendet weil Git commands diktieren/merken kacke ist :(
Note
Alle Schritte sind im pkg_tutorial Branch dieses Repos einsehbar.
Zunächst holen wir uns das Repo:
cdgerne zuvor in einen beliebigen Ordner, je nach deiner Organisationsweise.
git clone https://github.com/autonohm/georg_at_home.git
cd georg_at_home
Dann müssen wir git sagen wer wir sind, dafür:
git config --global user.name "Sam 'snaens' Pelz"
git config --global user.email "[email protected]"
Name und Email natürlich personalisieren!
Das
--globalkann weggelassen werden. Damit gelten die Änderungen nur für dieses Repo / diesen Ordner.
Und für später werden wir die push-Berechtigungen auf das Repo brauchen:
gh auth login
Und dem Anmeldevorgang folgen.
Wir sind auf GitHub.com, wollen HTTPS, und nutzen web browser
(optional) Dann richten wir autocomplete für das projectctl.bash Skript ein.
./projectctl.bash install_completion
source ~/.bashrc
Als letztes builden wir das base Image für alle Container.
Dieses Image baut auf das offizielle ROS Image auf, und enthält häufig gebrauchte Software für alle unserer Pakete.
./projectctl.bash build_base_image
Jetzt machen wir unseren eigenen Branch.
Den Branch werden wir später auf Github pushen, daher bitte etwas einzigartiges (zb den Nutzernamen) verwenden.
Öffne nun
lazygit
Tip
In der untersten Zeile stehen hilfreiche Tipps, und die Tasten für die häufigsten Funktionen
Drücke ENTER um die wilkommensnachricht zu schließen.
Drücke nun die 3 oder mehrfach TAB um zu "Local branches" zu kommen und danach n für "New branch".
Gebe nun einen Branch-Namen ein, beende die Eingabe mit ENTER.

Glückwunsch! Du hast einen Branch erstellt.
Schließe nun lazygit mit q.
Das war äquivalent zu den git commands:
git branch snaens/pkg_tutorial git checkout snaens/pkg_tutorial
Jetzt erstellen wir die Ordnerstruktur.
mkdir software/pkg_tutorial
Öffne einen neuen Tab, und cd-e zu dem neuen Ordner.
cd software/pkg_tutorial
Nun erstellen wir die docker-compose.yaml
nano docker-compose.yaml
rein kommt:
services:
tutorial:
image: georg-ros:humble
command: 'ros2 topic pub /hello std_msgs/msg/String "data: hello world"'Na dann probieren wir es aus!
docker compose up
Wenn alles bislang geklappt hat kommt jetzt das bekannte "publishing ..."
Fertig zugeschaut? Würge den Container mit STRG+C ab.
Um das ganze in Git zu committen wieder lazygit öffnen (geht in allen georg_at_home Ordnern).
Dann Auf Schaltfläche 2: "Files" navigieren
Mit den Pfeiltasten oder j und k die zu committenden Dateien anfahren und mit LEERTASTE auswählen.
Danach auf c für commit drücken, und einen Titel (und Beschreibung) angeben.
Mit TAB zwischen den beiden Feldern wechseln, und im Titelfeld mit ENTER absenden.
Commit ist fertig!

Das war äquivalent zu den git commands:
git add software/pkg_tutorial/docker-compose.yaml
git commit --message="01 Das erste Paket"
In georg_at_home sind mehr als nur ein Paket, wie können wir sie alle auf einmal starten?
Dafür gibt es die Makefile im georg_at_home Ordner.
Für dieses Tutorial wollen wir aber nur unser Demo Paket starten. Also disablen wir alle anderen.
Im ersten Tab, führe aus:
./projectctl.bash check_pkgs
Wir erwarten etwas wie das hier:

Kopiere die "found pkgs", es kann gut sein dass die Liste bei dir durch neue Pakete länger ist.
Nun Öffne die "projectctl.bash":
nano projectctl.bash
Wir haben es auf diesen Teil abgesehen:
#SKIP_PACKAGES=("drive" "examples")
SKIP_PACKAGES=( )ändere ihn sodass steht:
SKIP_PACKAGES=("drive" "examples" "<weitere Pakete>")
SKIP_PACKAGES=( )Danach speichern und schließeb
Nun erwarten wir aus ./projectctl.bash check_pkgs etwas wie das hier:

Tobe dich nun mit den Verwaltungsfunktionen aus!
./projectctl.bash help
./projectctl.bash up
./projectctl.bash down
./projectctl.bash build
./projectctl.bash start
./projectctl.bash stop
./projectctl.bash logs # nur bei laufendem Container
./projectctl.bash logs tutorial # nur bei laufendem Container
Important
Nicht vergessen zu committen!
Nun wollen wir eine weiteres ROS Paket mit apt in den container installieren.
Dies wollen wir bei build-time machen, damit dies im Image eingebacken ist und nicht bei jedem container-start gemacht werden muss.
Dazu werden wir eine Dockerfile mit weiteren Bauanleitungen für das Image verfassen.
Erstelle die Datei "Dockerfile" im pkg_tutorial Ordner:
FROM georg-ros:humble
WORKDIR /ws
RUN apt-get update && apt-get install --no-install-recommends -y \
ros-humble-examples-rclcpp-minimal-subscriber \
ros-humble-examples-rclcpp-minimal-publisher \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["bash"]Und modifiziere die "docker-compose.yaml":
services:
tutorial:
image: tutorial
build:
context: .
dockerfile: ./Dockerfile
command: 'ros2 run examples_rclcpp_minimal_publisher publisher_member_function'
Im georg_at_home Ordner, mache nun
./projectctl.bash down
./projectctl.bash up
```.
Docker wird jetzt das Image automatisch builden und starten.
<img width="1141" height="310" alt="image" src="https://github.com/user-attachments/assets/86726d13-c8be-499d-bc8e-a8ca8ce6b7e4" />
Das Verzeichnis schaut an diesem Punkt so aus:
```console
$ tree software/pkg_tutorial/
software/pkg_tutorial/
├── docker-compose.yaml
└── Dockerfile
1 directory, 2 files
Important
Nicht vergessen zu committen!
Nun wollen wir unseren eigenen Node coden.
Wir wollen ihn mit colcon build ins Image backen.
Hierfür kopieren wir das ROS tutorial: Writing-A-Simple-Py-Publisher-And-Subscriber
Folge dem Tutorial bis vor Schritt 4: "Build and Run",
im pkg_tutorial Ordner.
Wenn du fertig bist sollte die Struktur wie folgt aussehen:
software/pkg_tutorial/
├── docker-compose.yaml
├── Dockerfile
└── py_pubsub
├── LICENSE
├── package.xml
├── py_pubsub
│ ├── __init__.py
│ ├── publisher_member_function.py
│ └── subscriber_member_function.py
├── resource
│ └── py_pubsub
├── setup.cfg
├── setup.py
└── test
└── ...
Danach brauchen wir wieder die Dockerfile.
Die muss wie folgt ausgebaut werden:
FROM georg-ros:humble
WORKDIR /ws
RUN apt-get update && apt-get install --no-install-recommends -y \
ros-humble-examples-rclcpp-minimal-subscriber \
ros-humble-examples-rclcpp-minimal-publisher
# copy directly into ws folder, src folder is optional
COPY py_pubsub/ src/py_pubsub/
RUN rosdep install --from-paths . --ignore-src -r -y && \
rm -rf /var/lib/apt/lists/*
RUN /bin/bash -c "\
source /opt/ros/humble/setup.bash && \
colcon build --symlink-install \
"
ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["bash"]Und um unseren Node zu starten noch die "docker-compose.yaml"
services:
tutorial:
image: tutorial
build:
context: .
dockerfile: ./Dockerfile
command: 'ros2 run py_pubsub talker'dann zurück zum georg_at_home Ordner und einen Rebuild des images triggern. Danach den aten container sauber schießen und neu starten.
./projectctl.bash build
./projectctl.bash down
./projectctl.bash up
./projectctl.bash logs tutorial
Important
Nicht vergessen zu committen!
In der Regel wollen wir mehr als nur einen ROS Node in unserem Paket starten.
Hierfür integrieren wir eine Launchfile.
dafür erstellen wir in unserem Paket ein neuen Ordner: config/.
Hierfür wieder in den pkg_tutorial Ordner zurück (Tab 2)
mkdir config
Nun erstellen wir eine Launchfile. Diese kann man in XML, Yaml oder Python schreiben → Creating-Launch-Files
Mit python ist man aber eintschieden flexibler.
nano config/pubsub.launch.py
Und rein kommt:
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='py_pubsub',
executable='talker',
name='pub',
emulate_tty=True,
),
Node(
package='py_pubsub',
executable='listener',
name='sub',
emulate_tty=True,
)
])Das Paket soll nun wie folgt aussehen:
software/pkg_tutorial/
├── config
│ └── pubsub.launch.py
├── docker-compose.yaml
├── Dockerfile
└── py_pubsub
├── ...
Die Compose des Containers muss den Neuen Ordner und Launchfile befassen:
services:
tutorial:
image: tutorial
build:
context: .
dockerfile: ./Dockerfile
volumes:
- ./config:/config:ro
privileged: true
init: true
command: 'ros2 launch /config/pubsub.launch.py'-
privileged: trueist nötig weil Programme im Container sonst keine (lese)-Berechtigungen auf die Dateien haben -
init: trueermöglicht, dass das abwürgen über den container an die Launchfile übertragen wird. Ohne gibt es kein clean shutdown.
dann wieder zurück zu georg_at_home und
./projectctl.bash down
./projectctl.bash up
./projectctl.bash logs tutorial
Important
Nicht vergessen zu committen!
Kommt noch - Permissions fehlen :)
Note
Unwichtig für alle die kein git in ihrem Paket verwendet haben.
Tip
Ich empfehle zuerst ein Paket mit den Grundlagen in georg_at_home hergestellt zu haben,
und erst danach die ganzen Commits zu übertragen. Sonst kann es sehr wirr werden!
Im georg_at_home Ordner ausführen:
git remote add oldrepo ../<pfad-zu-altem-repo>
# z.B. git remote add oldrepo ../demorepo
git remote update So was sollte rauskommen:

Danach
git checkout oldrepo/HEAD
Jetzt sind die alten Commits im neuen Repo drin.
lazygit
In Lazygit auf die Schaltfläche 4 - "Commits" navigieren.
Dann mit SHIFT + Pfeiltasten alle Commits anwählen
und mit SHIFT + c cherry-picken.
Sollte so aussehen:

Jetzt auf die Schaltfläche 3 - "Local Branches" navigieren,
und mit LEERTASTE zu dem main branch wechseln.
Nun zurück auf die Schaltfläche 4 - "Commits",
und mit SHIFT + v die commits oben rein pasten. Mit ENTER bestätigen.
Jetzt sollten die Commits übertragen sein!

Die Commits sind nun am richtigen Ort, aber die Dateien noch nicht.
Hierfür können wir die Commits einfach abändern.
(Alternativ kann man die Dateien einfach so verschieben und daraus einen riesen commit machen, der alles verschiebt.)
In Lazygit auf Schaltfläche 4 - "Commits" den ersten commit drücken in der eine Datei vorkommt.
Dann auf e Edit drücken.
In einem weiteren Tab die Datei beliebig verschieben.
Jetzt wieder in Lazygit auf Schaltfläche 2 - "Files" die änderungen mit Pfeiltasten und LEERTASTE übernehmen.
Sobald alles übernommen ist auf SHIFT + a drücken, um die Änderungen dem Commit anzuhängen (amend). Mit ENTER bestätigen.
Um die Änderung jetzt endgültig anzuwenden m - "Rebase options" und dann c continue drücken.
Falls es zu merge errors kommt, die fehlerhafte Teile aus den Dateien entfernen, und wieder mit SHIFT + a den Commit amenden.
Die Dateien sollten jetzt an ihrem neuen Ort sein, und der Commit Verlauf sei derselbe!
- Statt die
projectctl.bashzu nutzen kann man zum debuggen genauso gut im Paket-Ordnerdocker compose upusw machen.
Alle Pakete sind ihre eigene Docker Projekte. (Dieprojectctl.bashmacht das intern genauso, nur halt mit allen Paketen auf einmal.)