carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程

carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程

win10
matlab 2020b
carmaker 10.2.2

在carmaker/matlab仿真中,carmaker提供了摄像头、雷达等传感器模型,能够将场景中在传感器覆盖范围内的目标传送到simulink中供给算法模块利用。但是对于车道线信息,Line Sensor只能将车道类型、距离等属性信息,缺少对于车道线本身点的位置信息。而对于有横向控制的算法功能如LKA等就需要提供车道线的点或者车道线拟合成的多项式方程。对于这种情况,可以通过carmaker的拓展功能将当前车道左右侧车道线的点以UAQ的形式传送到simulink中,再做进一步的拟合,以便后续功能模块使用。
还是以前本系列前两篇内容中生成的工程文件为基础做演示。
1 由于在第一篇中创建工程时只勾选了Carmaker for Simulink Extras的选项,文件夹中缺少拓展的模块。所以需要重新在创建一次工程以补充缺少的模块。在工程文件夹下打开的simulink模型中通过点击GUI图标打开carmaker主界面。点击File -> Project Folder -> Create Project,将工程文件夹切换到之前建立的文件夹处,然后勾选所有五个选项,点击OK。警告框中选择Continue。此时在项目文件夹下会多出来一个src文件夹。
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第1张图片
2 打开工程文件夹下的src文件夹,发现这是一个visual studio的工程文件。使用visual studio打开CarMaker.sln文件。选择项目->重定目标解决方案。在跳出的重定向目标中点击确定。点击生成->生成解决方案,在输出框中会出现生成成功的字样。
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第2张图片

carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第3张图片
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第4张图片
3 将下面三个文件放到src文件夹下,替换原来的文件。
User.c

/*
******************************************************************************
**  CarMaker - Version 10.2.2
**  Vehicle Dynamics Simulation Toolkit
**
**  Copyright (C)   IPG Automotive GmbH
**                  Bannwaldallee 60             Phone  +49.721.98520.0
**                  76185 Karlsruhe              Fax    +49.721.98520.99
**                  Germany                      WWW    www.ipg-automotive.com
******************************************************************************
**
** Functions
** ---------
**
** Initialization
**
**	User_Init_First ()
**	User_PrintUsage ()
**	User_ScanCmdLine ()
**
**	User_AppLogFilter ()
**
**	User_Init ()
**	User_Register ()
**	User_DeclQuants ()
**
**	User_Param_Add ()
**	User_Param_Get ()
**
**
** Main TestRun Start/End:
**
**	User_TestRun_Start_atBegin ()
**	User_TestRun_Start_atEnd ()
**	User_TestRun_Start_StaticCond_Calc ()
**	User_TestRun_Start_Finalize ()
**	User_TestRun_RampUp ()
**
**	User_TestRun_End_First ()
**	User_TestRun_End ()
**
**
** Main Cycle:
**
**	User_In ()
**
**	User_DrivMan_Calc ()
** 	User_Traffic_Calc ()
**	User_VehicleControl_Calc ()
**	User_Brake_Calc ()           in Vhcl_Calc ()
**	User_Calc ()
**	User_Check_IsIdle ()
**
**	User_Out ()
**
**
** APO Communication:
**
**	User_ApoMsg_Eval ()
**	User_ApoMsg_Send ()
**
**	User_ShutDown ()
**	User_End ()
**	User_Cleanup ()
**
**
******************************************************************************
*/

#include 

#if defined(WIN32)
# include 
#endif

#include 
#include 
#include 

#if defined(XENO)
# include 
#endif
# include 

#include 
#include 

#include 

#include 

#include "IOVec.h"
#include "User.h"

/* @@PLUGIN-BEGIN-INCLUDE@@ - Automatically generated code - don't edit! */
/* @@PLUGIN-END@@ */
// Add the following inclusion at the beginning of the User.c file
#include "Lineds.h"

int UserCalcCalledByAppTestRunCalc = 0;


tUser	User;
//Add the following declaration at the beginning of the User.c file
tLds Lds;


/*
** User_Init_First ()
**
** First, low level initialization of the User module
**
** Call:
** - one times at start of program
** - no realtime conditions
**
*/

int
User_Init_First (void)
{
    memset (&User, 0, sizeof(User));

    return 0;
}



/*
** User_PrintUsage ()
**
** Print the user/application specific programm arguments
*/

void
User_PrintUsage (const char *Pgm)
{
    /* REMARK: 1 log statement for each usage line, no line breaks */
    LogUsage("\n");
    LogUsage("Usage: %s [options] [testrun]\n", Pgm);
    LogUsage("Options:\n");

#if defined(CM_HIL)
    {
	const tIOConfig *cf;
	const char *defio = IO_GetDefault();
	LogUsage(" -io %-12s Default I/O configuration (%s)\n", "default",
	    (defio!=NULL && strcmp(defio, "none")!=0) ? defio : "minimal I/O");
	for (cf=IO_GetConfigurations(); cf->Name!=NULL; cf++)
	    LogUsage(" -io %-12s %s\n", cf->Name, cf->Description);
    }
#endif
}



/*
** User_ScanCmdLine ()
**
** Scan application specific command line arguments
**
** Return:
** - argv: last unscanned argument
** - NULL: error or unknown argument
*/

char **
User_ScanCmdLine (int argc, char **argv)
{
    const char *Pgm = argv[0];

    /* I/O configuration to be used in case no configuration was
       specified on the command line. */
    IO_SelectDefault("default" /* or "demoapp", "demorbs,demofr" etc. */);

    while (*++argv) {
	if (strcmp(*argv, "-io") == 0 && argv[1] != NULL) {
	    if (IO_Select(*++argv) != 0)
		return NULL;
	} else if (strcmp(*argv, "-h") == 0 || strcmp(*argv, "-help") == 0) {
	    User_PrintUsage(Pgm);
	    SimCore_PrintUsage(Pgm); /* Possible exit(), depending on CM-platform! */
	    return  NULL;
	} else if ((*argv)[0] == '-') {
	    LogErrF(EC_General, "Unknown option '%s'", *argv);
	    return NULL;
	} else {
	    break;
	}
    }

    return argv;
}



/*
** User_Init ()
**
** Basic initialization of the module User.o
**
** Call:
** - once at program start
** - no realtime conditions
*/

int
User_Init (void)
{
    return 0;
}



int
User_Register (void)
{

    /* @@PLUGIN-BEGIN-REGISTER@@ - Automatically generated code - don't edit! */
    /* @@PLUGIN-END@@ */

    return 0;
}



/*
** User_DeclQuants ()
**
** Add user specific quantities to the dictionary
**
** Call:
** - once at program start
** - no realtime conditions
*/

