Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 124 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,91 +1,143 @@
# Volksbot ROS2 branch

This branch contains the in progess migration of the volksbot package to ROS2 after applying the ros-migration-tool. After successful use of the migration tool not all ROS code snippets are converted into ROS2, like the subscriber, publisher and services. This further migration is now done manually.


# Expanded Joystick Driver for Volksbot ROS2

This branch is used to convert the old joystick backend into a new and expanded ROS2 implementation. It will expand the useability and agility of the original implementation to allow easier project integration and force feedback.

The new implementation will no longer use the `/dev/input/js*` joystick devices but the more general `/dev/input/event*` event devices.
> It is usually advised to use the general event interface instead of the the more constraint joystick interface.


### Information

To use the general event interface the joysticks event file handle needs to be ruled to a non dynamic device handle. At the moment only the **Logitech F710** and the **Microsoft X-Box One** joysticks are _used_ and will be fully integrated. Therefor the backend will currently only implement these joysticks.

However integrating further joysticks is easily possible by adapting the applied rules and adding the necessary interface implementations.


### How to use

Unlike the old implementation it is no longer necessary to preemptively define the joysticks `/dev/input/*` Path.
It will now automatically select one of the connected (and implemented) Joysticks.

If multiple implemented joysticks are recognized, the one with the lowest number of its `/dev/input/js*` handle will be selected. This is usually the first connected joystick device.


