sil-kit icon indicating copy to clipboard operation
sil-kit copied to clipboard

Silkit integration in fmu

Open abhisheksajnani opened this issue 3 months ago • 7 comments

I am trying to integrate sil-kit (CAN apis) in a sample virtual ECU code and create an fmu out of it. In this way I am trying to create 2 fmus, FMU1 will Tx the CAN frames and FMU2 will Rx the CAN frames.

I am able to generate the fmus and they are running in co-simulation environment however I could notice that the CAN communication happens only once in the init step only and during the do-step CAN message is not transmitted / received.

The structure of my code looks like this:

void FrameHandler(const SilKit::Services::Can::CanFrameEvent& frameEvent)
{
 /*extract the data from frameevent frame and pass to upper layer software (code not shared here)*/
}

init()
{
    _registryUri = "silkit://localhost:8500";
    CANParticipant = SilKit::CreateParticipant(SilKit::Config::ParticipantConfigurationFromString(""), "RestBus", _registryUri);
    CanController = CANParticipant->CreateCanController("CAN1", "CAN1");
	
    CanController->AddFrameHandler(
        [](SilKit::Services::Can::ICanController* ctrl, const SilKit::Services::Can::CanFrameEvent& frameEvent) {
            FrameHandler(frameEvent);
        });
	
    CanController->Start();
	
    LifecycleService = CANParticipant->CreateLifecycleService({SilKit::Services::Orchestration::OperationMode::Autonomous});
		
    LifecycleService->StartLifecycle();
}

step()
{
/* pack the payload in frame42 (code is not shared here)*/
	CanController->SendFrame(std::move(frame42));
}

terminate()
{
 LifecycleService->Stop("User requested to stop the simulation");
}

where is the issue?

abhisheksajnani avatar Apr 02 '24 12:04 abhisheksajnani

Hello @abhisheksajnani. To diagnose your issue, you can activate logging in your applications by using the configuration string below:

Logging:
  Sinks:
    - Level: Debug
      Type: Stdout

I don't see any issue in the code you have shown, off the top of my head.

VDanielEdwards avatar Apr 02 '24 13:04 VDanielEdwards

I took the liberty to edit your issue and use the code-block.

VDanielEdwards avatar Apr 02 '24 13:04 VDanielEdwards

Hello @VDanielEdwards, thanks a lot for your quick response. I have a new observation today, the CAN communication is working when I chose the simulation mode as real time. As SiL can run in adaptive time also (faster or slower than real time) and in this mode the CAN communication is not working.

My new question is whether SiLkit supports adaptive time and if yes then how to enable it? In most of the demos i have seen from vector, it is always based on async mode. How to make silkit registry in sync with fmus running in adaptive time?

One more observation is that during the terminate function from my code the simulation is crashing because of Null pointer defrence. is there any other way to stop the communication or I am doing something wrong here?

Thanks in advance!

abhisheksajnani avatar Apr 03 '24 08:04 abhisheksajnani

Hello @abhisheksajnani!

Regarding the simulation mode, are you using CANoe? In this case you might not need to package your code as an FMU, but you can build you application similar to the demo applications.

Apart from that, if you use the Trace log-level in the configuration you will get a log message whenever a CanFrame is sent or received. Utilizing this, you can check if the issue is at the sender or the receiver end.

Regarding adaptive time, take a look at the documentation on time-sync and, e.g., the CAN demo application which shows how to use it to synchronize time across SIL Kit participants.

The registry is not involved in the time-synchronization mechanism.

Regarding the null-pointer dereference, is it possible that the CANParticipant object is destroyed before the call to terminate? The pointers retrieved from (e.g.) CreateLifecycleService and CreateCanController have the same lifetime as the participant object they are retrieved from.

VDanielEdwards avatar Apr 03 '24 08:04 VDanielEdwards

Hello @VDanielEdwards , I had a look at the documentation on time-sync and i have a doubt. Is "timeSyncService->SetSimulationStepHandler()" is called automatically as a call back function or we need to call it under fmi step function?

  • If its a call back function then how it is synchronized with the co-simulation tool running this fmu? or how the simulation time and fmu time is synchornised?
  • what is the reference for the 5ms step size mentioned in the CAN demo example. is it the PC clock or the simulation time?

is it possible for you to create a dummy code structure (init, step and terminate) like i did for coordinated mode and this would be a great reference for me.

Thanks in advance!

abhisheksajnani avatar Apr 03 '24 12:04 abhisheksajnani

Hello @abhisheksajnani.

First of all, did you try to run your original code (without time-sync) with the logging enabled? If you can, please post the output then we can help you analysing it.

Regarding the time-synchronization:

The function set with the SetSimulationStepHandler call is called from within SIL Kit whenever a simulation step starts.

Synchronization of SIL Kits simulation-step can be achieved using the SetSimulationStepHandlerAsync call and the corresponding CompleteSimulationStep call. This allows you to return from the callback function and explicitly complete the simulation step after your code has run. This also means that you will have to synchronize the two steps using, e.g., a std::condition_variable.

In pseude-code this would look like the following:

YourSimulationStepHandler(...):
  // signal simulation-step

tick():
  // wait for SIL Kit simulation-step signal and reset it
  // ... execute tick ...
  // call CompleteSimulationStep

As I'm not particularly familiar with FMUs, maybe @DominikHerr has additional insigths regarding your issue.

VDanielEdwards avatar Apr 04 '24 06:04 VDanielEdwards

Hello @abhisheksajnani,

I cannot provide much more feedback regarding a solution with your implementation based on the currently available information than @VDanielEdwards, but I was wondering if there is a reason to use CAN frames instead of DataPublishers and DataSubscribers (which do not require to additional data wrapping).

We also provide an open source solution called "FMU Importer" that allows to run an FMU as a participant in a SIL Kit setup. It handles the time synchronization and data exchange between FMI 2.0/3.0 FMUs and SIL Kit. It is also available on GitHub (https://github.com/vectorgrp/sil-kit-fmu-importer). Maybe the FMU Importer can solve your issues or provide you with some ideas how to do the synchronization based on its documentation.

Let us know if that works for you.

DominikHerr avatar Apr 04 '24 11:04 DominikHerr

Closing this issue due to inactivity. Please feel to re-open it.

VDanielEdwards avatar Apr 26 '24 12:04 VDanielEdwards