void
User_DeclQuants (void)
{
    int i;
    // in the function User_DeclQuants (void), add the following lines:

    Lineds_DeclQuants();
    for (i=0; i<N_USEROUTPUT; i++) {
	char sbuf[32];
	sprintf (sbuf, "UserOut_%02d", i);
	DDefDouble (NULL, sbuf, "", &User.Out[i], DVA_IO_Out);
    }
    RBS_DeclQuants();
}


/*
** User_Param_Add ()
**
** Update all modified application specific parameters in the test stand
** parameter file (ECUParameters).
**
** If the variable SimCore.TestRig.ECUParam.Modified set to 1 somewhere else
** CarMaker calls this function to let the user add or change all necessary
** entries before the file is written.
** So, if writing the ECUParam file is necessary, set ECUParam.Modified to 1.
** The next TestRun start or end, CarMaker calls this function and writes
** the file to the harddisk.
**
** Call:
** - in a separate thread (no realtime contitions)
** - when starting a new test run
*/

int
User_Param_Add (void)
{
#if defined(CM_HIL)
    /* ECU parameters */
    if (SimCore.TestRig.ECUParam.Inf == NULL)
	return -1;
#endif

    return 0;
}



/*
** User_Param_Get ()
**
** Update all modified application specific parameters from the test stand
** parameter file (ECUParameters).
**
** Call:
** - in a separate thread (no realtime conditions)
** - if User_Param_Get() wasn't called
** - when starting a new test run, if
**   - the files SimParameters and/or
**   - ECUParameters
**   are modified since last reading
**
** return values:
**  0	ok
** -1	no testrig parameter file
** -2	testrig parameter error
** -3	i/o configuration specific error
** -4	no simulation parameters
** -5	simulation parameters error
** -6	FailSafeTester parameter/init error
*/

int
User_Param_Get (void)
{
    int rv = 0;

#if defined(CM_HIL)
    /*** testrig / ECU parameters */
    if (SimCore.TestRig.ECUParam.Inf == NULL)
	return -1;

    if (IO_Param_Get(SimCore.TestRig.ECUParam.Inf) != 0)
	rv = -2;
#endif

    /*** simulation parameters */
    if (SimCore.TestRig.SimParam.Inf == NULL)
	return -4;

    return rv;
}



/*
** User_TestRun_Start_atBegin ()
**
** Special things before a new simulation starts like
** - reset user variables to their default values
** - reset counters
** - ...
**
** Call:
** - in separate thread (no realtime conditions)
** - when starting a new test run
** - after (standard) infofiles are read in
** - before reading parameters for Environment, DrivMan, Car, ...
**   the models are NOT in the simulation-can-start-now state
**   (after Start(), before StaticCond())
*/

int
User_TestRun_Start_atBegin (void)
{
    int rv = 0;
    int i;

    for (i=0; i<N_USEROUTPUT; i++)
	User.Out[i] = 0.0;


    if (IO_None)
	return rv;

#if defined(CM_HIL)
    if (FST_New(SimCore.TestRig.ECUParam.Inf) != 0)
	rv = -6;
#endif

    return rv;
}




/*
** User_TestRun_Start_atEnd ()
**
** Special things before a new simulation starts like
** - reset user variables to there default values
** - reset counters
** - ...
**
** Call:
** - in separate thread (no realtime conditions)
** - when starting a new test run
** - at the end, behind reading parameters for Environment, DrivMan,
**   Car, ...
**   the models are NOT in the simulation-can-start-now state
**   (after Start(), before StaticCond())
*/

int
User_TestRun_Start_atEnd (void)
{
    int rv = 0;

    rv = Lineds_TestRun_Start_atEnd();

    
#if defined(XENO)
    IOConf_MapQuants();
#endif
    return rv;
}



/*
** User_TestRun_Start_StaticCond_Calc ()
**
** called in non RT context
*/

int
User_TestRun_Start_StaticCond_Calc (void)
{
    return 0;
}



/*
** User_TestRun_Start_Finalize ()
**
** called in RT context
*/

int
User_TestRun_Start_Finalize (void)
{
    return 0;
}



/*
** User_TestRun_RampUp ()
**
** Perform a smooth transition of variables (e.g. I/O)
** from their current state  to the new testrun.
** This function is called repeatedly, once during each cycle, until
** it returns true (or issues an error message), so the function should
** return true if transitioning is done, false otherwise.
**
** In case of an error the function should issue an apropriate
** error message and return false;
**
** Called in RT context, in state SCState_StartSim,
** after preprocessing is done, before starting the engine.
** Please note, that in this early initialization state no calculation
** of the vehicle model takes place.
*/

int
User_TestRun_RampUp (double dt)
{
    int IsReady = 1;

    return IsReady;
}



/*
** User_TestRun_End_First ()
**
** Invoked immediately after the end of a simulation is initiated,
** but before data storage ends and before transitioning into SCState_Idle.
** - Send Scratchpad-note
** - ...
**
** Call:
** - in main task, in the main loop (real-time conditions!)
** - when a test run is finished (SimCore.State is SCState_End)
*/

int
User_TestRun_End_First (void)
{
    return 0;
}



/*
** User_TestRun_End ()
**
** Special things after the end of a simulation like
** - switch off an air compressor
** - Write something to a file
** - ...
**
** Call:
** - in separate thread (no realtime conditions)
** - when a test run is finished (SimCore.State is SCState_End)
*/

int
User_TestRun_End (void)
{
    return 0;
}



/*
** User_In ()
**
** Assign quantities of the i/o vector to model variables
**
** Call:
** - in the main loop
** - pay attention to realtime condition
** - just after IO_In()
*/

void
User_In (const unsigned CycleNo)
{
    if (SimCore.State != SCState_Simulate)
	return;
}



/*
** User_DrivMan_Calc ()
**
** called
** - in RT context
** - after DrivMan_Calc()
*/

int
User_DrivMan_Calc (double dt)
{
    /* Rely on the Vehicle Operator within DrivMan module to get
       the vehicle in driving state using the IPG's
       PowerTrain Control model 'Generic' or similar */
    if (Vehicle.OperationState != OperState_Driving)
	return 0;

    return 0;
}


/*
** User_VehicleControl_Calc ()
**
** called
** - in RT context
** - after VehicleControl_Calc()
*/

int
User_VehicleControl_Calc (double dt)
{
    /* Rely on the Vehicle Operator within DrivMan module to get
       the vehicle in driving state using the IPG's
       PowerTrain Control model 'Generic' or similar */
    if (Vehicle.OperationState != OperState_Driving)
	return 0;

    return 0;
}



/*
** User_Brake_Calc ()
**
** called
** - in RT context
** - after Brake_Calc() in Vhcl_Calc()
*/

