Skip to content

Framework for rapid integration of CAN-equipped STM32 μcontrollers with ROS. Server side.

License

Notifications You must be signed in to change notification settings

Zjonn/rubi_server

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rover Universal Board Infrastructure

General description

Rover Universal Board Infrastructure (RUBI) is a framework designed for rapid and reliable integration of STM32 controller based devices with the Robot Operating System (ROS) over the CAN bus. It was conceived during works on the Aleph1 rover project, in which the following systems model was implemented (simplified):

alt text

In this model, most of the robot functions (like sensor polling or the motor control) are directly managed by the programmable universal logic boards, which are equipped with the STM32F103 microcontroller, CAN bus transceiver and a wide range of IO (GPIO, UARTs, SPIs, etc.). Those boards are then connected to the robot’s main computer via multiple CAN buses. It was first planned, that each board will have a separate microcontroller code, a control program on the robot’s main computer and a separate GUI application. This ‘naive’ workflow of software/firmware development was found not efficient due to the following facts:

  • when a new board was added, a new communication layer had to be carefully designed to avoid conflicts with the previous configuration,
  • when a new board was added, the code for all major robot’s components had to be modified (you have to touch the code of the board, the main computer, and the control station),
  • many of the logic boards need a very simple user interface, for example, the drill controller had four buttons and the power monitor displayed two integers,
  • writing a separate control program for each board discouraged implementing universal functions like the QoS of the bus, board remote reboot, emergency shutdown of the system, hot-plug etc.

To address these downsides, RUBI is designed so that in most cases, a new board is integrated to the system by specifying its capabilities in the microcontroller code with the provided API and simply plugging the board into one of the RUBI-controlled CAN buses.

RUBI then dynamically addresses the board, handles communication between the board, the main computer and the control station, pushes data from the board to the ROS and depending on the programmer’s choice either automatically generates user interface for the board or provides a compact Python API with the previously-specified capabilities for the developer to write a GUI control program himself.

Subprojects

RUBI consists of four components:

  • rubi_client (API for the STM32FX): using a set of macros, the programmer defines variables and function callbacks, which will represent the board capabilities and will be automatically synchronized by the code included with the API. This code also provides additional functions like basic hardware initialization, remote reboot or system time access,
  • rubi_server (this repository): the program which runs on the main computer, keeps track of the connected boards and does all the data synchronization between the ROS and the boards connected across multiple CAN buses,
  • rubi_generic_gui: dynamic user interface generator,
  • rubi_custom_gui: a template for custom interface creation with QtDesigner and rqt.

Hardware

Currently, it is easy to make rubi_client work on any STM32F1 or STM32F3 microcontroller (provided it is equipped with a CAN bus). It was tested on the:

customly designed logic board with STM32F303RC off the shelf OLIMEXINO-STM32 with STM32F103RB

As of hardware for the rubi_server, it runs on a Linux-based machine with a ROS installation, a CAN transceiver and a socketcan implementation for it. It is also possible to tunnel the CAN traffic over Ethernet with tools like cannelloni, but it is discouraged for purposes other than prototyping or debugging.

An interesting configuration was tested using the Banana Pi M1+ microcomputer with the CAN bus on the A20 SoC and two additional MCP2515s connected over single SPI and two interrupt lines. This adds up to three CAN buses over two different chips being simultaneously managed by the rubi_server.

alt text

Usage

Provided that you have a rubi-capable board connected to the can bus (let's say its can0), activate the can bus and set the baud rate manually:

sudo ip link set can0 down && sudo ip link set can0 type can bitrate 500000 && sudo ip link set can0 up

Then start the rubi_server:

rosrun rubi_server rubi_server _cans:="can0"

And expect the following output on the console:

[ INFO] [1535631798.654781409]: [CommunicationHandler] Handshake complete for board <your board name>
[ INFO] [1535631798.678517125]: [RosModule] Frontend registered new board type: <your board name>

The rubi_server should now publish / subscribe to the following ROS topics:

/rubi/cans_load     # Usage of the can buses the rubi_server is attached to
/rubi/new_boards    # When a new board is registered, the rubi server publishes an std_msgs::Empty message here
/rubi/panic         # Send std_msgs::Empty message here to restart everything :>

Depending on the number of connected boards and their capabilities you should also see board-specific topic, i.e.:

/rubi/boards/engine_driver/fields_from_board/current_speed       # Topics that the _board_ publishes into
/rubi/boards/engine_driver/fields_from_board/motor_temperature   #
/rubi/boards/engine_driver/fields_to_board/set_brake             # Topics on which the _board_ receives the data
/rubi/boards/engine_driver/fields_to_board/set_speed             #
/rubi/boards/engine_driver/reboot                                # You can command the rubi-compatible board by sending
/rubi/boards/engine_driver/sleep                                 # std_msgs::Empty onto those topics
/rubi/boards/engine_driver/wake                                  #

The rubi_server will also provide you with some services you can use to dynamically explore capabilities of the boards (this is what the automatically-generated GUI uses):

/rubi/boards/engine_driver/online   # Use this to check if the board is connected and alive
/rubi/get_board_descriptor          # Get board capabilities (fields and functions)
/rubi/get_cans_names                # Get can buses to which the rubi_server is attached
/rubi/get_field_descriptor          # Get properties of the specific board's field
/rubi/get_func_descriptor           # Get properties of the specific board's function
/rubi/show_boards                   # Get names of the connected boards (even the dead ones)

About

Framework for rapid integration of CAN-equipped STM32 μcontrollers with ROS. Server side.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 89.8%
  • CMake 6.8%
  • C 3.4%