Source Code for Project Feel


The following source files, led by gray banners, contain all the class functions needed for Project Feel.  The sections highlighted by a yellow background Color are manually entered.  Code sections with white background color are generated by the SansGUI Source Code Framework.  The source files are compiled into a dynamic linked library to be invoked by SansGUI during simulation runs.

For more details about this example, please read A Tour of SansGUI Examples in the SansGUI Getting Started Guide.

Implementation in C/C++ (MSVC)

Functions in Class Base.Object     [Go To Top]

/* Base_Object.c
 * - DLL routines for class <Component>Base.Object
 * DATE: Monday, May 22, 2000 TIME: 02:05:11 PM
 * The skeleton of this file is generated by SansGUI(tm)
 */

#include <stdio.h>

#include <string.h>

#include "SGdll.h"

#ifdef __cplusplus
extern "C"
{
#endif

SG_EXPORT SG_SIM_FUNC SG_xInit_Base_Object;
SG_EXPORT SG_SIM_FUNC SG_xEval_Base_Object;

#ifdef __cplusplus
}
#endif

/* Macros for attribute indices in class version [1.0.alpha.2] */
#define SG_NDX_FMASS 0 /* fMass - Mass */
#define SG_NDX_FX 1 /* fX - Position */
#define SG_NDX_FXDOT 2 /* fXDot - Velocity */
#define SG_NDX_FRESIST 3 /* fResist - Resistance */

/* The following link index macros are manually added as needed */
#define SG_NDX_LNK_IINFO 0 /* link info index */
#define SG_NDX_LNK_FFORCE 1 /* index for force in link */
#define SG_NDX_LNK_FVELO 2 /* index for velocity in link */

/* The following llink index macro is manually added for DT */
#define SG_NDX_SIM_FDT 10 /* index to time increment in SimControl object */

/* ============================================================
 * SG_xEval - Evaluation
 * ------------------------------------------------------------
 */
SG_RET_CODE SG_xEval_Base_Object(SG_OBJ *const self,
          SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
          SG_OBJ *const refObjs[], const INT *const piRefObjs,
          SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
          SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
          TCHAR *const cMessage, const INT iMsgLen,
          TCHAR *const cCommand, const INT iCmdLen,
          SG_FILE *const pOutFile )
{
    /* TODO: declare your local variables here */

    FLOAT* pfMass = &self->zValues[SG_NDX_FMASS].fData[0];
    FLOAT* pfX = &self->zValues[SG_NDX_FX].fData[0];
    FLOAT* pfXDot = &self->zValues[SG_NDX_FXDOT].fData[0];
    FLOAT* pfResist = &self->zValues[SG_NDX_FRESIST].fData[0];
    FLOAT fDt = simCtrl->zValues[SG_NDX_SIM_FDT].fData[0];
    FLOAT fForceIn;
    INT i;
    INT iFoundInput = 0;
    INT iFoundOutput = 0;

    if (!SG_IsSchemaOK(self->nSGobjSchema))
        return SG_R_SCHM;

    /* TODO: put your simulator code here */

    /* find force from the first input link */
    for (i = 0; i < *piLnkObjs; i++)
    {
        if (lnkObjs[i]->zValues[SG_NDX_LNK_IINFO].iData[0] == SG_LINK_IN)
        {
            iFoundInput++;
            fForceIn = lnkObjs[i]->zValues[SG_NDX_LNK_FFORCE].fData[0];
            break;
        }
    }
    if (iFoundInput == 0)
    {
        strcpy(cMessage,
               "Need to have a part that excerts force to this part." );
        return SG_R_STOP; /* severe error */
    }

    /* calculate resistance */
    *pfResist = (*pfX < 0.3f) ? 0.0f : 20.0f * (*pfXDot);

    /* push step */
    *pfXDot += ((fForceIn - *pfResist) / (*pfMass)) * fDt;
    *pfX += (*pfXDot) * fDt;

    /* deposit velocity *pfXDot to all output links */
    for (i = 0; i < *piLnkObjs; i++)
    {
        if (lnkObjs[i]->zValues[SG_NDX_LNK_IINFO].iData[0] == SG_LINK_OUT)
        {
            iFoundOutput++;
            lnkObjs[i]->zValues[SG_NDX_LNK_FVELO].fData[0] = *pfXDot;
            /* no break here because we want to go through all output links */
        }
    }
    if (iFoundOutput == 0)
    {
        strcpy(cMessage,

               "No output link is found for sending velocity stimula." );
        return SG_R_PAUS; /* let user decide to go on or stop */
    }

    return SG_R_OK;
}

