Skip to content

Commit

Permalink
update dbcppp
Browse files Browse the repository at this point in the history
  • Loading branch information
dongdongO committed May 3, 2024
1 parent a7a195e commit 3dce46c
Show file tree
Hide file tree
Showing 11,776 changed files with 2,327,251 additions and 45 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
21 changes: 10 additions & 11 deletions control_ws/src/stanley/include/stanley/canprotocol/can_protocol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,19 @@
#include <unordered_map>
#include <memory>
#include <chrono>
#include <string>
#include <unordered_map>

class CANReceiver {
class CANSender {
public:
CANReceiver(const std::string& dbc_file, const std::string& can_interface);
~CANReceiver();
void receiveMessages();
CANSender(const std::string& dbc_file, const std::string& can_interface);
~CANSender();

private:
void printMessage(const dbcppp::IMessage& msg, const can_frame& frame);

std::unique_ptr<dbcppp::INetwork> net;
std::unordered_map<uint64_t, const dbcppp::IMessage*> messages;
int sock;
uint64_t last_received;
std::chrono::time_point<std::chrono::steady_clock> last_received_time;
std::chrono::seconds message_timeout;
uint64_t target_message_id;
double speed_value;
std::shared_ptr<const dbcppp::INetwork> net;
std::unordered_map<uint64_t, const dbcppp::IMessage*> messages;
};

108 changes: 108 additions & 0 deletions control_ws/src/stanley/include/stanley/dbcppp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
cmake_minimum_required(VERSION 3.12)

project("dbcppp" VERSION 3.8.0)

# CONFIGURATION

set(CMAKE_CXX_STANDARD 17)
option(build_kcd "Enable support for KCD parsing" ON)
option(build_tools "Build dbcppp utility application" ON)

option(build_tests "Build tests" ON)
option(build_examples "Build examples" ON)


# DEPENDENCIES & Requirements

find_package(Boost)

if(NOT Boost_FOUND)
message(WARNING "Boost not found. Using libdbcppp boost (third-party/boost)")
include_directories("third-party/boost")
endif()

# kcd is an xml based can database
message("kcd enabled: ${build_kcd}")

if(build_kcd)
add_compile_definitions(ENABLE_KCD)

# LibXml2

find_package(LibXml2)

if (NOT LibXml2_FOUND)
message(WARNING "LibXml2 was not found. Using libdbcppp LibXml2 (third-party/libxml2)")
set(LIBXML2_WITH_ICONV OFF)
set(LIBXML2_WITH_LZMA OFF)
set(LIBXML2_WITH_PYTHON OFF)
set(LIBXML2_WITH_ZLIB OFF)
set(LIBXML2_WITH_TESTS OFF)
add_subdirectory(third-party/libxml2)
endif()

# libxmlmm (no find package because it is certainly not installed

add_subdirectory("third-party/libxmlmm")
target_include_directories(libxmlmm PUBLIC third-party/libxmlmm/libxmlmm ${LIBXML2_INCLUDE_DIR})
endif()


# CREATE LIBRARY

file(GLOB include "include/dbcppp/*.h")
file(GLOB headers "src/*.h")
file(GLOB sources "src/*.cpp")

add_library(${PROJECT_NAME} SHARED ${include} ${headers} ${sources})


# CONFIGURE LIBRARY

if (build_kcd)
target_link_libraries(${PROJECT_NAME} PUBLIC libxmlmm)
endif()

set_target_properties(${PROJECT_NAME} PROPERTIES
SOVERSION ${PROJECT_VERSION}
PUBLIC_HEADER "${include}"
)

target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/dbcppp>
$<INSTALL_INTERFACE:include/dbcppp>
include/
)

# INSTALL LIBRARY

install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include/dbcppp
)


# ADDITIONAL: Tools, Tests & Examples

if (build_tools)
add_subdirectory(third-party/cxxopts)
add_subdirectory(tools/dbcppp)
endif()

if (build_tests)
add_subdirectory(tests)
endif()

if (build_examples)
add_subdirectory(examples)
endif()

