Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New lib for GPIO #99

Merged
merged 15 commits into from
Feb 1, 2024
4 changes: 4 additions & 0 deletions .wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,7 @@ subprocess
cbus
Dockerfile
unbuffered
libgpiod
REQ
gpiochip
gpiod
42 changes: 31 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
# Rosbot ROS

ROS2 packages for ROSbot 2R and ROSbot 2 PRO.

## ROS packages

### `rosbot`

Metapackage that contains dependencies to other repositories.

### `rosbot_bringup`

Package that contains launch, which starts all base functionalities. Also configuration for [robot_localization](https://github.com/cra-ros-pkg/robot_localization) and [ros2_controllers](https://github.com/ros-controls/ros2_controllers) are defined there.

### `rosbot_description`

URDF model used as a source of transforms on the physical robot. It was written to be compatible with ROS Industrial and preconfigured for ROS2 control.

### `rosbot_gazebo`

Launch files for Ignition Gazebo working with ROS2 control.

### `rosbot_controller`

ROS2 hardware controllers configuration for ROSbots.

## ROS API
Expand All @@ -32,13 +39,15 @@ For detailed instructions refer to the [rosbot_ros2_firmware repository](https:/
### Prerequisites

Install `colcon`, `vcs` and `rosdep`:

```
sudo apt-get update
sudo apt-get install -y python3-colcon-common-extensions python3-vcstool python3-rosdep python3-pip
```

Create workspace folder and clone `rosbot_ros` repository:
```

```bash
mkdir -p ros2_ws/src
cd ros2_ws
git clone https://github.com/husarion/rosbot_ros src/
Expand All @@ -47,7 +56,8 @@ git clone https://github.com/husarion/rosbot_ros src/
### Build and run on hardware

Building:
```

```bash
export HUSARION_ROS_BUILD=hardware

source /opt/ros/$ROS_DISTRO/setup.bash
Expand All @@ -70,12 +80,14 @@ colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release
> Before starting the software on the robot please make sure that you're using the latest firmware and run the `micro-ROS` agent (as described in the *Usage on hardware* step).

Running:
```

rafal-gorecki marked this conversation as resolved.
Show resolved Hide resolved
```bash
source install/setup.bash
ros2 launch rosbot_bringup bringup.launch.py
```

### Build and run Gazebo simulation

Prerequisites:

> **Warning**
Expand All @@ -84,12 +96,14 @@ Prerequisites:
> Look at [the table](https://gazebosim.org/docs/garden/ros_installation#summary-of-compatible-ros-and-gazebo-combinations) to see the compatible ROS 2 and Gazebo versions.

If you have installed multiple versions of Gazebo use the global variable to select the correct one:

```bash
export GZ_VERSION=fortress
```

Building:
```

```bash
export HUSARION_ROS_BUILD=simulation

source /opt/ros/$ROS_DISTRO/setup.bash
Expand All @@ -110,14 +124,16 @@ colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release
```

Running:
```

```bash
source install/setup.bash
ros2 launch rosbot_gazebo simulation.launch.py
```

## Testing package
## Developer info

### pre-commit

[pre-commit configuration](.pre-commit-config.yaml) prepares plenty of tests helping for developing and contributing. Usage:

```bash
Expand All @@ -134,20 +150,23 @@ pre-commit run -a
After initialization [pre-commit configuration](.pre-commit-config.yaml) will applied on every commit.

### Industrial CI
```

```bash
colcon test
```

> [!NOTE]
> Command `colcon test` does not build the code. Remember to build your code after changes.

If tests finish with errors print logs:
```

``` bash
colcon test-result --verbose
```

### Format python code with [Black](https://github.com/psf/black)
```

```bash
cd src/
black rosbot*
```
Expand All @@ -156,18 +175,19 @@ black rosbot*

At fist install [act](https://github.com/nektos/act):

```
```bash
cd /
curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
```

And test the workflow with:

```
```bash
act -W .github/workflows/industrial_ci.yaml
```

## Demo

Below you can find demos with ROSbots:
| link | description |
| - | - |
Expand Down
2 changes: 1 addition & 1 deletion rosbot_utils/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<url type="bugtracker">https://github.com/husarion/rosbot_ros/issues</url>

<exec_depend>python3-sh</exec_depend>
<exec_depend>python-periphery-pip</exec_depend>
<exec_depend>python3-libgpiod</exec_depend>
<exec_depend>python3-pyftdi-pip</exec_depend>
<exec_depend>usbutils</exec_depend>
<exec_depend>python3-serial</exec_depend>
Expand Down
46 changes: 27 additions & 19 deletions rosbot_utils/rosbot_utils/flash-firmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
import time
import sys
import argparse
from periphery import GPIO
import gpiod
from gpiod.line import Direction, Value


class FirmwareFlasher:
Expand All @@ -34,45 +35,52 @@ def __init__(self, sys_arch, binary_file):

print(f"System architecture: {self.sys_arch}")

if self.sys_arch.stdout == b"armv7l\n":
if self.sys_arch == "armv7l":
# Setups ThinkerBoard pins
print("Device: ThinkerBoard\n")
self.port = "/dev/ttyS1"
rafal-gorecki marked this conversation as resolved.
Show resolved Hide resolved
boot0_pin_no = 164
reset_pin_no = 184
self.boot0_pin_no = 164
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.boot0_pin_no = 164
self.boot0_pin = 164

self.reset_pin_no = 184
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.reset_pin_no = 184
self.reset_pin = 184


elif self.sys_arch.stdout == b"x86_64\n":
elif self.sys_arch == "x86_64":
# Setups UpBoard pins
print("Device: UpBoard\n")
self.port = "/dev/ttyS4"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.port = "/dev/ttyS4"
self.serial_port = "/dev/ttyS4"

boot0_pin_no = 17
reset_pin_no = 18
self.boot0_pin_no = 17
delihus marked this conversation as resolved.
Show resolved Hide resolved
self.reset_pin_no = 18
delihus marked this conversation as resolved.
Show resolved Hide resolved

elif self.sys_arch.stdout == b"aarch64\n":
elif self.sys_arch == "aarch64":
# Setups RPi pins
print("Device: RPi\n")
self.port = "/dev/ttyAMA0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.port = "/dev/ttyAMA0"
self.serial_port = "/dev/ttyAMA0"

boot0_pin_no = 17
reset_pin_no = 18
self.boot0_pin_no = 17
rafal-gorecki marked this conversation as resolved.
Show resolved Hide resolved
self.reset_pin_no = 18
delihus marked this conversation as resolved.
Show resolved Hide resolved

else:
print("Unknown device...")

self.boot0_pin = GPIO(boot0_pin_no, "out")
self.reset_pin = GPIO(reset_pin_no, "out")
chip = gpiod.Chip("/dev/gpiochip0")
self.boot0_pin = chip.request_lines(
delihus marked this conversation as resolved.
Show resolved Hide resolved
{self.boot0_pin_no: gpiod.LineSettings(Direction.OUTPUT)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{self.boot0_pin_no: gpiod.LineSettings(Direction.OUTPUT)}
{self.boot0_pin: gpiod.LineSettings(Direction.OUTPUT)}

)
self.reset_pin = chip.request_lines(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.reset_pin = chip.request_lines(
self.reset_port = chip.request_lines(

{self.reset_pin_no: gpiod.LineSettings(Direction.OUTPUT)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{self.reset_pin_no: gpiod.LineSettings(Direction.OUTPUT)}
{self.reset_pin: gpiod.LineSettings(Direction.OUTPUT)}

)
# gpiod.Chip("/dev/gpiochip0").get_line(self.boot0_pin_no, direction=gpiod.LINE_REQ_DIR_OUT)
# self.reset_pin = gpiod.Chip("/dev/gpiochip0").get_line(self.reset_pin_no, direction=gpiod.LINE_REQ_DIR_OUT)
rafal-gorecki marked this conversation as resolved.
Show resolved Hide resolved

def enter_bootloader_mode(self):
self.boot0_pin.write(True)
self.reset_pin.write(True)
self.boot0_pin.set_value(self.boot0_pin_no, Value.ACTIVE)
self.reset_pin.set_value(self.reset_pin_no, Value.ACTIVE)
delihus marked this conversation as resolved.
Show resolved Hide resolved
time.sleep(0.2)
self.reset_pin.write(False)
self.reset_pin.set_value(self.reset_pin_no, Value.INACTIVE)
delihus marked this conversation as resolved.
Show resolved Hide resolved
time.sleep(0.2)

def exit_bootloader_mode(self):
self.boot0_pin.write(False)
self.reset_pin.write(True)
self.boot0_pin.set_value(self.boot0_pin_no, Value.INACTIVE)
self.reset_pin.set_value(self.reset_pin_no, Value.ACTIVE)
delihus marked this conversation as resolved.
Show resolved Hide resolved
time.sleep(0.2)
self.reset_pin.write(False)
self.reset_pin.set_value(self.reset_pin_no, Value.INACTIVE)
delihus marked this conversation as resolved.
Show resolved Hide resolved
time.sleep(0.2)

def try_flash_operation(self, operation_name, flash_command, flash_args):
Expand Down Expand Up @@ -118,7 +126,7 @@ def main():
)

binary_file = parser.parse_args().file
sys_arch = sh.uname("-m")
sys_arch = sh.uname("-m").stdout.decode().strip()

flasher = FirmwareFlasher(sys_arch, binary_file)
flasher.flash_firmware()
Expand Down
Loading