Functions in Class Base.Feeling.Progress     [Go To Top]

/* Base_Feeling_Progress.c
 * - DLL routines for class <Component>Base.Feeling.Progress
 * DATE: Monday, May 22, 2000 TIME: 02:05:11 PM
 * The skeleton of this file is generated by SansGUI(tm)
 */

#include <stdio.h>

#include <math.h>
#include <string.h>

#include "SGdll.h"

#ifdef __cplusplus
extern "C"
{
#endif

SG_EXPORT SG_SIM_FUNC SG_xInit_Base_Feeling_Progress;
SG_EXPORT SG_SIM_FUNC SG_xEval_Base_Feeling_Progress;

#ifdef __cplusplus
}
#endif

/* Macros for attribute indices in class version [1.0.alpha.2] */
#define SG_NDX_FPROGRESS 0 /* fProgress - Progress */
#define SG_NDX_FPROG1 1 /* fProg1 - Progress Term 1 */
#define SG_NDX_FPROG2 2 /* fProg2 - Progress Term 2 */
#define SG_NDX_FPROG3 3 /* fProg3 - Progress Term 3 */
#define SG_NDX_FFORCE 4 /* fForce - Force Excertion */

/* The following link index macros are manually added as needed */
#define SG_NDX_LNK_IINFO 0 /* link info index */
#define SG_NDX_LNK_FFORCE 1 /* index for force in link */
#define SG_NDX_LNK_FVELO 2 /* index for velocity in link */
#define SG_NDX_LNK_FJERK 3 /* index for progress jerk in link */

/* ============================================================
 * SG_xEval - Evaluation
 * ------------------------------------------------------------
 */
SG_RET_CODE SG_xEval_Base_Feeling_Progress(SG_OBJ *const self,
          SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
          SG_OBJ *const refObjs[], const INT *const piRefObjs,
          SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
          SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
          TCHAR *const cMessage, const INT iMsgLen,
          TCHAR *const cCommand, const INT iCmdLen,
          SG_FILE *const pOutFile )
{
    /* TODO: declare your local variables here */

    FLOAT* pfProgress = &self->zValues[SG_NDX_FPROGRESS].fData[0];
    FLOAT* pfProgress1 = &self->zValues[SG_NDX_FPROG1].fData[0];
    FLOAT* pfProgress2 = &self->zValues[SG_NDX_FPROG2].fData[0];
    FLOAT* pfProgress3 = &self->zValues[SG_NDX_FPROG3].fData[0];
    FLOAT* pfForce = &self->zValues[SG_NDX_FFORCE].fData[0];
    FLOAT fVelocityIn;
    FLOAT fAbsProgJerk;
    INT i;
    INT iFoundInput = 0;
    INT iFoundOutput = 0;

    if (!SG_IsSchemaOK(self->nSGobjSchema))
        return SG_R_SCHM;

    /* TODO: put your simulator code here */

    /* find velocity from the first input link */
    for (i = 0; i < *piLnkObjs; i++)
    {
        if (lnkObjs[i]->zValues[SG_NDX_LNK_IINFO].iData[0] == SG_LINK_IN)
        {
            iFoundInput++;
            fVelocityIn = lnkObjs[i]->zValues[SG_NDX_LNK_FVELO].fData[0];
            break;
        }
    }
    if (iFoundInput == 0)
    {
        strcpy(cMessage,
               "Need to have an object that provides velocity feedback to the Progress Center." );
        return SG_R_STOP; /* severe error */
    }

    /* calculate new progress */
    *pfProgress3 = *pfProgress2;
    *pfProgress2 = *pfProgress1;
    *pfProgress1 = *pfProgress;
    *pfProgress = fVelocityIn / 0.3f;

    /* calculate absolute value of progress jerk */
    fAbsProgJerk = (FLOAT)fabs((DOUBLE)(*pfProgress - 3.0f * (*pfProgress1) +
                   3.0f * (*pfProgress2) - (*pfProgress3) ));
    /* calculate new force - *pfProgress is a fraction of good progress */
    *pfForce += (0.01f * (2.0f - (*pfProgress)) * (2.0f - (*pfForce)));

    /* deposit fAbsProgJerk and fForce to all output links */
    for (i = 0; i < *piLnkObjs; i++)
    {
        if (lnkObjs[i]->zValues[SG_NDX_LNK_IINFO].iData[0] == SG_LINK_OUT)
        {
            iFoundOutput++;
            lnkObjs[i]->zValues[SG_NDX_LNK_FFORCE].fData[0] = *pfForce;
            lnkObjs[i]->zValues[SG_NDX_LNK_FJERK].fData[0] = fAbsProgJerk;
            /* no break here because we want to go through all output links */
        }
    }
    if (iFoundOutput == 0)
    {
        strcpy(cMessage,

               "No output link is found for the Progress Center." );
        return SG_R_PAUS; /* let user decide to go on or stop */
    }

    return SG_R_OK;
}

