Matlab S-Function Beispiel: Double-Eingabe lesen und in Datei schreiben

Dies ist ein Beispiel für eine Matlab Level-2 S-Funktion, die eine einzelne kontinuierliche Eingabe vom Typ double liest und sie in die Datei out.txt als CSV time,value schreibt. Die Datei wird in der Funktion mdlStart geöffnet und in der Funktion mdlTerminate geschlossen. Der Eingabewert wird in der Funktion mdlUpdate gelesen.

Siehe auch Matlab Level 2 S-Function Beispiel: Sinuswelle (kontinuierliche Ausgabe).

single_input_write_to_file.cpp
#define S_FUNCTION_NAME  single_input_write_to_file
#define S_FUNCTION_LEVEL 2

#include "simstruc.h"
#include <cstdio>  // Für Dateiverarbeitung

// Konstanten definieren
#define SAMPLING_RATE 1000 // 1kHz

static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, 0);  // Keine Parameter
    ssSetNumContStates(S, 0);  // Keine kontinuierlichen Zustände
    ssSetNumDiscStates(S, 0);  // Keine diskreten Zustände
    // 1 Eingabe-Port mit 1 Element
    if (!ssSetNumInputPorts(S, 1)) return;
    ssSetInputPortWidth(S, 0, 1);  // Eingabe-Port-Breite = 1
    ssSetInputPortDataType(S, 0, SS_DOUBLE);
    ssSetInputPortComplexSignal(S, 0, COMPLEX_NO);

    ssSetInputPortRequiredContiguous(S, 0, 1);  // Zusammenhängender Eingabe-Port-Speicher erforderlich
    // ssSetInputPortDirectFeedThrough(S, 0, 1);  // Direkter Feedthrough

    // Keine Ausgabe-Ports
    if (!ssSetNumOutputPorts(S, 0)) return;
    // Sample times
    ssSetNumSampleTimes(S, 1);  // Einzelne Sample-Time

    // Work-Vektoren
    ssSetNumRWork(S, 0);  // Real-Work-Vektor
    ssSetNumIWork(S, 0);  // Integer-Work-Vektor
    ssSetNumPWork(S, 1);  // Pointer-Work-Vektor für File-Pointer
    ssSetNumModes(S, 0);  // Mode-Vektor
    ssSetNumNonsampledZCs(S, 0);  // Nulldurchgänge

    // S-Function-Block zur Verwendung in einem Real-Time Workshop-generierten Modell befähigen
    ssSetOptions(S, 0);
}

#define MDL_START
static void mdlStart(SimStruct *S) {
    // Datei "out.txt" zum Schreiben öffnen
    FILE *file = fopen("out.txt", "w");
    if (file == NULL) {
        ssSetErrorStatus(S, "Failed to open file 'out.txt'");
        return;
    }

    const real_T *u = (const real_T*) ssGetInputPortSignal(S, 0);  // Eingabe-Zeiger
    real_T input_value = u == nullptr ? -1 : u[0];  // Eingabewert lesen

    ssSetPWorkValue(S, 0, file);
}

// Funktion: mdlInitializeSampleTimes =========================================
// Zusammenfassung:
//    Sample-Times auf 1ms (1kHz) initialisieren
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, 1.0 / SAMPLING_RATE);  // 1kHz Sampling-Rate
    ssSetOffsetTime(S, 0, 0.0);
}

// Für dieses Beispiel nicht benötigt
static void mdlOutputs(SimStruct *S, int_T tid) {
    // Nichts tun
}

#define MDL_UPDATE
static void mdlUpdate(SimStruct *S, int_T tid)
{
    real_T time = ssGetT(S);  // Aktuelle Simulationszeit holen

    // Eingabewert holen
    const real_T *u = (const real_T*) ssGetInputPortRealSignal(S, 0);  // Eingabe-Zeiger
    real_T input_value = u == nullptr ? -1 : u[0];  // Eingabewert lesen

    // File-Pointer aus dem Work-Vektor holen
    FILE *file = (FILE*) ssGetPWorkValue(S, 0);
    if (file != NULL) {
        fprintf(file, "%f,%f\n", time, input_value);  // Eingabewert in die Datei schreiben
    }
}

static void mdlTerminate(SimStruct *S)
{
    // Datei schließen
    FILE *file = (FILE*) ssGetPWorkValue(S, 0);
    if (file != NULL) {
        fclose(file);
    }
}

// Erforderlicher S-Function-Trailer
#ifdef MATLAB_MEX_FILE
#include "simulink.c"   // MEX-File-Interface-Mechanismus
#else
#include "cg_sfun.h"    // Code-Generierungs-Interface
#endif

Ähnliche Beiträge nach Kategorie: