This package contains the KELO Tulip software. This software takes a velocity vector for the overall platform and converts it to commands for the individual KELO Drives of the platform. It implements an EtherCAT master to communicate with the KELO Drives and provides a simple velocity controller that can be used on real robots as well as for simulation.
The KELO Drive is the patent pending novel drive concept for mobile robots developed by KELO robotics. These wheels can be attached to any rigid platform in order to transform it into a mobile robot. It can even be used to robotize a container. A few screws are enough.
After mechanically connecting the KELO Drives to your platform, you only need to connect them to power via an XT-60 power connector and to your computer via an EtherCAT cable. For multiple wheels, you should either use a Beckhoff Ethernet Switch or one of the KELO power distribution boards. After the wheels are powered and connected to your computer via EtherCAT, the software in this repository will help you make your robot move.
You can move your mobile platform via a joypad for test purposes or use any software that publishes ROS geometry_msgs/Twist
messages to the cmd_vel
topic. See the Interface section below. The software can also be used without ROS. Please contact the developers for that.
This software was tested on Ubuntu 16 with ROS Kinetic, Ubuntu 18 with ROS Melodic and Ubuntu 20 with ROS Noetic. Other Linux flavors should work as well.
For ROS it is enough to install the base system (for Noetic ros-noetic-ros-base). In addition it requires
sudo apt install ros-noetic-tf
If another ROS version is used, replace the term noetic accordingly in these commands.
The package can be compiled like any ROS package. Clone or copy it into a ROS workspace source folder and run catkin_make
or catkin build
, depending on your preferences.
Special permissions need to be granted to the generated executable, since it needs RAW access to the Ethernet port. Instead of starting it as root the setcap
tool can be used:
sudo setcap cap_net_raw+ep <name_of_executable>
Optionally, the command can be applied during the build process by passing the -DUSE_SETCAP=ON
option to catkin. Default is OFF
.
catkin_make -DUSE_SETCAP=ON
OR
catkin build kelo_tulip -DUSE_SETCAP=ON
Note: If you use this flag, you will be asked to input the sudo password during the build process. It might look like the build is going on but you need to lookout for [sudo] password for <username>
in the output and enter the password after this prompt had appeared. If not, the build process will continue forever.
If using Ubuntu 18 or newer (with ROS Melodic or Noetic), running the setcap command as described above can cause the executable to not find all dynamic libraries anymore. This is because the dynamic linker works in a "secure-execution mode" when the capabilities of a program changed, in which it ignores most environment variables such as LD_LIBRARY_PATH. A typical error after starting reads like this:
devel/lib/kelo_tulip/platform_driver: error while loading shared libraries: libtf2_ros.so: cannot open shared object file: No such file or directory
In that case it is recommended to set the path to those libraries on system level. The following method should work on default installations, but please adapt accordingly if you already made other changes in your system.
For ROS Noetic, the following command will add an entry to point to the dynamic libraries of ROS:
sudo sh -c 'echo "/opt/ros/noetic/lib/" > /etc/ld.so.conf.d/ros.conf'
If not using ROS Noetic, the path there should be changed accordingly.
Afterwards you need to run
sudo ldconfig
to make the changes take effect.
The program can be started by running
roslaunch kelo_tulip example.launch
The default launch file in kelo_tulip/launch/example.launch
loads the YAML configuration from config/example.yaml
. Feel free to change parameters directly in this config file, or to make a copy and adjust the launch file to load the new file.
The following setting defines the network interface used by the driver:
device: enp2s0
This setting must be adjusted to the network interface by which the KELO drives are connected via EtherCAT.
The controller needs to know the number of wheels and their location in the body fixed frame of the platform as well as the offset of their pivot encoder (the encoder value when the wheel is oriented forward). This information should be included in the YAML configuration file in the following manner:
num_wheels: 4
wheel0:
ethercat_number: 6
x: 0.175
y: 0.1605
a: 3.14
wheel1:
...
Please adjust the list of wheels with the correct number and location of the wheels on your platform. wheel0
refers to the first wheel, starting counting with zero. The ethercat_number
is the EtherCAT slave number of that wheel. The possible numbers can be seen from when starting kelo_tulip, it will print out information about all slaves found on the EtherCAT bus.
The values x
and y
are the coordinates of the wheels center according to the fixed frame of the platform in meters. a
is the offset of pivot encoder in rad.
Currently the kelo_tulip software uses ROS as a middleware, subscribing resp. publishing to the following topics.
This topic accepts geometry_msgs/Twist
messages. Any motion software that creates a velocity vector for the platform and publishes geometry_msgs/Twist
messages to the cmd_vel
topic can be used. The ROS package move_base
is an example that conforms to that.
By sending messages to the /joy
topic the platform can be moved by a joypad. The joy
ROS package can be used to send these messages via joypad. In the function joyCallback()
in PlatformDriverROS.cpp
is a simple translation between joystick input and platform velocity command.
Note: For safety reasons joystick messages are only considered if the RB
button on the joypad is pressed, resp. the joy button with index 5 is active. This makes it also possible to run it in parallel with other packages that already process joystick input, overriding their input as long as the RB
button keeps being pressed.
On the topic /odom
odometry data in form of nav_msgs/Odometry
are published. Each time the program is started, the position is reset to the origin.
The same odometry data is published also on the topic /tf
in the form of tf transform from the frame base_link
to odom
.
On this topic an integer representing status information about the controller is published periodically in form of std_msgs::Int32
messages. The single bits of the number have the following meaning:
Bit | Description |
---|---|
0x0001 | Status OK, EtherCAT communication and all drives are working properly. |
0x0100 | An unspecified error occured. |
0x0200 | Error detected in EtherCAT communcation because of wrong WKC value. Might be temporary communication loss or power off of one wheel. |
0x0400 | Timestamp of one KELO Drive did not increase as expected, probably it stopped communicating. |
0x0800 | One KELO Drive did not have the expected status bits set, probably it got deactivated for some reasons. |
kelo_tulip includes a simple velocity controller to demonstrate the general principle how to command wheel velocities. It considers velocity and acceleration limits for the platform. Being velocity based it does not allow for the compliant motion of the platform. It is rather meant as a guideline how own controllers can be developed. The controller itself is implemented as a C++ class and does not have any dependencies on ROS.
The concept of this simple controller is as follows. For each drive a target velocity is computed that depends on the desired velocity for the whole platform and the mounting position of the drive on the platform. The velocity of the individual wheel determines which pivot angle it should have. This pivot angle must be achieved by rotating the wheel around its center. This can be done by moving the left and right hubwheel with the same speed in opposite directions; similar to like a robot with differential drive would rotate around its center. In addition the linear motion of the drive can be achieved by giving the left and right hubwheel the same speed in the same direction. Just overlaying both parts, speeds in opposite direction for pivot-rotation and speeds in same direction for linear motion, will lead to the desired overall motion of the platform.
The crucial part here is that each drive is handled on its own, separately from the others. This makes the whole approach very modular and does not cause any issues when more wheels are added or their mounting locations are changed. A flaw of this simple approach is the tendency to give already a forward motion if the wheels do not point yet into the correct orientation. If different wheels then start to move into different directions, the result on the platform can be very suboptimal. One possible solution is to delay giving forward velocities until all wheels are oriented more or less correctly. This can increase the stability of the motion, but also make maneuvers slower, and for the sake of simplicitiy was not done in the provided example controller.
The controller can be found in the file src/VelocityPlatformController.cpp
. The main functions are the following:
The constructor initializes several variables, there are in particular:
platform_target_vel_
: A struct withx
,y
, anda
members to set the target values as requested by the external applicationplatform_ramped_vel_
: A struct withx
,y
, anda
members to set velocities that acceleration limits into accountplatform_limits_
: A struct with minimum and maximal settings for velocity, acceleration and deceleration
Called to set the desired platform velocity in x, y, and rotational direction.
This function is called with a configuration setting for each wheel, in particular containing the location of each wheel in the platform's coordinate center.
This function ramps up or down the current velocity setpoints according to the acceleration limits and the platform's target velocities. Each dimension is considered separately from the others.
This is the main function that computes the setpoint for the left and right hub wheels of each drive. It must be called once for each drive at each step. The computation consists of the following main steps:
- Determine the x and y position of each (left and right) hub wheel relative to the platform's center.
- Calculate the velocity this wheel unit should have at its pivot position, i.e. between the left and right hub wheel.
- Calculate the target pivot angle based on the wheel velocity.
- Apply a simple P-controller to minimize the error between measured pivot angle and target pivot angle.
- Calculate the single hubwheel velocity based on the pivot-controller result and the target velcoity of the drive.
The result is the setpoints for the left and right hubwheel, which can then be sent to the real KELO drive.