Functions in Class Base.Feeling.Surprise     [Go To Top]

/* Base_Feeling_Surprise.c
 * - DLL routines for class <Component>Base.Feeling.Surprise
 * DATE: Monday, May 22, 2000 TIME: 02:05:11 PM
 * The skeleton of this file is generated by SansGUI(tm)
 */

#include <stdio.h>

#include <string.h>

#include "SGdll.h"

#ifdef __cplusplus
extern "C"
{
#endif

SG_EXPORT SG_SIM_FUNC SG_xInit_Base_Feeling_Surprise;
SG_EXPORT SG_SIM_FUNC SG_xEval_Base_Feeling_Surprise;

#ifdef __cplusplus
}
#endif

/* Macros for attribute indices in class version [1.0.alpha.1] */
#define SG_NDX_FA 0 /* fA - Input Scaling Factor A */
#define SG_NDX_FLA 1 /* fa - Level Scaling Factor a */
#define SG_NDX_FB 2 /* fB - Input Scaling Factor B */
#define SG_NDX_FLB 3 /* fb - Level Scaling Factor b */
#define SG_NDX_FX 4 /* fX - Level X */
#define SG_NDX_FY 5 /* fY - Level Y */
#define SG_NDX_FZ 6 /* fZ - Level Z */
#define SG_NDX_FSURP 7 /* fSurp - Surprise */

/* The following link index macros are manually added as needed */
#define SG_NDX_LNK_IINFO 0 /* link info index */
#define SG_NDX_LNK_FJERK 3 /* index for progress jerk in link */

/* The following llink index macro is manually added for DT */
#define SG_NDX_SIM_FDT 10 /* index to time increment in SimControl object */

/* ============================================================
 * SG_xEval - Evaluation
 * ------------------------------------------------------------
 */