# PACKAGE (useful for debugging install, use make package)

set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY NO)
set(CPACK_VERBATIM_VARIABLES YES)
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES \\.git/ build/ ".*~$")
include(CPack)
21 changes: 21 additions & 0 deletions control_ws/src/stanley/include/stanley/dbcppp/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020 xR3b0rn

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
176 changes: 176 additions & 0 deletions control_ws/src/stanley/include/stanley/dbcppp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
[![Build Status](https://github.com/xR3b0rn/dbcppp/actions/workflows/linux.yml/badge.svg?branch=master)
# dbcppp
A C/C++ DBC file parser based on `boost.spirit`. This library is designed for decoding performance.
# Features
* very fast decoding
* verbose parser output in error case
* DBC is editable through C/C++ interface exported from the library
* read/write DBC file
* decode functionality for frames of arbitrarily byte length
* [cantools](https://github.com/eerimoq/cantools) like decoding
* [KCD](https://github.com/julietkilo/kcd) file format support


# Getting started
## Build & Install
```
git clone --recurse-submodules https://github.com/xR3b0rn/dbcppp.git
cd dbcppp
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j
make RunTests
make install
ldconfig # on Unix-systems only
```

# Usage example
## Command line tool
### dbc2
```
# generate C source from DBC/KCD
dbcparser dbc2 --dbc=file.dbc --format=C
# beauty or merge DBC/KCD
dbcparser dbc2 --dbc=file1.dbc --dbc=file2.kcd --format=DBC
# print DBC/KCD in human readable format
dbcparser dbc2 --dbc=file1.dbc --dbc=file2.kcd --format=human
```
### decode
[cantools](https://github.com/eerimoq/cantools) like decoding:
```
candump any | dbcppp decode --bus=vcan0,file1.dbc --bus=vcan1,file2.dbc
```
## Library
* [Examples](https://github.com/xR3b0rn/dbcppp/tree/master/examples)
* `C++`
```C++
#include <fstream>
#include <dbcppp/Network.h>
int main()
{
std::unique_ptr<dbcppp::INetwork> net;
{
std::ifstream idbc("your.dbc");
net = dbcppp::INetwork::LoadDBCFromIs(idbc);
}
std::unordered_map<uint64_t, const dbcppp::IMessage*> messages;
for (const dbcppp::IMessage& msg : net->Messages())
{
messages.insert(std::make_pair(msg.Id(), &msg));
}
can_frame frame;
while (1)
{
receive_frame_data(&frame);
auto iter = messages.find(frame.can_id);
if (iter != messages.end())
{
const dbcppp::IMessage* msg = iter->second;
std::cout << "Received Message: " << msg->Name() << "\n";
for (const dbcppp::ISignal& sig : msg->Signals())
{
const dbcppp::ISignal* mux_sig = msg->MuxSignal();
if (sig.MultiplexerIndicator() != dbcppp::ISignal::EMultiplexer::MuxValue ||
(mux_sig && mux_sig->Decode(frame.data) == sig.MultiplexerSwitchValue()))
{
std::cout << "\t" << sig.Name() << "=" << sig.RawToPhys(sig.Decode(frame.data)) << sig.Unit() << "\n";
}
}
}
}
}
```
* `C`
```C
#include <stdio.h>
#include <dbcppp/CApi.h>
int main()
{
const dbcppp_Nework* net = dbcppp_NetworkLoadDBCFromFile("your.dbc");
if (net)
{
can_frame frame;
while (1)
{
receive_can_frame_from_somewhere(&frame);
const dbcppp_Message* msg = nullptr;
auto n_msgs = dbcppp_NetworkMessages_Size(net);
for (uint64_t i = 0; i < n_msgs; i++)
{
const dbcppp_Message* msg = dbcppp_NetworkMessages_Get(i);
if (dbcppp_MessageId(tmp) == frame.can_id)
{
printf("Received message: %s\n", dbcppp_MessageGetName(msg));
dbcppp_MessageForEachSignal(msg, print_signal_data, &frame);
for (uint64_t i = 0; i < dbcppp_MessageSignals_Size(msg); i++)
{
const dbcppp_Signal* sig = dbcppp_MessageSignals_Get(msg, i);
uint64_t raw = dbcppp_SignalDecode(sig, frame.data);
double phys = dbcppp_SignalRawToPhys(sig, raw);
printf("\t%s=%f\n", dbcppp_SignalName(sig), phys);
}
}
}
}
}
dbcppp_NetworkFree(net);
}
```
# DBC data types
## Supported
* version
* new_symbols
* bit_timing
* nodes
* value_tables
* messages
* message_transmitters
* environment_variables
* environment_variables_data
* signal_types
* comments
* attribute_definitions
* attribute_defaults
* attribute_values
* value_descriptions
* signal_extended_value_type_list
* signal_groups
* signal_multiplexer_value
## Not supported yet
* sigtype_attr_list
* signal_type_refs
# Decode-function
The signals decode function is using prestored masks and fixed offsets to speed up calculation, therefore the decoding-function should be almost as fast as a code generated decode function would be. The assembly of the `decode`-function on its critical path (signed and byte swap must happen) looks like this (VS19 10.0.18362.0 compiler):
```
template <Alignment aAlignment, Signal::ByteOrder aByteOrder, Signal::ValueType aValueType, Signal::ExtendedValueType aExtendedValueType>
double template_decode(const Signal* sig, const void* nbytes) noexcept
00007FF8025BCA73 mov rax,rcx
00007FF8025BCA76 mov rcx,qword ptr [rcx+140h]
00007FF8025BCA7D xorps xmm0,xmm0
00007FF8025BCA80 bswap r8
00007FF8025BCA83 shr r8,cl
00007FF8025BCA86 and r8,qword ptr [rax+130h]
00007FF8025BCA8D mov rcx,qword ptr [rax+138h]
00007FF8025BCA94 mov rax,rcx
00007FF8025BCA97 or rcx,r8
00007FF8025BCA9A and rax,r8
00007FF8025BCA9D cmove rcx,r8
00007FF8025BCAA1 cvtsi2sd xmm0,rcx
00007FF8025BCAA6 ret
```
On the best path (no byteswap must take place and ExtendedValueType == Double) the decode function only has 5 instructions:
```
template <Alignment aAlignment, Signal::ByteOrder aByteOrder, Signal::ValueType aValueType, Signal::ExtendedValueType aExtendedValueType>
double template_decode(const Signal* sig, const void* nbytes) noexcept
00007FF8025BCAF0 mov rax,qword ptr [rdx]
00007FF8025BCAF3 mov qword ptr [rsp+8],rcx
00007FF8025BCAF8 mov qword ptr [sig],rax
00007FF8025BCAFD movsd xmm0,mmword ptr [data]
00007FF8025BCB03 ret
```
# Known issues
* tests for decoding function for float/double is failing on some machines (currently only confirmed for System/s390x)
# Similar projects
* [Vector_DBC](https://bitbucket.org/tobylorenz/vector_dbc/src/master/) Does basically the same, the biggest difference is that it uses `bison` instead of `boost::spirit` for grammar parsing
* [CAN BUS tools in Python 3 (cantools)](https://github.com/eerimoq/cantools)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")

file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove $ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif(NOT "${rm_retval}" STREQUAL 0)
else(EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif(EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

include_directories(
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
)

file(GLOB header
"*.h"
)
file(GLOB src
"*.cpp"
)

add_executable(${PROJECT_NAME}_ExampleBasicUsage ${header} ${src})
set_target_properties(${PROJECT_NAME}_ExampleBasicUsage PROPERTIES LINKER_LANGUAGE CXX)
set_property(TARGET ${PROJECT_NAME}_ExampleBasicUsage PROPERTY CXX_STANDARD 17)
add_dependencies(${PROJECT_NAME}_ExampleBasicUsage ${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME}_ExampleBasicUsage ${PROJECT_NAME} ${Boost_LIBRARIES})
Loading

0 comments on commit 3dce46c

Please sign in to comment.