# Sick LMS
## Info
The library used is the [official ROS2 library](https://github.com/SICKAG/sick_scan_xd/tree/master) version 3.5.0 for sick scanners.

## [Building](https://github.com/SICKAG/sick_scan_xd/blob/master/INSTALL-ROS2.md#summary-for-the-different-build-options)

Building the library for the lms100

colcon build --packages-select sick_scan_xd --cmake-args " -DROS_VERSION=2" " -DLDMRS=0" " -DSCANSEGMENT_XD=0" --event-handlers console_direct+

> TODO: (if possible?) add cmake args to the cmake file used for building
# Volksbot ROS2
This project is an adaptation of the original code to the modern ROS2 alternative for the Volksbot rovers (the original ROS version can be found under the branch [ROS](https://github.com/JMUWRobotics/volksbot/tree/ROS1)).

---
# Prerequisits
- Ubuntu 22.04 or Ubuntu 24.04
- GCC 11.0 or greater
- [ROS2 humble](https://docs.ros.org/en/humble/index.html)

> [!Warning]
> Other Linux distributions may or may not work correctly. Therefore, it is recommented to use one of the distributions mentioned above.
> Please let us know your experience and success with other systems.

> [!Important]
> If you use Ubuntu 24.04, you will probably encounter a `Permission Denied` error when trying to run the `volksbot` node.
> To fix this error regard the section [Trouble Shooting - Permission Denied](#permission-denied).

# Quickstart
> [!Note]
> For advanced build options regard the section [How To Build - Advanced](#how-to-build---advanced).

## How To Build
1. clone the repository locally
```bash
git clone git@github.com:JMUWRobotics/volksbot.git
```
2. change to the `ros2_ws` directory
```bash
cd volksbot/ros2_ws
```
2. set the udev rules (once) so that the motor controllers are recognized by the code.
Copy the `42-usb-serial-volksbot.rules` from the `motor_controller` package into your udev rules:
```bash
sudo cp src/motor_controller/42-usb-serial-volksbot.rules /etc/udev/rules.d/
```
Afterwards, either restart or reset the udev server to load the new rules:
```bash
udevadm control --reload-rules && udevadm trigger
```
4.
a) *on your **initial** build*: source the global ros2 environment:
```bash
source ${ros2_distro}
```

b) ***else*** source the ROS2 workspace:
```bash
source ./install/setup.bash
```
5. build the project with the build script `volksbuild.sh`:
```bash
./volksbuild.sh
```

> [!Tip]
> You can run the build with a set number of concurrent worker threads by supplying an argument to the build script.
> This is usefull when your system is limited in RAM or your OS freezes while building. (building with 2-4 threads should work on any system):
> ```bash
> ./volksbuild.sh n
> ```

## How to Run
The `volksbot` node from the `volksbot` package must always be started as this node determines the connected rover and comunicates the configureation over the `rover` topic to all other nodes:
```bash
ros2 run volksbot volksbot
```

## [Running / Launching](https://github.com/SICKAG/sick_scan_xd?tab=readme-ov-file#running-the-driver)
> [!Tip]
> If you want to select a specific rover supply the name of the rover as an argument:
> ```bash
> ros2 run volksbot volksbot [RoverName]
> ```

Launching the sick driver for the lms100 ! Attention: must set the correct host-ip manually
In an other terminal you can run any node or the default launch script `praktikum_launch.py` of the package `volkslaunch`, which launches the remaining (not your customs) nodes.
```bash
ros2 launch volkslaunch praktikum_launch.py
```

ros2 run sick_scan_xd sick_generic_caller ./src/sick_scan_xd/launch/sick_lms_1xx.launch hostname:=192.168.0.XX
> [!Caution]
> When playing back rosbags while connected to the rover you may want to comment out the `gamepad_driver` node from the launch script to avoid unwanted velocity commands to the motors with the recorded data.

> TODO: configure and add laser specific settings like in the ROS1 volksbot parameter.yaml
---

# Building
> Hint: When your OS freezes on building consider using less parallel workers by adding ```--parallel-workers n``` to the colcon build command. (2 or 3 should usually work for everyone)
# Documentation & more Information
Regard the following documentation markdowns for further information on usage and configuration of the project:
- [Gamepad Driver](ros2_ws/src/gamepad_driver/README.md): Information on how to use the gamepad and the different drive modes.
- [Logging](ros2_ws/src/volksface/logging.md): Information on how to set up logging for the packages and how to use the logging macros for debugging and development and console prints.

### When building for the first follow the following steps:
---
# Trouble Shooting
## Permission Denied
If you are running the `volksbot` node on Ubuntu 24, you might encounter a `Permission Denied` error during the selection process.
This happens because the program attempts to use ICMP sockets for pinging, which requires specific kernel permissions.
By default, some Ubuntu configurations set the allowed group range to `1 0`, meaning only the root user is permitted to open these sockets.

1) source ros2
To allow all users to use ICMP sockets, you have to type in the command:
```bash
source ${ros2_distro}
sudo sysctl -w net.ipv4.ping_group_range="0 2147483647"
```
To make this setting permanent, you have to edit your `/etc/sysctl.conf` and add the line `net.ipv4.ping_group_range=0 2147483647`.

2) only build the SICK LMS package
```bash
colcon build --packages-select sick_scan_xd --cmake-args " -DROS_VERSION=2" " -DLDMRS=0" " -DSCANSEGMENT_XD=0" --event-handlers console_direct+
```

3) source the project
```bash
source ./install/setup.bash
```
---
# Bugs or Issues?
Any Bugs or Issues, please open an [issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/learning-about-issues/quickstart) on this [repository](https://github.com/JMUWRobotics/volksbot/issues) or conntact us directly.

4) build all other packages
```bash
colcon build --packages-ignore sick_scan_xd
```
---
# How To Build - Advanced
> [!Tip]
> When your OS freezes on building consider using less parallel workers by adding ```--parallel-workers n``` to the colcon build command (2-4 should usually work for everyone).

### For normal building use the following command
> Make sure you are source into the workspace with
> `source ./install/setup.bash`
## When building for the first time:
1. source global ros2 environment
```bash
source ${ros2_distro}
```
2. only build the SICK LMS package
```bash
colcon build --packages-select sick_scan_xd --cmake-args " -DROS_VERSION=2" " -DLDMRS=0" " -DSCANSEGMENT_XD=0" --event-handlers console_direct+
```
3. source the ros2 workspace
```bash
source ./install/setup.bash
```
4. build the remaining packages
```bash
colcon build --packages-ignore sick_scan_xd
```

## Regular building:
> [!Caution]
> Make sure you are sourced into the workspace with
> ```bash
> source ./install/setup.bash
> ```

```bash
colcon build --packages-ignore sick_scan_xd
```


# Logging

Enter the following line in your terminal to set the logging directory for all logs:

or just a subset of the packages:
```bash
export ROS_LOG_DIR=./log/latest
colcon build --packages-select [package1] [package2] [package3] [...]
```

the logs can then be found under the linked folder `./logs/latest/` where `latest/` is a symlink to the folder of the latest build
2 changes: 1 addition & 1 deletion ros2_ws/cmake/project_config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ add_compile_definitions(
USE_COLORED_LOGGING=1

# set logging for individual packages, will override the global logging config
# comment out to use global logging config
# [comment out to use global logging config}
# USE_LOGGING_GAME_PAD=0
# USE_LOGGING_KEYBOARD=0
# USE_LOGGING_LMS_STARTER=0
Expand Down
86 changes: 80 additions & 6 deletions ros2_ws/src/gamepad_driver/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,93 @@
# Expanded Joystick Driver for Volksbot ROS2

This branch is used to convert the old joystick backend into a new and expanded ROS2 implementation. It will expand the useability and agility of the original implementation to allow easier project integration and force feedback.
This package handles the gamepad input for the volksbot rovers. It dynamically recognizes connected gamepads and communicates the gamepad inputs vie the `gamepad` topic. In addition to that it also directly translates the gamepad inputs into velocity commands and publishes them on the `cmd_vel` topic. This allows for a direct control of the rover via the gamepad without the need for an additional node to translate the volksbot velocity command ROS2 messages. The driver is designed to be flexible and can support multiple types of controllers and can make use of the haptic feedback rumble if implemented in the controllers.

The currently supported controllers are:
- **Logitech F710**
- **Microsoft X-Box One**

## How To Use
To use the gamepad driver, simply run the `gamepad_driver` node:
```bash
ros2 run gamepad_driver gamepad_driver
```

Currently **two** drive modes are implemented to control the rover via the gamepad:
- **Arcade Drive**: The left thumb stick controls the forward and backward movement and left and right steering.
- **Throttle Drive**: The left thumb stick controls the left and right steering, the right trigger controls the forward acceleration and the left trigger controls the backward acceleration. This allows for a more intuitive control of the rover, especially for users familiar with racing games.

<!-- - **Tank Drive**: The left joystick controls the left wheels and the right joystick controls the right wheels. This allows for precise control of the rover and is especially useful for tight maneuvers. -->

The drive modes can be switched by pressing the `START` button on the controller.
In all drive modes the right thumb stick can be used to turn on the spot, where left and right movement of the stick will cause the rover to rotate left and right respectively.
Likewise, pressing the index Buttons `RB` and `LB` will increase or decrease the max speed of the rover, respectively.

- Arcade Drive:
```yaml
/ LT \ Switch Mode / RT \
Slower--> | LB | | | RB | <--Faster
|------+--------------V--+------|
) ^ Back Start Y (
/ < + > Logitech X A \
( v Mode Vibrate B )
Accelerate ------> ^ ^ |
Steering ----> < O > < O > <---- Rotate <-CCW / CW->
Decelerate ------> V V )
\ /^^^^^^^^^^^^^^^^^^^\ /
\-__-/ \-__-/
```

- Throttle Drive:
```yaml
Decelerate-> / LT \ Switch Mode / RT \ <--Accelerate
Slower--> | LB | | | RB | <--Faster
|------+--------------V--+------|
) ^ Back Start Y (
/ < + > Logitech X A \
( v Mode Vibrate B )
| ^ ^ |
Steering ----> < O > < O > <---- Rotate <-CCW / CW->
( V V )
\ /^^^^^^^^^^^^^^^^^^^\ /
\-__-/ \-__-/
```


The new implementation will no longer use the `/dev/input/js*` joystick devices but the more general `/dev/input/event*` event devices.
> It is usually advised to use the general event interface instead of the the more constraint joystick interface.

> [!Caution]
> For the **Logitech F710**: Make sure to set the switch on the back of the controller to the **X** mode, otherwise the controller will not be recognized by the driver and that you do not have the **mode** button activated (as indicated by the LED) as it switches the functions from the thumb stick to the D-pad.

### Information

To use the general event interface the joysticks event file handle needs to be ruled to a non dynamic device handle. At the moment only the **Logitech F710** and the **Microsoft X-Box One** joysticks are _used_ and will be fully integrated. Therefor the backend will currently only implement these joysticks.





# Information for Developer
The new implementation will no longer use the `/dev/input/js*` joystick devices but the more general `/dev/input/event*` event devices.
> It is usually advised to use the general event interface instead of the the more constraint joystick interface.

## Information

To use the general event interface the joysticks event file handle needs to be ruled to a non dynamic device handle. At the moment only the **Logitech F710** and the **Microsoft X-Box One** joysticks are _used_ and fully integrated.
However integrating further joysticks is easily possible by adapting the applied rules and adding the necessary interface implementations.

## Internal Defines and Debug Symbols
The `volksbot_adapter.cpp` contains some internal defines that can be used for debugging and development.
These can be activated by uncommenting the corresponding `#define` statement.
The following are symbols which enable different print outputs to the console for display or debuging, by default the `PRINT_STATE` is activated:
| Symbol | Description | Printed Once | Printed Per Update Loop |
|:-------|:------------|:------------:|:-------------------------:|
| `PRINT_EVIO` | This will print the raw configuration data of the connected gamepad, once the connection is established, can be useful for debugging and setting up new joysticks. | ✅ | ❌ |
| `PRINT_STATE` | This will print a visualization of the gamepad inputs. | ❌ | ✅ |
| `PRINT_EVENT` | This will print every recorded input event. | ❌ | ✅ |
| `PRINT_VEL_CTRL` | This will print debug information for debugging the ACCEL_FORCE_FEEDBACK. | ❌ | ✅ |

> **The following feature is currently unstable and currently disabled**
>
> `ACCEL_FORCE_FEEDBACK` is a feature that emulates force feedback by applying an acceleration to the rover when the trigger buttons are pressed. This can be used to give the user a better feel for the speed of the rover and can be useful for controlling the rover in tight spaces.

### How to use
## How to use

Unlike the old implementation it is no longer necessary to preemptively define the joysticks `/dev/input/*` Path.
It will now automatically select one of the connected (and implemented) Joysticks.
Expand Down
35 changes: 30 additions & 5 deletions ros2_ws/src/gamepad_driver/src/volksbot_adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,42 @@ using namespace std::chrono_literals;
//-----------------//
// debug symbols //
//-----------------//
// print a visualization of the gamepad inputs
// print the evio data of the gamepad (e.g. for debugging and setup of new gamepads)
// #define PRINT_EVIO

// print a visualization of the gamepad inputs (gets called every update loop)
// #define PRINT_STATE

// debug print every recorded input event
// debug print every recorded input event (gets called every update loop)
// #define PRINT_EVENT

// debug print for debuging ACCEL_FORCE_FEEDBACK
// debug print for debuging ACCEL_FORCE_FEEDBACK (gets called every update loop)
// #define PRINT_VEL_CTRL

// enable emulated force feedback // works currently unstable
// #define ACCEL_FORCE_FEEDBACK


//=============================================================================
// CODE
//=============================================================================

// assert that at most one of the debug print options is enabled to avoid cluttered output
static_assert(
0
#ifdef PRINT_STATE
+ 1
#endif
#ifdef PRINT_EVENT
+ 1
#endif
#ifdef PRINT_VEL_CTRL
+ 1
#endif
<= 1,
"At most one of the debug print options PRINT_STATE, PRINT_EVENT and PRINT_VEL_CTRL can be enabled at the same time to avoid cluttered output!"
)

using std::placeholders::_1;
using std::placeholders::_2;

Expand Down Expand Up @@ -247,7 +270,6 @@ class Volks_gamepad : public rclcpp::Node {
_pub_gp = create_publisher<msg::Gamepad>( VB::TOPIC_NAME_GAMEPAD, 10 );
_service_rumble = create_service<srv::Rumble>( VB::SERVICE_NAME_RUMBLE, std::bind( &Volks_gamepad::set_rumble, this, _1, _2) );


while( rclcpp::ok() ) {
active_gamepad = device_util::select_and_connect_gamepad(true);

Expand All @@ -256,7 +278,10 @@ class Volks_gamepad : public rclcpp::Node {

rclcpp::sleep_for( nanoseconds( 1000ms ) );
}
active_gamepad->print_evio();

#ifdef PRINT_EVIO
active_gamepad->print_evio();
#endif
}

void run( rclcpp::Executor& executor ) {
Expand Down
Loading