SG_RET_CODE SG_xEval_Base_Feeling_Surprise(SG_OBJ *const self,
          SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
          SG_OBJ *const refObjs[], const INT *const piRefObjs,
          SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
          SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
          TCHAR *const cMessage, const INT iMsgLen,
          TCHAR *const cCommand, const INT iCmdLen,
          SG_FILE *const pOutFile )
{
    /* TODO: declare your local variables here */

    FLOAT* pfA = &self->zValues[SG_NDX_FA].fData[0];
    FLOAT* pfa = &self->zValues[SG_NDX_FLA].fData[0];
    FLOAT* pfB = &self->zValues[SG_NDX_FB].fData[0];
    FLOAT* pfb = &self->zValues[SG_NDX_FLB].fData[0];
    FLOAT* pfX = &self->zValues[SG_NDX_FX].fData[0];
    FLOAT* pfY = &self->zValues[SG_NDX_FY].fData[0];
    FLOAT* pfZ = &self->zValues[SG_NDX_FZ].fData[0];
    FLOAT* pfSurp = &self->zValues[SG_NDX_FSURP].fData[0];
    FLOAT fDt = simCtrl->zValues[SG_NDX_SIM_FDT].fData[0];
    FLOAT fAbsProgJerkIn;
    FLOAT fInput;
    INT i;
    INT iFoundInput = 0;

    if (!SG_IsSchemaOK(self->nSGobjSchema))
        return SG_R_SCHM;

    /* TODO: put your simulator code here */

    /* find absolute progress jerk from the first input link */
    for (i = 0; i < *piLnkObjs; i++)
    {
        if (lnkObjs[i]->zValues[SG_NDX_LNK_IINFO].iData[0] == SG_LINK_IN)
        {
            iFoundInput++;
            fAbsProgJerkIn = lnkObjs[i]->zValues[SG_NDX_LNK_FJERK].fData[0];
            break;
        }
    }
    if (iFoundInput == 0)
    {
        strcpy(cMessage,
               "Need to have an progress center that provides a jerk to the surprise Center." );
        return SG_R_STOP; /* severe error */
    }

    /* calculate one step */
    fInput = 5.0f * fAbsProgJerkIn;

    /* modeling 2 leaky capacitors */
    *pfX += (*pfA * fInput - (*pfa) * (*pfX)) * fDt;
    *pfY += (*pfB * fInput - (*pfb) * (*pfY)) * fDt;
    *pfZ = *pfX - *pfY;

    /* surprise level */
    *pfSurp = 2.0f * (*pfZ);

    return SG_R_OK;
}

Functions in Class Collection.Clock     [Go To Top]

/* Collection_Clock.c
 * - DLL routines for class <Reference>Collection.Clock
 * DATE: Monday, May 22, 2000 TIME: 02:05:11 PM
 * The skeleton of this file is generated by SansGUI(tm)
 */

#include <stdio.h>
#include "SGdll.h"

#ifdef __cplusplus
extern "C"
{
#endif

SG_EXPORT SG_SIM_FUNC SG_xInit_Collection_Clock;
SG_EXPORT SG_SIM_FUNC SG_xEval_Collection_Clock;

#ifdef __cplusplus
}
#endif

/* The following index macros are manually added for the simulation clock */
#define SG_NDX_SIM_FTIME 9 /* index to the current simulation time */
#define SG_NDX_SIM_FDT 10 /* index to time increment in SimControl object */

/* ============================================================
 * SG_xEval - Evaluation
 * ------------------------------------------------------------
 */
SG_RET_CODE SG_xEval_Collection_Clock(SG_OBJ *const self,
          SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
          SG_OBJ *const refObjs[], const INT *const piRefObjs,
          SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
          SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
          TCHAR *const cMessage, const INT iMsgLen,
          TCHAR *const cCommand, const INT iCmdLen,
          SG_FILE *const pOutFile )
{
    /* TODO: declare your local variables here */

    FLOAT* pfTime = &simCtrl->zValues[SG_NDX_SIM_FTIME].fData[0];
    FLOAT fDt = simCtrl->zValues[SG_NDX_SIM_FDT].fData[0];

    if (!SG_IsSchemaOK(self->nSGobjSchema))
        return SG_R_SCHM;

    /* TODO: put your simulator code here */

    /* advance the simulation clock */
    *pfTime += fDt;

    return SG_R_OK;
}

 


SansGUI Modeling and Simulation Environment version 1.2

Copyright 2000-2003 ProtoDesign, Inc. All rights reserved.

http://protodesign-inc.com