#include "demo_can_generator.h"
using namespace adtf::util;
using namespace adtf::ucom;
using namespace adtf::streaming;
ADTF_PLUGIN_VERSION("Can generator",
devicetb,
DEVICETB_VERSION_MAJOR,
DEVICETB_VERSION_MINOR,
DEVICETB_VERSION_PATCH,
cCanGenerator)
constexpr const char* description =
R"(Use this Streaming Source to generate a in source predefined CAN Sample.
)";
cCanGenerator::cCanGenerator():
{
SetDescription("can_output", "The outcoming CAN sample stream containing the configured message.");
m_nTimer.SetDescription("Generation rate in [ms]");
RegisterPropertyVariable("Timer", m_nTimer);
m_nMessageID.SetDescription("The ID of the message.");
RegisterPropertyVariable("CAN Message ID", m_nMessageID);
m_nChannelID.SetDescription("The channel and database which should be used.");
RegisterPropertyVariable("CAN Channel ID", m_nChannelID);
SetDescription(description);
SetHelpLink("$(ADTF_DEVICE_TOOLBOX_DIR)/doc/adtf_device_toolbox_html/page_example_source_can_generator.html");
}
tResult cCanGenerator::Init()
{
object_ptr<ICANSupport> pCANSrv;
RETURN_IF_FAILED(_runtime->GetObject(m_pClock));
RETURN_IF_FAILED(_runtime->GetObject(pCANSrv));
RETURN_IF_FAILED(pCANSrv->GetDatabase(m_nChannelID, m_pCanDb));
RETURN_IF_FAILED(pCANSrv->CreateCoder(m_pMediaCoderCan));
return cSampleStreamingSource::Init();
}
tResult cCanGenerator::StartStreaming()
{
auto strMyName = get_named_graph_object_full_name(*this);
m_oLooper = system::kernel_timer(strMyName, m_nTimer * 1000, 0, &cCanGenerator::ProcessSample, this);
return cSampleStreamingSource::StartStreaming();
}
tResult cCanGenerator::StopStreaming()
{
m_oLooper.Stop();
return cSampleStreamingSource::StopStreaming();
}
tResult cCanGenerator::ProcessSample()
{
RETURN_IF_FAILED(alloc_sample(m_pSample));
RETURN_IF_FAILED(m_pSample->WriteLock(m_pBufferLock,
sizeof(
tCANData)));
cMemoryBlock::MemZero(m_pBufferLock->GetPtr(), m_pBufferLock->GetSize());
RETURN_IF_FAILED(m_pSample->SetTime(m_pClock->GetStreamTime()));
RETURN_IF_FAILED(m_pMediaCoderCan->Begin(m_pBufferLock.Get()));
RETURN_IF_FAILED(m_pCanDb->GetMessageInfo(m_nMessageID, tTrue, &oMessageInfo));
RETURN_IF_FAILED(m_pMediaCoderCan->SetMessageInfo(m_nChannelID, m_nMessageID, oMessageInfo->bCANExtended));
for (tUInt32 nSignalCounter = 0; nSignalCounter < oMessageInfo->nSignalCount; nSignalCounter++)
{
tSignalInfo oSignalInfo = oMessageInfo->psSignalInfo[nSignalCounter];
auto oSignalValue = getSignalValueFromSignalInfo(oSignalInfo);
if (IS_FAILED(m_pMediaCoderCan->SetSignalValue(oSignalInfo.nSignalID, &oSignalValue)))
LOG_ERROR("could not set signal value for signal %s", oSignalInfo.strSignalName);
}
RETURN_IF_FAILED(m_pMediaCoderCan->End());
RETURN_IF_FAILED(m_pWriter->Write(m_pSample));
return m_pWriter->ManualTrigger();
}
{
switch (oSignalInfo.nType)
{
case tSignalRawDataType::DT_CAN_UNSIGNED:
oSignalValue.nTypeTag = tSignalValue::TAG_UINT64;
oSignalValue.nui64Value = (tUInt64)oSignalInfo.nStartRawValue;
break;
case tSignalRawDataType::DT_CAN_SIGNED:
oSignalValue.nTypeTag = tSignalValue::TAG_INT64;
oSignalValue.ni64Value = (tInt64)oSignalInfo.nStartRawValue;
break;
case tSignalRawDataType::DT_CAN_IEEE_FLOAT:
oSignalValue.nTypeTag = tSignalValue::TAG_FLOAT32;
oSignalValue.f32Value = (tFloat32)oSignalInfo.nStartRawValue;
break;
case tSignalRawDataType::DT_CAN_IEEE_DOUBLE:
oSignalValue.nTypeTag = tSignalValue::TAG_FLOAT64;
oSignalValue.f64Value = (tFloat64)oSignalInfo.nStartRawValue;
break;
default: break;
}
return oSignalValue;
}
Namespace for functionality provided by V3.0.0.
axle::tMessageInfo tMessageInfo
axle::tSignalValue tSignalValue
axle::tSignalInfo tSignalInfo
axle::tCANData tCANData
The CAN data structure is used by CAN MediaSamples use following code within your filter:
axle::stream_meta_type_can stream_meta_type_can
Definition of Stream Meta Type CAN Messages.