Bertrand's Design Study

From CSSEMediaWiki
Revision as of 02:37, 5 October 2009 by Bertrand Roussel (Talk | contribs)
Jump to: navigation, search

Last year, I was involved in a project which consisted in building an autonomous robot to compete in the French Robotic Cup. My main task was to handle all the data transmissions in the robot. This mean I had to work a lot with networks, especially the CAN network (widely used in cars).

This one is not like TCP/IP, there is no sources nor destinations. All frames have IDs (11 or 29 bits), and each nodes connected to the network needs to determine if the frame is relevant or not by filtering IDs.
The main problem is for managing the whole network, which mean handling IDs:

  • nodes are mostly µc like PIC, ARM, ... and are running home-made firmwares, without OS (written in C)
  • the data part of a frame can be up to 8 bytes long, the format is determined by the developer

Managing the network "by hand" would be a really painful task: determining IDs, format, writing them in the code, ... can lead to an infinite amount of errors and wasted time. In order to do that, I developed a tool called CanXml in C++ which takes an XML-based configuration file describing the network (nodes, frames, format), and exporting it as a C header with all the networks IDs defined in here using #define with convenient names.

This tool was really helpful but when designing it, I was thinking in building a library that feature tools to manage the network, but also that can be used to debug the network.

This goal was not reached and the design I realized then is far from perfect, that's why I think it can be a great subject for my design study.

Requirements

The library must feature:

  • network management abilities (IDs generation, XML import and C-header export)
  • a way to process existing frames
  • be memory efficient (in order to be used on Linux embedded devices)

And it also need to be clean, since I want to release it under an open source license.

First implementation

In my first attempt, I was mainly trying to make things work and I did not much think about what the design should be to be a good OO design.

Here is the first UML:

CanXmlUML.png

My naming convention appeared as a bad choice when I started implementing a way to process existing frames, there is a conflict between "abstract frames" (the "family") and "concrete frames" (transfered frames), which gets really confusing when processing the code.

The way it determines IDs is too static, the policy is static while it should be more ... well, dynamic. Network/Nodes/Frames is some kind of tree, and each frame generate his ID using a simple algorithm based on the node it belongs to, the priority, ...

There is another problem for XML import and C export which is closely related. The XML file is processed recursively by objects in order to build the tree. A similar pattern is used for C export. The whole library heavily depend on one XML library (ticpp).

The pattern I used for storing the format is too complex and inefficient. Since I was looking for a memory-efficient way to handle formats of different type, bit sizes, endianness while being able to process existing frames, I produced something that is heavy and not clean.

Actual implementation

I released my work in OpenSource, the library is called CanArch (CanOE at first but this name was already taken).

UML diagram for CanArch:

CanArchUML.png

I started from scratch in order to build something clean from the beginning.

Personal tools