ADTF_DEVICE_TOOLBOX  3.12.1 (ADTF 3.18.3)
Source Code for Demo CAN Config Encoder Filter
Location
./src/examples/src/can_config_encoder/
This example shows:
This example shows:
  • howto implement a basic encoder filter
  • howto configure a basic encoder 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 encoder CAN samples
  • howto use the cSampleDecoder to access DDL elements directly by its name index (for more information take a look into the ADTF documentation)
  • howto create a streamtype from your defined struct
  • howto handle the new filtersdk, introduced in ADTF 3.5.0
Header
#pragma once
#include <adtf_filtersdk.h>
#include <adtf_base.h>
#include <a_utils.h>
#include <adtf_ucom3.h>
#include <adtf_streaming3.h>
//*************************************************************************************************
#define CID_DEMO_CAN_ENCODER_FILTER "demo_can_encoder.filter.devicetb.cid"
class cDDL2CANFilter : public adtf::filter::cFilter
{
public:
ADTF_CLASS_ID_NAME(cDDL2CANFilter, CID_DEMO_CAN_ENCODER_FILTER, "Demo CAN Config Encoder");
ADTF_CLASS_DEPENDENCIES(REQUIRE_INTERFACE(adtf::services::IReferenceClock),
cDDL2CANFilter();
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::mediadescription::decoding_sample_reader<adtf::streaming::cSingleSampleReader>* m_pReader;
adtf::streaming::ISampleWriter* m_pWriter;
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_pCANCoder;
adtf::ucom::object_ptr<adtf::devicetb::sdk::can::axle::ICANDatabase> m_pCANDatabase;
adtf::ucom::object_ptr<adtf::services::IReferenceClock> m_pClock;
adtf::devicetb::sdk::can::tSignalID getSignalID(const char * strSignalName);
};
Copyright © CARIAD SE.
Copyright © CARIAD SE.
Copyright © CARIAD SE.
axle::tSignalID tSignalID
Definition: can_types.h:296
Implementation
#include "demo_can_encoder.h"
#include <sdk/can_types.h>
#include <adtf_mediadescription.h>
#include <cstring>
#include <string>
using namespace adtf;
using namespace adtf::devicetb::sdk::can;
ADTF_PLUGIN_VERSION("Demo CAN Encoder",
devicetb,
DEVICETB_VERSION_MAJOR,
DEVICETB_VERSION_MINOR,
DEVICETB_VERSION_PATCH,
cDDL2CANFilter)
namespace {
// This is our input data
struct tSignal
{
tUInt16 ECU2_Signal8_16;
tUInt8 ECU2_Signal7_4;
tInt8 ECU2_Signal6_4;
tInt8 ECU2_Signal5_6;
tUInt16 ECU2_Signal4_10;
tUInt8 ECU2_Signal3_8;
tInt8 ECU2_Signal2_6;
tInt16 ECU2_Signal1_10;
static mediadescription::structure<tSignal> getStructure()
{
return mediadescription::structure<tSignal>("tSignal")
.Add("ECU2_Signal8_16", &tSignal::ECU2_Signal8_16)
.Add("ECU2_Signal7_4", &tSignal::ECU2_Signal7_4)
.Add("ECU2_Signal6_4", &tSignal::ECU2_Signal6_4)
.Add("ECU2_Signal5_6", &tSignal::ECU2_Signal5_6)
.Add("ECU2_Signal4_10", &tSignal::ECU2_Signal4_10)
.Add("ECU2_Signal3_8", &tSignal::ECU2_Signal3_8)
.Add("ECU2_Signal2_6", &tSignal::ECU2_Signal2_6)
.Add("ECU2_Signal1_10", &tSignal::ECU2_Signal1_10);
}
};
const std::map<std::string, std::string> mapping{
{"ECU2_Signal8_16","ECU2_Full.ECU2_Signal8_16" },
{"ECU2_Signal7_4","ECU2_Full.ECU2_Signal7_4"},
{"ECU2_Signal6_4","ECU2_Full.ECU2_Signal6_4"},
{"ECU2_Signal5_6","ECU2_Full.ECU2_Signal5_6"},
{"ECU2_Signal4_10","ECU2_Full.ECU2_Signal4_10"},
{"ECU2_Signal3_8","ECU2_Full.ECU2_Signal3_8"},
{"ECU2_Signal2_6","ECU2_Full.ECU2_Signal2_6"},
{"ECU2_Signal1_10","ECU2_Full.ECU2_Signal1_10"},
};
}
cDDL2CANFilter::cDDL2CANFilter():
m_pReader(CreateInputPin<mediadescription::decoding_sample_reader<streaming::cSingleSampleReader>>("input_ddl", tSignal::getStructure())),
m_pWriter(CreateOutputPin("output_can", devicetb::sdk::can::axle::stream_meta_type_can()))
{
SetDescription("input_ddl", "The incoming CAN content to encode.");
SetDescription("output_can", "The encoded 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("Use this filter to encode CAN data for specific signals.");
SetHelpLink("$(ADTF_DEVICE_TOOLBOX_DIR)/doc/adtf_device_toolbox_html/page_example_source_can_config_encoder.html");
}
tResult cDDL2CANFilter::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_pCANCoder));
RETURN_IF_FAILED(m_pCANSupport->GetDatabase(static_cast<tChannelID>(*m_nChannelID),m_pCANDatabase));
}
RETURN_NOERROR;
}
tResult cDDL2CANFilter::ProcessInput(streaming::ISampleReader* /*pReader*/,
const ucom::iobject_ptr<const streaming::ISample>& pSample)
{
mediadescription::cSampleDecoder oDecoder;
m_pReader->GetLastDecoder(oDecoder);
streaming::output_sample_data<tCANData> pOutput(pSample->GetTime());
std::memset(&(pOutput->sData), 0, sizeof(pOutput->sData));
m_pCANCoder->Begin(pOutput.GetDataPtr(), sizeof(tCANData));
// in this special case, we are writing just one single message
tBool messageInfoSet = tFalse;
for (const auto& it : mapping)
{
const tSignalInfo* pInfo;
m_pCANDatabase->GetSignalInfo(getSignalID(it.second.c_str()), &pInfo);
if (!messageInfoSet)
{
m_pCANCoder->SetMessageInfo(static_cast<tChannelID>(*m_nChannelID), pInfo->nMessageId, pInfo->bCANExtended);
messageInfoSet = tTrue;
}
// set the values
tSignalValue oValue;
oValue.f64Value = oDecoder.GetElement(it.first).getValue<double>();
oValue.nTypeTag = tSignalValue::TAG_FLOAT64;
m_pCANCoder->SetSignalValue(pInfo->nSignalID, &oValue);
}
// set the time
tSignalValue oTimeValue;
oTimeValue.nTypeTag = tSignalValue::TAG_UINT64;
oTimeValue.nui64Value = static_cast<decltype(oTimeValue.nui64Value)>(pSample->GetTime());
m_pCANCoder->SetSignalValue(axle::CAN_SIGNALID_HEADER_HWTIME, &oTimeValue);
m_pCANCoder->End();
m_pWriter->Write(pOutput.Release());
return m_pWriter->Flush();
}
tSignalID cDDL2CANFilter::getSignalID(const char* strSignalName)
{
tSignalID nId;
m_pCANDatabase->GetSignalID(strSignalName, &nId);
return nId;
}
Copyright 2024 CARIAD SE.
Namespace for CAN in ADTF-Devicetoolbox.
axle::tSignalValue tSignalValue
Definition: can_types.h:301
axle::tSignalInfo tSignalInfo
Definition: can_types.h:300
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.