int
User_Brake_Calc (double dt)
{
    /* Modify the total brake torque from the brake system model Brake.Trq_tot[]
       or the target drive source torque from the brake control unit
       Brake.HydBrakeCU_IF.Trq_DriveSrc_trg[]
    */

    return 0;
}



/*
** User_Traffic_Calc ()
**
** called
** - in RT context
** - after Traffic_Calc()
*/

int
User_Traffic_Calc (double dt)
{
    if (SimCore.State != SCState_Simulate)
	return 0;

    return 0;
}



/*
** User_Calc ()
**
** called in RT context
*/

int
User_Calc (double dt)
{
    /* Starting with CM 6.0 User_Calc() will be invoked in EVERY simulation
       state. Uncomment the following line in order to restore the behaviour
       of CM 5.1 and earlier. */
    /*if (!UserCalcCalledByAppTestRunCalc) return 0;*/

    int rv;
    rv = Lineds_Calc(dt);

    return rv;
}



/*
** User_Check_IsIdle ()
**
** Checking, if the simulation model is in idle conditions (stand still,
** steeringwheel angle zero, cluch pedal pressed, ...).
** If reached idle state, the calculation of vehicle model and driving
** manoevers is stopped.
** Ready for start new simulation.
**
** Return:
** 1  idle state reached
** 0  else
**
** Call:
** - in main task, in the main loop
** - pay attention to realtime condition
** - while SimCore.State==SCState_EndIdleGet
*/

int
User_Check_IsIdle (int IsIdle)
{
    double val;

    /*** ECU / carmodel signals */

    /* vehicle and wheels: stand still */
    val = 0.5*kmh2ms;
    if (Vehicle.v > val
     || fabs(Vehicle.Wheel[0]->vBelt) > val || fabs(Vehicle.Wheel[1]->vBelt) > val
     || fabs(Vehicle.Wheel[2]->vBelt) > val || fabs(Vehicle.Wheel[3]->vBelt) > val) {
	IsIdle = 0;
    }

    /* SteerAngle: drive  straight forward position */
    val = 1.0*deg2rad;
    if (Vehicle.Steering.Ang > val || Vehicle.Steering.Ang < -val)
	IsIdle = 0;

    return IsIdle;
}



/*
** User_Out ()
**
** Assigns model quantities to variables of the i/o vector
**
** call:
** - in the main loop
** - pay attention to realtime condition
** - just before IO_Out();
*/

void
User_Out (const unsigned CycleNo)
{
    RBS_OutMap(CycleNo);

    if (SimCore.State != SCState_Simulate)
	return;
}



/*
** User_ApoMsg_Eval ()
**
** Communication between the application and connected GUIs.
** Evaluate messages from GUIs
**
** Call:
** - in the main loop
** - pay attention to realtime condition
** - near the end of the main loop, if the function SimCore_ApoMsg_Eval()
**    skips the message
**
** Return:
**   0 : message evaluated
**  -1 : message not handled
*/

int
User_ApoMsg_Eval (int Ch, char *Msg, int len, int who)
{
#if defined(CM_HIL)
    /*** FailSafeTester */
    if (Ch == ApoCh_CarMaker) {
	if (FST_ApoMsgEval(Ch, Msg, len) <= 0)
	    return 0;
    }
#endif
    return -1;
}



/*
** User_ApoMsg_Send ()
**
** Communication between the application and connected GUIs.
** Sends messages to GUIs
**
** Call:
** - near the end of the main loop, in MainThread_FinishCycle()
** - pay attention to realtime condition
*/

void
User_ApoMsg_Send (double T, const unsigned CycleNo)
{
}



/*
** User_ShutDown ()
**
** Prepare application for shut down
**
** Call:
** - at end of program
** - no realtime conditions
*/

int
User_ShutDown (int ShutDownForced)
{
    int IsDown = 0;

    /* Prepare application for shutdown and return that
       shutdown conditions are reached */
    if (1) {
	IsDown = 1;
    }

    return IsDown;
}



/*
** User_End ()
**
** End all models of the user module
**
** Call:
** - one times at end of program
** - no realtime conditions
*/

int
User_End (void)
{
    return 0;
}



/*
** User_Cleanup ()
**
** Cleanup function of the User module
**
** Call:
** - one times at end of program, just before exit
** - no realtime conditions
*/

void
User_Cleanup (void)
{
}

Lineds.h


typedef struct tLds tLds;

struct tLds {

    struct {
        struct {
            double x;
            double y;
            double z;
        } p1, p2,p3,p4,p5,p6,p7,p8,p9,p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20;
    } L1, L2, R1, R2;

};

extern tLds Lds;

int		Lineds_TestRun_Start_atEnd	(void);
void	Lineds_DeclQuants			(void);
int		Lineds_Calc					(double dt);

Lineds.c

#include "Lineds.h"
#include 
#include "Vehicle/Sensor_Line.h"

/*  
** call in User_DeclQuants ()
*/   

