ADTF_DEVICE_TOOLBOX  3.12.1 (ADTF 3.18.3)
Source Code for Demo CAN Config Decoder Filter
Location
./src/examples/src/can_config_decoder/
This example shows:
  • howto implement a basic decoder filter
  • howto configure a basic decoder filter including its input and output pins
  • howto use the adtf::devicetb::sdk::can::ICANSupport interface to work with a CAN database
  • howto use the adtf::devicetb::sdk::can::ICANCoder interface to decoder CAN samples
  • howto use the SampleCodecFactory to access DDL elements directly by its name index
Header
#pragma once
#include <adtf_filtersdk.h>
#include <adtf_ucom3.h>
#include <adtf_mediadescription.h>
#include <cc_decoder.h>
//*************************************************************************************************
#define CID_DEMO_CAN_DECODER_FILTER "demo_can_decoder.filter.devicetb.cid"
class cCAN2DDLFilter : public adtf::filter::cFilter
{
public:
ADTF_CLASS_ID_NAME(cCAN2DDLFilter, CID_DEMO_CAN_DECODER_FILTER, "Demo CAN Config Decoder");
ADTF_CLASS_DEPENDENCIES(REQUIRE_INTERFACE(adtf::services::IReferenceClock),
cCAN2DDLFilter();
tResult Init(adtf::filter::cFilter::tInitStage eStage) override;
// This method will be called when a trigger occours via our input Pin.
tResult ProcessInput(adtf::streaming::ISampleReader* pReader,
const adtf::ucom::iobject_ptr<const adtf::streaming::ISample>& pSample) override;
private:
adtf::filter::cPinReader* m_pReader;
adtf::mediadescription::encoding_sample_writer<>* m_pWriter;
// properties
adtf::base::property_variable<tUInt> m_nChannelID = 1;
adtf::ucom::object_ptr<adtf::devicetb::sdk::can::axle::ICANSupport> m_pCANSupport;
adtf::ucom::object_ptr<adtf::devicetb::sdk::can::axle::ICANCoder> m_pDecoder;
adtf::mediadescription::md_sample_data_factory<output_ddl> m_oSampleDataFactory;
};
Copyright © CARIAD SE.
Copyright © CARIAD SE.
Implementation
#include "demo_can_decoder.h"
#include <sdk/can_types.h>
#include <cstring>
#include <string>
#include <map>
using namespace adtf;
using namespace adtf::devicetb::sdk::can;
ADTF_PLUGIN_VERSION("Demo CAN Decoder",
devicetb,
DEVICETB_VERSION_MAJOR,
DEVICETB_VERSION_MINOR,
DEVICETB_VERSION_PATCH,
cCAN2DDLFilter)
namespace {
// our predefined mapping
const std::map<std::string, std::string> mapping{
{ "ECU2_Full.ECU2_Signal8_16","ECU2_Signal8_16" },
{ "ECU2_Full.ECU2_Signal7_4","ECU2_Signal7_4" },
{ "ECU2_Full.ECU2_Signal6_4","ECU2_Signal6_4" },
{ "ECU2_Full.ECU2_Signal5_6","ECU2_Signal5_6" },
{ "ECU2_Full.ECU2_Signal4_10","ECU2_Signal4_10" },
{ "ECU2_Full.ECU2_Signal3_8","ECU2_Signal3_8" },
{ "ECU2_Full.ECU2_Signal2_6","ECU2_Signal2_6" },
{ "ECU2_Full.ECU2_Signal1_10","ECU2_Signal1_10" },
};
}
cCAN2DDLFilter::cCAN2DDLFilter():
m_pReader(CreateInputPin("input_can", devicetb::sdk::can::stream_meta_type_can())),
m_pWriter(CreateOutputPin<mediadescription::encoding_sample_writer<>>("output_ddl", mediadescription::description<output_ddl>()))
{
SetDescription("input_can", "The CAN sample stream to decode.");
SetDescription("output_ddl", "The decoded content of the CAN sample stream.");
m_nChannelID.SetDescription("Channel-ID for the desired can database, made available by can service.");
m_nChannelID.SetValidRange(CAN_CHANNEL_MIN, CAN_CHANNEL_MAX);
RegisterPropertyVariable("ChannelID", m_nChannelID);
SetDescription("Demo filter for decoding CAN samples into previous specified signals.");
SetHelpLink("$(ADTF_DEVICE_TOOLBOX_DIR)/doc/adtf_device_toolbox_html/page_example_source_can_config_decoder.html");
}
tResult cCAN2DDLFilter::Init(filter::cFilter::tInitStage eStage)
{
if (filter::cFilter::tInitStage::StageNormal == eStage)
{
RETURN_IF_FAILED(_runtime->GetObject(m_pCANSupport));
RETURN_IF_FAILED(m_pCANSupport->CreateCoder(m_pDecoder));
}
RETURN_NOERROR;
}
tResult cCAN2DDLFilter::ProcessInput(streaming::ISampleReader* /*pReader*/,
const ucom::iobject_ptr<const streaming::ISample>& pSample)
{
streaming::sample_data<tCANData> pData(pSample);
m_pDecoder->Begin(pData.GetDataPtr(),sizeof(tCANData));
auto oGeneratedData = m_pWriter->MakeSample(pData.GetTimeNs());
// decode the sample via the decoder
tChannelID nChannel = static_cast<tChannelID>(*m_nChannelID);
tMessageID nCANMessageID;
tBool bExtended = tFalse;
if (IS_OK(m_pDecoder->GetMessageInfo(&nChannel, &nCANMessageID, &bExtended)))
{
ucom::object_ptr<ICANDatabase> pDatabase;
RETURN_IF_FAILED(m_pDecoder->GetDatabase(nChannel, pDatabase));
const tMessageInfo* pInfo = nullptr;
if (IS_OK(pDatabase->GetMessageInfo(nCANMessageID, bExtended, &pInfo)))
{
if (util::cString("ECU2_Full").Compare(pInfo->strMessageName) == 0)
{
for (const auto& it : mapping)
{
util::cString sgnNm = it.first.c_str();
tSignalID nSignalID;
pDatabase->GetSignalID(sgnNm, &nSignalID);
tSignalValue sSignalValue;
if (IS_OK(m_pDecoder->GetSignalValue(nSignalID, &sSignalValue)))
{
util::cVariant oValue;
auto oElement = oGeneratedData.GetElement(it.second);
switch (sSignalValue.nTypeTag)
{
case tSignalValue::TAG_RAW_VALUE:
oElement.setValue(sSignalValue.n64RawValue);
break;
case tSignalValue::TAG_FLOAT64:
oElement.setValue(sSignalValue.f64Value);
break;
case tSignalValue::TAG_UINT64:
oElement.setValue(sSignalValue.nui64Value);
break;
case tSignalValue::TAG_INT64:
oElement.setValue(sSignalValue.ni64Value);
break;
case tSignalValue::TAG_UINT32:
oElement.setValue(sSignalValue.nui32Value);
break;
case tSignalValue::TAG_INT32:
oElement.setValue(sSignalValue.ni32Value);
break;
case tSignalValue::TAG_FLOAT32:
oElement.setValue(sSignalValue.f32Value);
break;
default:
break;
}
}
}
// if a signal from a can message was saved into our newly created sample,
// send it to the output pin
m_pWriter->Write(oGeneratedData.Release());
}
}
}
// reset the data pointer to the current sample payload
return m_pDecoder->End();
}
Copyright © CARIAD SE.
Copyright 2024 CARIAD SE.
Namespace for CAN in ADTF-Devicetoolbox.
axle::tMessageInfo tMessageInfo
Definition: can_types.h:302
axle::tSignalValue tSignalValue
Definition: can_types.h:301
axle::tCANData tCANData
The CAN data structure is used by CAN MediaSamples use following code within your filter:
Definition: can_types.h:294
axle::stream_meta_type_can stream_meta_type_can
Definition of Stream Meta Type CAN Messages.
ADTF - Namespace.
Copyright © CARIAD SE.