Home

Awesome

OpenDLV

OpenDLV is an open software environment intended to run in autonomous self-driving vehicles. It runs on the vehicle itself and should handle hardware communication, safety and override functions, sensor fusion, decision making, and visualisation. It is written entirely in standard C++, and is formally tested (unit tests and code coverage). Its focus is on code clarity, portability, and performance.

The software is based on the compact middle-ware OpenDaVINCI (http://www.opendavinci.org).

Getting started

OpenDLV is designed to work with standard C++ (C++11 or newer) and to depend on few dependencies.

Clone and build source repository

Clone this repository:

$ git clone https://github.com/chalmers-revere/opendlv.git

You can build the entire source tree:

$ cd opendlv && mkdir build && cd build
$ cmake ..
$ make

Alternatively you can use locally compiled version of OpenDaVINCI by instead running:

$ cmake -DOPENDAVINCI_DIR=/path/to/opendavinci ..

Run the software

Next, you can test the software by executing different parts of the software stack.

Terminal 1 (odsupercomponent will load and provide the configuration data and realize the other components' life-cycle management; cf. http://docs.opendavinci.org):

$ cd opendlv/build/out
$ LD_LIBRARY_PATH=lib bin/odsupercomponent --cid=111 --verbose=1

Terminal 2:

$ cd opendlv/build/out
$ LD_LIBRARY_PATH=lib bin/opendlv-system-core-diagnostics --cid=111

Development

The development of OpenDLV shall follow some principles:

Function testing

TODO: Christian please add some guidelines and perhaps an example.

Code coverage

TODO: Is this something we should test? In that case, how?

Coding standard

This section describes the coding standard used within OpenDLV. Make sure to keep the code readable, especially when it comes to variable, class, and method names. Only add meaningful comments, the code itself should be self-explanatory.

Further information about coding guidelines are found here:

General layout rules:

Naming rules:

Specific coding rules:

Here follows a code example that shows many of the aspects of the coding standard. Please also browse the code for more examples.

#ifndef EXAMPLECLASSB_HPP_
#define EXAMPLECLASSB_HPP_

// Always include standard libs first, then external libs, then our own headers.
#include <memory>
#include <string>

#include "exampleclassa.hpp"

namespace opendlv {
namespace system {

// Use forward declaration whenever possible to speed up the compilation of a translation unit (cf. J. Lakos).
class ExampleClassC;

/**
 * Class documentation goes here.
 */
class ExampleClassB : public ExampleClassA {
  public:
    ExampleClassB(std::string const &); // Argument names are omitted.
    // C++11 style method deletion. These two methods should almost always be 
    // deleted to let the compiler warn us of unwanted object copying or assignment.
    ExampleClassB(ExampleClassB const &) = delete;
    ExampleClassB &operator=(ExampleClassB const &) = delete;
    virtual ~ExampleClassB();

    std::shared_ptr<ExampleClassC> GetClassMemberPointer() const;
    bool IsValid() const;

  private:
    // Generally list methods alphabetically.
    void FancyMethod();

    // In general, start listing objects before primitives, group on type, then 
    // go alphabetically.
    std::shared_ptr<ExampleClassC> m_classMemberPointer;
    uint32_t m_classMember;
};

} // system
} // opendlv

#endif
#include <iostream>

#include "exampleclassb.hpp"
#include "exampleclassc.hpp"

// The opendlv namespace should always be in the top.
// Otherwise the structure should be relatively flat.
namespace opendlv {
namespace system {

// Note that we pass references and that const goes after type.
// All member MUST be declared in the initialization list and the constructor.
ExampleClassB::ExampleClassB(std::string const &a_arg) :
    ExampleClassA(),
    m_classMember(42),
    m_classMemberPointer(new ExampleClassC)
{
  std::cout << "This is a very long text thats prints the argument " << a_arg
      << " and breaks the line at column 80 with a double indent." 
      << std::endl; 
}

// Method brackets begins on new lines.
ExampleClassB::~ExampleClassB() 
{
}

std::shared_ptr<ExampleClassC> ExampleClassB::GetClassMemberPointer() const
{
  return m_classMemberPointer;
}

/**
 * Method documentation goes here.
 *
 */
void ExampleClassB::FancyMethod() const 
{
  uint32_t const numberOfRuns = 10;

  for (uint32_t i = 0; i < numberOfRuns; i++) {
    // Even short statements should have brackets.
    if (i > 5) {
      m_classMember += i;
    } else {
      m_classMember -= i;
    }
  }
}

// Methods should be defined const whenever they can.
bool ExampleClassB::IsValid() const
{
  return true;
}

} // system
} // opendlv