void
Lineds_DeclQuants (void)
{

    DDefDouble4  (NULL, "LineL1_p1_x",	"m", &Lds.L1.p1.x, DVA_None);
    DDefDouble4  (NULL, "LineL1_p1_y",	"m", &Lds.L1.p1.y, DVA_None);
    DDefDouble4  (NULL, "LineL1_p1_z",	"m", &Lds.L1.p1.z, DVA_None);
    DDefDouble4  (NULL, "LineL1_p2_x",	"m", &Lds.L1.p2.x, DVA_None);
    DDefDouble4  (NULL, "LineL1_p2_y",	"m", &Lds.L1.p2.y, DVA_None);
    DDefDouble4  (NULL, "LineL1_p2_z",	"m", &Lds.L1.p2.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p3_x", "m", &Lds.L1.p3.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p3_y", "m", &Lds.L1.p3.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p3_z", "m", &Lds.L1.p3.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p4_x", "m", &Lds.L1.p4.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p4_y", "m", &Lds.L1.p4.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p4_z", "m", &Lds.L1.p4.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p5_x", "m", &Lds.L1.p5.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p5_y", "m", &Lds.L1.p5.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p5_z", "m", &Lds.L1.p5.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p6_x", "m", &Lds.L1.p6.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p6_y", "m", &Lds.L1.p6.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p6_z", "m", &Lds.L1.p6.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p7_x", "m", &Lds.L1.p7.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p7_y", "m", &Lds.L1.p7.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p7_z", "m", &Lds.L1.p7.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p8_x", "m", &Lds.L1.p8.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p8_y", "m", &Lds.L1.p8.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p8_z", "m", &Lds.L1.p8.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p9_x", "m", &Lds.L1.p9.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p9_y", "m", &Lds.L1.p9.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p9_z", "m", &Lds.L1.p9.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p10_x", "m", &Lds.L1.p10.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p10_y", "m", &Lds.L1.p10.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p10_z", "m", &Lds.L1.p10.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p11_x", "m", &Lds.L1.p11.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p11_y", "m", &Lds.L1.p11.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p11_z", "m", &Lds.L1.p11.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p12_x", "m", &Lds.L1.p12.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p12_y", "m", &Lds.L1.p12.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p12_z", "m", &Lds.L1.p12.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p13_x", "m", &Lds.L1.p13.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p13_y", "m", &Lds.L1.p13.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p13_z", "m", &Lds.L1.p13.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p14_x", "m", &Lds.L1.p14.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p14_y", "m", &Lds.L1.p14.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p14_z", "m", &Lds.L1.p14.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p15_x", "m", &Lds.L1.p15.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p15_y", "m", &Lds.L1.p15.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p15_z", "m", &Lds.L1.p15.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p16_x", "m", &Lds.L1.p16.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p16_y", "m", &Lds.L1.p16.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p16_z", "m", &Lds.L1.p16.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p17_x", "m", &Lds.L1.p17.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p17_y", "m", &Lds.L1.p17.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p17_z", "m", &Lds.L1.p17.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p18_x", "m", &Lds.L1.p18.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p18_y", "m", &Lds.L1.p18.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p18_z", "m", &Lds.L1.p18.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p19_x", "m", &Lds.L1.p19.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p19_y", "m", &Lds.L1.p19.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p19_z", "m", &Lds.L1.p19.z, DVA_None);
	DDefDouble4(NULL, "LineL1_p20_x", "m", &Lds.L1.p20.x, DVA_None);
	DDefDouble4(NULL, "LineL1_p20_y", "m", &Lds.L1.p20.y, DVA_None);
	DDefDouble4(NULL, "LineL1_p20_z", "m", &Lds.L1.p20.z, DVA_None);

    DDefDouble4  (NULL, "LineL2_p1_x",	"m", &Lds.L2.p1.x, DVA_None);
    DDefDouble4  (NULL, "LineL2_p1_y",	"m", &Lds.L2.p1.y, DVA_None);
    DDefDouble4  (NULL, "LineL2_p1_z",	"m", &Lds.L2.p1.z, DVA_None);
    DDefDouble4  (NULL, "LineL2_p2_x",	"m", &Lds.L2.p2.x, DVA_None);
    DDefDouble4  (NULL, "LineL2_p2_y",	"m", &Lds.L2.p2.y, DVA_None);
    DDefDouble4  (NULL, "LineL2_p2_z",	"m", &Lds.L2.p2.z, DVA_None);

    DDefDouble4  (NULL, "LineR1_p1_x",	"m", &Lds.R1.p1.x, DVA_None);
    DDefDouble4  (NULL, "LineR1_p1_y",	"m", &Lds.R1.p1.y, DVA_None);
    DDefDouble4  (NULL, "LineR1_p1_z",	"m", &Lds.R1.p1.z, DVA_None);
    DDefDouble4  (NULL, "LineR1_p2_x",	"m", &Lds.R1.p2.x, DVA_None);
    DDefDouble4  (NULL, "LineR1_p2_y",	"m", &Lds.R1.p2.y, DVA_None);
    DDefDouble4  (NULL, "LineR1_p2_z",	"m", &Lds.R1.p2.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p3_x", "m", &Lds.R1.p3.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p3_y", "m", &Lds.R1.p3.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p3_z", "m", &Lds.R1.p3.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p4_x", "m", &Lds.R1.p4.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p4_y", "m", &Lds.R1.p4.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p4_z", "m", &Lds.R1.p4.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p5_x", "m", &Lds.R1.p5.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p5_y", "m", &Lds.R1.p5.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p5_z", "m", &Lds.R1.p5.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p6_x", "m", &Lds.R1.p6.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p6_y", "m", &Lds.R1.p6.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p6_z", "m", &Lds.R1.p6.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p7_x", "m", &Lds.R1.p7.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p7_y", "m", &Lds.R1.p7.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p7_z", "m", &Lds.R1.p7.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p8_x", "m", &Lds.R1.p8.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p8_y", "m", &Lds.R1.p8.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p8_z", "m", &Lds.R1.p8.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p9_x", "m", &Lds.R1.p9.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p9_y", "m", &Lds.R1.p9.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p9_z", "m", &Lds.R1.p9.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p10_x", "m", &Lds.R1.p10.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p10_y", "m", &Lds.R1.p10.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p10_z", "m", &Lds.R1.p10.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p11_x", "m", &Lds.R1.p11.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p11_y", "m", &Lds.R1.p11.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p11_z", "m", &Lds.R1.p11.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p12_x", "m", &Lds.R1.p12.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p12_y", "m", &Lds.R1.p12.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p12_z", "m", &Lds.R1.p12.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p13_x", "m", &Lds.R1.p13.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p13_y", "m", &Lds.R1.p13.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p13_z", "m", &Lds.R1.p13.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p14_x", "m", &Lds.R1.p14.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p14_y", "m", &Lds.R1.p14.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p14_z", "m", &Lds.R1.p14.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p15_x", "m", &Lds.R1.p15.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p15_y", "m", &Lds.R1.p15.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p15_z", "m", &Lds.R1.p15.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p16_x", "m", &Lds.R1.p16.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p16_y", "m", &Lds.R1.p16.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p16_z", "m", &Lds.R1.p16.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p17_x", "m", &Lds.R1.p17.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p17_y", "m", &Lds.R1.p17.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p17_z", "m", &Lds.R1.p17.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p18_x", "m", &Lds.R1.p18.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p18_y", "m", &Lds.R1.p18.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p18_z", "m", &Lds.R1.p18.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p19_x", "m", &Lds.R1.p19.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p19_y", "m", &Lds.R1.p19.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p19_z", "m", &Lds.R1.p19.z, DVA_None);
	DDefDouble4(NULL, "LineR1_p20_x", "m", &Lds.R1.p20.x, DVA_None);
	DDefDouble4(NULL, "LineR1_p20_y", "m", &Lds.R1.p20.y, DVA_None);
	DDefDouble4(NULL, "LineR1_p20_z", "m", &Lds.R1.p20.z, DVA_None);

    DDefDouble4  (NULL, "LineR2_p1_x",	"m", &Lds.R2.p1.x, DVA_None);
    DDefDouble4  (NULL, "LineR2_p1_y",	"m", &Lds.R2.p1.y, DVA_None);
    DDefDouble4  (NULL, "LineR2_p1_z",	"m", &Lds.R2.p1.z, DVA_None);
    DDefDouble4  (NULL, "LineR2_p2_x",	"m", &Lds.R2.p2.x, DVA_None);
    DDefDouble4  (NULL, "LineR2_p2_y",	"m", &Lds.R2.p2.y, DVA_None);
    DDefDouble4  (NULL, "LineR2_p2_z",	"m", &Lds.R2.p2.z, DVA_None);
}


/*
** Lineds_TestRun_Start_atEnd ()
**
** initialises struct at the start of a new TestRun
**
** call in User_TestRun_Start_atEnd ()
*/
int
Lineds_TestRun_Start_atEnd (void)
{
     Lds.L1.p1.x = 0; 
     Lds.L1.p1.y = 0; 
     Lds.L1.p1.z = 0;
     Lds.L1.p2.x = 0;
     Lds.L1.p2.y = 0;
     Lds.L1.p2.z = 0;
	 Lds.L1.p3.x = 0;
	 Lds.L1.p3.y = 0;
	 Lds.L1.p3.z = 0;
	 Lds.L1.p4.x = 0;
	 Lds.L1.p4.y = 0;
	 Lds.L1.p4.z = 0;
	 Lds.L1.p5.x = 0;
	 Lds.L1.p5.y = 0;
	 Lds.L1.p5.z = 0;
	 Lds.L1.p6.x = 0;
	 Lds.L1.p6.y = 0;
	 Lds.L1.p6.z = 0;
	 Lds.L1.p7.x = 0;
	 Lds.L1.p7.y = 0;
	 Lds.L1.p7.z = 0;
	 Lds.L1.p8.x = 0;
	 Lds.L1.p8.y = 0;
	 Lds.L1.p8.z = 0;
	 Lds.L1.p9.x = 0;
	 Lds.L1.p9.y = 0;
	 Lds.L1.p9.z = 0;
	 Lds.L1.p10.x = 0;
	 Lds.L1.p10.y = 0;
	 Lds.L1.p10.z = 0;
	 Lds.L1.p11.x = 0;
	 Lds.L1.p11.y = 0;
	 Lds.L1.p11.z = 0;
	 Lds.L1.p12.x = 0;
	 Lds.L1.p12.y = 0;
	 Lds.L1.p12.z = 0;
	 Lds.L1.p13.x = 0;
	 Lds.L1.p13.y = 0;
	 Lds.L1.p13.z = 0;
	 Lds.L1.p14.x = 0;
	 Lds.L1.p14.y = 0;
	 Lds.L1.p14.z = 0;
	 Lds.L1.p15.x = 0;
	 Lds.L1.p15.y = 0;
	 Lds.L1.p15.z = 0;
	 Lds.L1.p16.x = 0;
	 Lds.L1.p16.y = 0;
	 Lds.L1.p16.z = 0;
	 Lds.L1.p17.x = 0;
	 Lds.L1.p17.y = 0;
	 Lds.L1.p17.z = 0;
	 Lds.L1.p18.x = 0;
	 Lds.L1.p18.y = 0;
	 Lds.L1.p18.z = 0;
	 Lds.L1.p19.x = 0;
	 Lds.L1.p19.y = 0;
	 Lds.L1.p19.z = 0;
	 Lds.L1.p20.x = 0;
	 Lds.L1.p20.y = 0;
	 Lds.L1.p20.z = 0;

     Lds.L2.p1.x = 0;
     Lds.L2.p1.y = 0;
     Lds.L2.p1.z = 0;
     Lds.L2.p2.x = 0; 
     Lds.L2.p2.y = 0; 
     Lds.L2.p2.z = 0;

     Lds.R1.p1.x = 0;
     Lds.R1.p1.y = 0;
     Lds.R1.p1.z = 0;
     Lds.R1.p2.x = 0;
     Lds.R1.p2.y = 0;
     Lds.R1.p2.z = 0;
	 Lds.R1.p3.x = 0;
	 Lds.R1.p3.y = 0;
	 Lds.R1.p3.z = 0;
	 Lds.R1.p4.x = 0;
	 Lds.R1.p4.y = 0;
	 Lds.R1.p4.z = 0;
	 Lds.R1.p5.x = 0;
	 Lds.R1.p5.y = 0;
	 Lds.R1.p5.z = 0;
	 Lds.R1.p6.x = 0;
	 Lds.R1.p6.y = 0;
	 Lds.R1.p6.z = 0;
	 Lds.R1.p7.x = 0;
	 Lds.R1.p7.y = 0;
	 Lds.R1.p7.z = 0;
	 Lds.R1.p8.x = 0;
	 Lds.R1.p8.y = 0;
	 Lds.R1.p8.z = 0;
	 Lds.R1.p9.x = 0;
	 Lds.R1.p9.y = 0;
	 Lds.R1.p9.z = 0;
	 Lds.R1.p10.x = 0;
	 Lds.R1.p10.y = 0;
	 Lds.R1.p10.z = 0;
	 Lds.R1.p11.x = 0;
	 Lds.R1.p11.y = 0;
	 Lds.R1.p11.z = 0;
	 Lds.R1.p12.x = 0;
	 Lds.R1.p12.y = 0;
	 Lds.R1.p12.z = 0;
	 Lds.R1.p13.x = 0;
	 Lds.R1.p13.y = 0;
	 Lds.R1.p13.z = 0;
	 Lds.R1.p14.x = 0;
	 Lds.R1.p14.y = 0;
	 Lds.R1.p14.z = 0;
	 Lds.R1.p15.x = 0;
	 Lds.R1.p15.y = 0;
	 Lds.R1.p15.z = 0;
	 Lds.R1.p16.x = 0;
	 Lds.R1.p16.y = 0;
	 Lds.R1.p16.z = 0;
	 Lds.R1.p17.x = 0;
	 Lds.R1.p17.y = 0;
	 Lds.R1.p17.z = 0;
	 Lds.R1.p18.x = 0;
	 Lds.R1.p18.y = 0;
	 Lds.R1.p18.z = 0;
	 Lds.R1.p19.x = 0;
	 Lds.R1.p19.y = 0;
	 Lds.R1.p19.z = 0;
	 Lds.R1.p20.x = 0;
	 Lds.R1.p20.y = 0;
	 Lds.R1.p20.z = 0;

     Lds.R2.p1.x = 0; 
     Lds.R2.p1.y = 0; 
     Lds.R2.p1.z = 0;
     Lds.R2.p2.x = 0;
     Lds.R2.p2.y = 0;
     Lds.R2.p2.z = 0;
     
    return 0;
}    
     
     
/*  
** call in User_Calc ()
*/   
     
int  
Lineds_Calc (double dt)
{    
     
    /*Execute only during simulation*/
    if (SimCore.State != SCState_Simulate) return 0;
     
    /*Execute only if at least 1 line is detected on the left or  right side*/
    if (LineSensor[0].RLines.nLine == 0 || LineSensor[0].LLines.nLine == 0) {
       Lds.L1.p1.x  = 0; 
       Lds.L1.p1.y  = 0; 
       Lds.L1.p1.z  = 0;
       Lds.L1.p2.x  = 0;
       Lds.L1.p2.y  = 0;
       Lds.L1.p2.z  = 0;
	   Lds.L1.p3.x = 0;
	   Lds.L1.p3.y = 0;
	   Lds.L1.p3.z = 0;
	   Lds.L1.p4.x = 0;
	   Lds.L1.p4.y = 0;
	   Lds.L1.p4.z = 0;
	   Lds.L1.p5.x = 0;
	   Lds.L1.p5.y = 0;
	   Lds.L1.p5.z = 0;
	   Lds.L1.p6.x = 0;
	   Lds.L1.p6.y = 0;
	   Lds.L1.p6.z = 0;
	   Lds.L1.p7.x = 0;
	   Lds.L1.p7.y = 0;
	   Lds.L1.p7.z = 0;
	   Lds.L1.p8.x = 0;
	   Lds.L1.p8.y = 0;
	   Lds.L1.p8.z = 0;
	   Lds.L1.p9.x = 0;
	   Lds.L1.p9.y = 0;
	   Lds.L1.p9.z = 0;
	   Lds.L1.p10.x = 0;
	   Lds.L1.p10.y = 0;
	   Lds.L1.p10.z = 0;
	   Lds.L1.p11.x = 0;
	   Lds.L1.p11.y = 0;
	   Lds.L1.p11.z = 0;
	   Lds.L1.p12.x = 0;
	   Lds.L1.p12.y = 0;
	   Lds.L1.p12.z = 0;
	   Lds.L1.p13.x = 0;
	   Lds.L1.p13.y = 0;
	   Lds.L1.p13.z = 0;
	   Lds.L1.p14.x = 0;
	   Lds.L1.p14.y = 0;
	   Lds.L1.p14.z = 0;
	   Lds.L1.p15.x = 0;
	   Lds.L1.p15.y = 0;
	   Lds.L1.p15.z = 0;
	   Lds.L1.p16.x = 0;
	   Lds.L1.p16.y = 0;
	   Lds.L1.p16.z = 0;
	   Lds.L1.p17.x = 0;
	   Lds.L1.p17.y = 0;
	   Lds.L1.p17.z = 0;
	   Lds.L1.p18.x = 0;
	   Lds.L1.p18.y = 0;
	   Lds.L1.p18.z = 0;
	   Lds.L1.p19.x = 0;
	   Lds.L1.p19.y = 0;
	   Lds.L1.p19.z = 0;
	   Lds.L1.p20.x = 0;
	   Lds.L1.p20.y = 0;
	   Lds.L1.p20.z = 0;

       Lds.L2.p1.x  = 0;
       Lds.L2.p1.y  = 0;
       Lds.L2.p1.z  = 0;
       Lds.L2.p2.x  = 0; 
       Lds.L2.p2.y  = 0; 
       Lds.L2.p2.z  = 0;

       Lds.R1.p1.x  = 0;
       Lds.R1.p1.y  = 0;
       Lds.R1.p1.z  = 0;
       Lds.R1.p2.x  = 0;
       Lds.R1.p2.y  = 0;
       Lds.R1.p2.z  = 0;
	   Lds.R1.p3.x = 0;
	   Lds.R1.p3.y = 0;
	   Lds.R1.p3.z = 0;
	   Lds.R1.p4.x = 0;
	   Lds.R1.p4.y = 0;
	   Lds.R1.p4.z = 0;
	   Lds.R1.p5.x = 0;
	   Lds.R1.p5.y = 0;
	   Lds.R1.p5.z = 0;
	   Lds.R1.p6.x = 0;
	   Lds.R1.p6.y = 0;
	   Lds.R1.p6.z = 0;
	   Lds.R1.p7.x = 0;
	   Lds.R1.p7.y = 0;
	   Lds.R1.p7.z = 0;
	   Lds.R1.p8.x = 0;
	   Lds.R1.p8.y = 0;
	   Lds.R1.p8.z = 0;
	   Lds.R1.p9.x = 0;
	   Lds.R1.p9.y = 0;
	   Lds.R1.p9.z = 0;
	   Lds.R1.p10.x = 0;
	   Lds.R1.p10.y = 0;
	   Lds.R1.p10.z = 0;
	   Lds.R1.p11.x = 0;
	   Lds.R1.p11.y = 0;
	   Lds.R1.p11.z = 0;
	   Lds.R1.p12.x = 0;
	   Lds.R1.p12.y = 0;
	   Lds.R1.p12.z = 0;
	   Lds.R1.p13.x = 0;
	   Lds.R1.p13.y = 0;
	   Lds.R1.p13.z = 0;
	   Lds.R1.p14.x = 0;
	   Lds.R1.p14.y = 0;
	   Lds.R1.p14.z = 0;
	   Lds.R1.p15.x = 0;
	   Lds.R1.p15.y = 0;
	   Lds.R1.p15.z = 0;
	   Lds.R1.p16.x = 0;
	   Lds.R1.p16.y = 0;
	   Lds.R1.p16.z = 0;
	   Lds.R1.p17.x = 0;
	   Lds.R1.p17.y = 0;
	   Lds.R1.p17.z = 0;
	   Lds.R1.p18.x = 0;
	   Lds.R1.p18.y = 0;
	   Lds.R1.p18.z = 0;
	   Lds.R1.p19.x = 0;
	   Lds.R1.p19.y = 0;
	   Lds.R1.p19.z = 0;
	   Lds.R1.p20.x = 0;
	   Lds.R1.p20.y = 0;
	   Lds.R1.p20.z = 0;

       Lds.R2.p1.x  = 0; 
       Lds.R2.p1.y  = 0; 
       Lds.R2.p1.z  = 0;
       Lds.R2.p2.x  = 0;
       Lds.R2.p2.y  = 0;
       Lds.R2.p2.z  = 0;

        return 0;
    };

        Lds.L1.p1.x = LineSensor[0].LLines.L[0].ds[0][0];
        Lds.L1.p1.y = LineSensor[0].LLines.L[0].ds[0][1];
        Lds.L1.p1.z = LineSensor[0].LLines.L[0].ds[0][2];
        Lds.L1.p2.x = LineSensor[0].LLines.L[0].ds[1][0];
        Lds.L1.p2.y = LineSensor[0].LLines.L[0].ds[1][1];
        Lds.L1.p2.z = LineSensor[0].LLines.L[0].ds[1][2];
		Lds.L1.p3.x = LineSensor[0].LLines.L[0].ds[2][0];
		Lds.L1.p3.y = LineSensor[0].LLines.L[0].ds[2][1];
		Lds.L1.p3.z = LineSensor[0].LLines.L[0].ds[2][2];
		Lds.L1.p4.x = LineSensor[0].LLines.L[0].ds[3][0];
		Lds.L1.p4.y = LineSensor[0].LLines.L[0].ds[3][1];
		Lds.L1.p4.z = LineSensor[0].LLines.L[0].ds[3][2];
		Lds.L1.p5.x = LineSensor[0].LLines.L[0].ds[4][0];
		Lds.L1.p5.y = LineSensor[0].LLines.L[0].ds[4][1];
		Lds.L1.p5.z = LineSensor[0].LLines.L[0].ds[4][2];
		Lds.L1.p6.x = LineSensor[0].LLines.L[0].ds[5][0];
		Lds.L1.p6.y = LineSensor[0].LLines.L[0].ds[5][1];
		Lds.L1.p6.z = LineSensor[0].LLines.L[0].ds[5][2];
		Lds.L1.p7.x = LineSensor[0].LLines.L[0].ds[6][0];
		Lds.L1.p7.y = LineSensor[0].LLines.L[0].ds[6][1];
		Lds.L1.p7.z = LineSensor[0].LLines.L[0].ds[6][2];
		Lds.L1.p8.x = LineSensor[0].LLines.L[0].ds[7][0];
		Lds.L1.p8.y = LineSensor[0].LLines.L[0].ds[7][1];
		Lds.L1.p8.z = LineSensor[0].LLines.L[0].ds[7][2];
		Lds.L1.p9.x = LineSensor[0].LLines.L[0].ds[8][0];
		Lds.L1.p9.y = LineSensor[0].LLines.L[0].ds[8][1];
		Lds.L1.p9.z = LineSensor[0].LLines.L[0].ds[8][2];
		Lds.L1.p10.x = LineSensor[0].LLines.L[0].ds[9][0];
		Lds.L1.p10.y = LineSensor[0].LLines.L[0].ds[9][1];
		Lds.L1.p10.z = LineSensor[0].LLines.L[0].ds[9][2];
		Lds.L1.p11.x = LineSensor[0].LLines.L[0].ds[10][0];
		Lds.L1.p11.y = LineSensor[0].LLines.L[0].ds[10][1];
		Lds.L1.p11.z = LineSensor[0].LLines.L[0].ds[10][2];
		Lds.L1.p12.x = LineSensor[0].LLines.L[0].ds[11][0];
		Lds.L1.p12.y = LineSensor[0].LLines.L[0].ds[11][1];
		Lds.L1.p12.z = LineSensor[0].LLines.L[0].ds[11][2];
		Lds.L1.p13.x = LineSensor[0].LLines.L[0].ds[12][0];
		Lds.L1.p13.y = LineSensor[0].LLines.L[0].ds[12][1];
		Lds.L1.p13.z = LineSensor[0].LLines.L[0].ds[12][2];
		Lds.L1.p14.x = LineSensor[0].LLines.L[0].ds[13][0];
		Lds.L1.p14.y = LineSensor[0].LLines.L[0].ds[13][1];
		Lds.L1.p14.z = LineSensor[0].LLines.L[0].ds[13][2];
		Lds.L1.p15.x = LineSensor[0].LLines.L[0].ds[14][0];
		Lds.L1.p15.y = LineSensor[0].LLines.L[0].ds[14][1];
		Lds.L1.p15.z = LineSensor[0].LLines.L[0].ds[14][2];
		Lds.L1.p16.x = LineSensor[0].LLines.L[0].ds[15][0];
		Lds.L1.p16.y = LineSensor[0].LLines.L[0].ds[15][1];
		Lds.L1.p16.z = LineSensor[0].LLines.L[0].ds[15][2];
		Lds.L1.p17.x = LineSensor[0].LLines.L[0].ds[16][0];
		Lds.L1.p17.y = LineSensor[0].LLines.L[0].ds[16][1];
		Lds.L1.p17.z = LineSensor[0].LLines.L[0].ds[16][2];
		Lds.L1.p18.x = LineSensor[0].LLines.L[0].ds[17][0];
		Lds.L1.p18.y = LineSensor[0].LLines.L[0].ds[17][1];
		Lds.L1.p18.z = LineSensor[0].LLines.L[0].ds[17][2];
		Lds.L1.p19.x = LineSensor[0].LLines.L[0].ds[18][0];
		Lds.L1.p19.y = LineSensor[0].LLines.L[0].ds[18][1];
		Lds.L1.p19.z = LineSensor[0].LLines.L[0].ds[18][2];
		Lds.L1.p20.x = LineSensor[0].LLines.L[0].ds[19][0];
		Lds.L1.p20.y = LineSensor[0].LLines.L[0].ds[19][1];
		Lds.L1.p20.z = LineSensor[0].LLines.L[0].ds[19][2];

        Lds.L2.p1.x = LineSensor[0].LLines.L[1].ds[0][0];
        Lds.L2.p1.y = LineSensor[0].LLines.L[1].ds[0][1];
        Lds.L2.p1.z = LineSensor[0].LLines.L[1].ds[0][2];
        Lds.L2.p2.x = LineSensor[0].LLines.L[1].ds[1][0];
        Lds.L2.p2.y = LineSensor[0].LLines.L[1].ds[1][1];
        Lds.L2.p2.z = LineSensor[0].LLines.L[1].ds[1][2];

        Lds.R1.p1.x = LineSensor[0].RLines.L[0].ds[0][0];
        Lds.R1.p1.y = LineSensor[0].RLines.L[0].ds[0][1]; 
        Lds.R1.p1.z = LineSensor[0].RLines.L[0].ds[0][2];  
        Lds.R1.p2.x = LineSensor[0].RLines.L[0].ds[1][0];  
        Lds.R1.p2.y = LineSensor[0].RLines.L[0].ds[1][1];
        Lds.R1.p2.z = LineSensor[0].RLines.L[0].ds[1][2];
		Lds.R1.p3.x = LineSensor[0].RLines.L[0].ds[2][0];
		Lds.R1.p3.y = LineSensor[0].RLines.L[0].ds[2][1];
		Lds.R1.p3.z = LineSensor[0].RLines.L[0].ds[2][2];
		Lds.R1.p4.x = LineSensor[0].RLines.L[0].ds[3][0];
		Lds.R1.p4.y = LineSensor[0].RLines.L[0].ds[3][1];
		Lds.R1.p4.z = LineSensor[0].RLines.L[0].ds[3][2];
		Lds.R1.p5.x = LineSensor[0].RLines.L[0].ds[4][0];
		Lds.R1.p5.y = LineSensor[0].RLines.L[0].ds[4][1];
		Lds.R1.p5.z = LineSensor[0].RLines.L[0].ds[4][2];
		Lds.R1.p6.x = LineSensor[0].RLines.L[0].ds[5][0];
		Lds.R1.p6.y = LineSensor[0].RLines.L[0].ds[5][1];
		Lds.R1.p6.z = LineSensor[0].RLines.L[0].ds[5][2];
		Lds.R1.p7.x = LineSensor[0].RLines.L[0].ds[6][0];
		Lds.R1.p7.y = LineSensor[0].RLines.L[0].ds[6][1];
		Lds.R1.p7.z = LineSensor[0].RLines.L[0].ds[6][2];
		Lds.R1.p8.x = LineSensor[0].RLines.L[0].ds[7][0];
		Lds.R1.p8.y = LineSensor[0].RLines.L[0].ds[7][1];
		Lds.R1.p8.z = LineSensor[0].RLines.L[0].ds[7][2];
		Lds.R1.p9.x = LineSensor[0].RLines.L[0].ds[8][0];
		Lds.R1.p9.y = LineSensor[0].RLines.L[0].ds[8][1];
		Lds.R1.p9.z = LineSensor[0].RLines.L[0].ds[8][2];
		Lds.R1.p10.x = LineSensor[0].RLines.L[0].ds[9][0];
		Lds.R1.p10.y = LineSensor[0].RLines.L[0].ds[9][1];
		Lds.R1.p10.z = LineSensor[0].RLines.L[0].ds[9][2];
		Lds.R1.p11.x = LineSensor[0].RLines.L[0].ds[10][0];
		Lds.R1.p11.y = LineSensor[0].RLines.L[0].ds[10][1];
		Lds.R1.p11.z = LineSensor[0].RLines.L[0].ds[10][2];
		Lds.R1.p12.x = LineSensor[0].RLines.L[0].ds[11][0];
		Lds.R1.p12.y = LineSensor[0].RLines.L[0].ds[11][1];
		Lds.R1.p12.z = LineSensor[0].RLines.L[0].ds[11][2];
		Lds.R1.p13.x = LineSensor[0].RLines.L[0].ds[12][0];
		Lds.R1.p13.y = LineSensor[0].RLines.L[0].ds[12][1];
		Lds.R1.p13.z = LineSensor[0].RLines.L[0].ds[12][2];
		Lds.R1.p14.x = LineSensor[0].RLines.L[0].ds[13][0];
		Lds.R1.p14.y = LineSensor[0].RLines.L[0].ds[13][1];
		Lds.R1.p14.z = LineSensor[0].RLines.L[0].ds[13][2];
		Lds.R1.p15.x = LineSensor[0].RLines.L[0].ds[14][0];
		Lds.R1.p15.y = LineSensor[0].RLines.L[0].ds[14][1];
		Lds.R1.p15.z = LineSensor[0].RLines.L[0].ds[14][2];
		Lds.R1.p16.x = LineSensor[0].RLines.L[0].ds[15][0];
		Lds.R1.p16.y = LineSensor[0].RLines.L[0].ds[15][1];
		Lds.R1.p16.z = LineSensor[0].RLines.L[0].ds[15][2];
		Lds.R1.p17.x = LineSensor[0].RLines.L[0].ds[16][0];
		Lds.R1.p17.y = LineSensor[0].RLines.L[0].ds[16][1];
		Lds.R1.p17.z = LineSensor[0].RLines.L[0].ds[16][2];
		Lds.R1.p18.x = LineSensor[0].RLines.L[0].ds[17][0];
		Lds.R1.p18.y = LineSensor[0].RLines.L[0].ds[17][1];
		Lds.R1.p18.z = LineSensor[0].RLines.L[0].ds[17][2];
		Lds.R1.p19.x = LineSensor[0].RLines.L[0].ds[18][0];
		Lds.R1.p19.y = LineSensor[0].RLines.L[0].ds[18][1];
		Lds.R1.p19.z = LineSensor[0].RLines.L[0].ds[18][2];
		Lds.R1.p20.x = LineSensor[0].RLines.L[0].ds[19][0];
		Lds.R1.p20.y = LineSensor[0].RLines.L[0].ds[19][1];
		Lds.R1.p20.z = LineSensor[0].RLines.L[0].ds[19][2];

        Lds.R2.p1.x = LineSensor[0].RLines.L[1].ds[0][0]; 
        Lds.R2.p1.y = LineSensor[0].RLines.L[1].ds[0][1]; 
        Lds.R2.p1.z = LineSensor[0].RLines.L[1].ds[0][2]; 
        Lds.R2.p2.x = LineSensor[0].RLines.L[1].ds[1][0]; 
        Lds.R2.p2.y = LineSensor[0].RLines.L[1].ds[1][1];  
        Lds.R2.p2.z = LineSensor[0].RLines.L[1].ds[1][2];  

        return 0;
}

4 打开src文件夹下的Makefile文件,将

OBJS =			CM_Main.o CM_Vehicle.o User.o

改为

OBJS = CM_Main.o CM_Vehicle.o User.o Lineds.o

5 打开工程文件CarMaker.sln,将Lineds.c加入到工程源文件列表中,点击生成->重新生成解决方案,成功的话会生成CarMaker.win64.exe文件。
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第5张图片
6 通过快捷方式或者开始菜单打开carmaker,点击Application->Configuration/Status,在Command(executable)下面的框中选择生成的CarMaker.win64.exe文件,点击start&connect,然后点击close
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第6张图片
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第7张图片
7 回到主界面后,点击Application -> Direct variable access,按住Quantity下的向下箭头就能看到L1\L2\R1\R2四条车道线的x,y,z的坐标点,可以选取几个进行观察。关闭carmaker。
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第8张图片
8 通过simulink模型中的CM图标打开carmaker,点击File->Open打开之前我们新建的testrun。
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第9张图片
9 打开IPGMovie观察动画,打开Direct Variable Access观察变量。点击Start开始运行仿真。可以看到已经能够读取车道线的坐标点。
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第10张图片
10 在simulink模型中接收车道线点的数据。simulink模型中集成控制算法的位置为generic/CarMaker/VehicleControl/CreateBus VhclCtrl,所以在这里接受车道线的数据,通过Read CM Dict模块读取carmaker变量。
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第11张图片
11 拟合左右车道线数据,生成车道线方程
carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第12张图片

使用matlab自带的拟合函数,一般采用三次拟合的方式,即可输出车道线方程。

function [l1c,r1c] = fcn(l1x,l1y,r1x,r1y)

l1c = polyfit(l1x,l1y,3);
r1c = polyfit(r1x,r1y,3);
end

运行效果如图

carmaker/matlab联合仿真(三) 生成车道线点,拟合多项式方程_第13张图片

你可能感兴趣的:(自动驾驶仿真,matlab,matlab)