Update simplix simplix_srw (Supercars with rear wing)

Reduced overhead for Memory Manager
Code cleanup

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@5841 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 889cce4d6063d01c8df1c25ad1e008e9d3220297
Former-commit-id: e870639b8f8bc536c755a9219ec5d0577320b463
This commit is contained in:
wdbee 2014-11-16 21:05:57 +00:00
parent ac34765515
commit 2c337a5042
15 changed files with 436 additions and 248 deletions

View file

@ -73,14 +73,30 @@ SET(ROBOT_SOURCES
)
# Official-only simplix instances.
SET(ROBOT_CLONES simplix_36GP simplix_sc simplix_trb1 simplix_ls1 simplix_ls2 simplix_mp5
SET(ROBOT_CLONES simplix_36GP simplix_sc simplix_srw simplix_trb1 simplix_ls1 simplix_ls2 simplix_mp5
simplix_mpa1 simplix_lp1 simplix_ref)
GET_TARGET_PROPERTY(MODLOC ${ROBOT_NAME} RUNTIME_OUTPUT_DIRECTORY)
MESSAGE(STATUS "MODLOC = ${MODLOC}")
# The ubiquitous robot module and its clones.
ROBOT_MODULE(NAME ${ROBOT_NAME} VERSION 3.3.0 SOVERSION 1.0.0
INTERFACE ${ROBOT_INTERFACE}
SOURCES ${ROBOT_SOURCES}
CLONENAMES ${ROBOT_CLONES})
GET_TARGET_PROPERTY(MODLOC ${ROBOT_NAME} RUNTIME_OUTPUT_DIRECTORY)
MESSAGE(STATUS "RUNTIME_OUTPUT_DIRECTORY = ${MODLOC}")
MESSAGE(STATUS "_TGT_LOC = ${_TGT_LOC}")
GET_TARGET_PROPERTY(_TGT_LOC ${ROBOT_NAME} LOCATION)
MESSAGE(STATUS "_TGT_LOC = ${_TGT_LOC}")
MESSAGE(STATUS "_TGT_DIR = ${_TGT_DIR}")
SET_TARGET_PROPERTIES(${ROBOT_NAME} PROPERTIES
LOCATION ${MODLOC})
GET_TARGET_PROPERTY(AVARIABLE ${ROBOT_NAME} LOCATION)
MESSAGE(STATUS "AVARIABLE = ${AVARIABLE}")
# For data associated to the ubiquitous robot module and its clones,
# see data/drivers/simplix*/CMakeLists.txt

View file

@ -1235,7 +1235,7 @@ void TDriver::InitTrack
// Override params for car type with params of track
snprintf(Buf,sizeof(Buf),"%s/%s/%s.xml",
BaseParamPath,oCarType,oTrackName);
LogSimplix.info("#Override params for car type with params of track: %s\n", Buf);
LogSimplix.warning("#Override params for car type with params of track: %s\n", Buf);
Handle = TUtils::MergeParamFile(Handle,Buf);
// Override params for car type with params of track and weather

View file

@ -93,7 +93,7 @@ extern GfLogger* PLogSimplix;
// Racing line version marker
// (Increment if racinglines needs to be recalculated)
//--------------------------------------------------------------------------*
#define RL_VERSION 135 // Force new calculation
#define RL_VERSION 136 // Force new calculation
//==========================================================================*
//==========================================================================*
@ -109,6 +109,7 @@ extern GfLogger* PLogSimplix;
#define RTYPE_SIMPLIX_MP5 7 // Robot type simplix_mp5
#define RTYPE_SIMPLIX_LP1 8 // Robot type simplix_lp1
#define RTYPE_SIMPLIX_REF 9 // Robot type simplix_ref
#define RTYPE_SIMPLIX_SRW 10 // Robot type simplix_srw
//==========================================================================*
//==========================================================================*

View file

@ -12,7 +12,7 @@
// eMail : wdb@wdbee.de
// Version : 4.02.000
//--------------------------------------------------------------------------*
// V4.01.000:
// V4.01.000:Supercars.xml
// New code for avoiding and overtaking
//--------------------------------------------------------------------------*
// V4.00.002:
@ -291,6 +291,8 @@ void SetUpSimplix()
SetParameters(NBBOTS, "car1-trb1");
TDriver::AdvancedParameters = true;
TDriver::SkillingFactor = 0.1f; // Skilling factor for career-mode
TDriver::UseWingControl = true;
TDriver::UseRacinglineParameters = true;
};
//==========================================================================*
@ -334,6 +336,21 @@ void SetUpSimplix_sc()
};
//==========================================================================*
//==========================================================================*
// Schismatic entry point for simplix_srw
//--------------------------------------------------------------------------*
void SetUpSimplix_srw()
{
cRobotType = RTYPE_SIMPLIX_SRW;
SetParameters(NBBOTS, "srw-sector-p4");
TDriver::AdvancedParameters = true;
TDriver::UseSCSkilling = true; // Use supercar skilling
TDriver::SkillingFactor = 0.1f; // Skilling factor for career-mode
TDriver::UseWingControl = true;
TDriver::UseRacinglineParameters = true;
};
//==========================================================================*
//==========================================================================*
// Schismatic entry point for simplix_36GP
//--------------------------------------------------------------------------*
@ -409,7 +426,7 @@ void SetUpSimplix_lp1()
void SetUpSimplix_ref()
{
cRobotType = RTYPE_SIMPLIX_REF;
SetParameters(NBBOTS, "ref.sector-p4");
SetParameters(NBBOTS, "ref-sector-p4");
TDriver::UseRacinglineParameters = true;
TDriver::UseWingControl = true;
};
@ -776,6 +793,16 @@ static int InitFuncPt(int Index, void *Pt)
cInstances[Index-IndexOffset].cRobot->ScaleSide(0.95f,0.95f);
cInstances[Index-IndexOffset].cRobot->SideBorderOuter(0.10f);
}
else if (cRobotType == RTYPE_SIMPLIX_SRW)
{
LogSimplix.debug("#cRobotType == RTYPE_SIMPLIX_SRW\n");
cInstances[Index-IndexOffset].cRobot->CalcSkillingFoo = &TDriver::CalcSkilling_simplix_SC;
cInstances[Index-IndexOffset].cRobot->CalcFrictionFoo = &TDriver::CalcFriction_simplix_Identity;
cInstances[Index-IndexOffset].cRobot->CalcCrvFoo = &TDriver::CalcCrv_simplix_Identity;
cInstances[Index-IndexOffset].cRobot->CalcHairpinFoo = &TDriver::CalcHairpin_simplix_Identity;
cInstances[Index-IndexOffset].cRobot->ScaleSide(0.95f,0.95f);
cInstances[Index-IndexOffset].cRobot->SideBorderOuter(0.10f);
}
else if (cRobotType == RTYPE_SIMPLIX_36GP)
{
LogSimplix.debug("#cRobotType == RTYPE_SIMPLIX_36GP\n");
@ -842,11 +869,12 @@ static int InitFuncPt(int Index, void *Pt)
else if (cRobotType == RTYPE_SIMPLIX_REF)
{
LogSimplix.debug("#cRobotType == RTYPE_SIMPLIX_REF\n");
cInstances[Index-IndexOffset].cRobot->CalcSkillingFoo = &TDriver::CalcSkilling_simplix;
cInstances[Index-IndexOffset].cRobot->CalcFrictionFoo = &TDriver::CalcFriction_simplix_REF;
cInstances[Index-IndexOffset].cRobot->CalcSkillingFoo = &TDriver::CalcSkilling_simplix_SC;
// cInstances[Index-IndexOffset].cRobot->CalcFrictionFoo = &TDriver::CalcFriction_simplix_REF;
cInstances[Index-IndexOffset].cRobot->CalcFrictionFoo = &TDriver::CalcFriction_simplix_Identity;
// cInstances[Index-IndexOffset].cRobot->CalcCrvFoo = &TDriver::CalcCrv_simplix;
cInstances[Index-IndexOffset].cRobot->CalcCrvFoo = &TDriver::CalcCrv_simplix_Identity;
cInstances[Index-IndexOffset].cRobot->CalcHairpinFoo = &TDriver::CalcHairpin_simplix;
cInstances[Index-IndexOffset].cRobot->CalcHairpinFoo = &TDriver::CalcHairpin_simplix_Identity;
cInstances[Index-IndexOffset].cRobot->ScaleSide(0.95f,0.95f);
cInstances[Index-IndexOffset].cRobot->SideBorderOuter(0.20f);
}

View file

@ -822,6 +822,7 @@ typedef struct CarElt
#define PRM_TCLINSIMU "enable tcl"
#define PRM_ABSINSIMU "enable abs"
#define PRM_ESPINSIMU "enable esp"
#define PRM_LIMITEDGROUNDEFFECT "enable cliftlimit"
#define VAL_YES "yes"
#define VAL_NO "no"
#define FEAT_AEROTOCG 0x01 //shift aero coordinates with the CG
@ -833,6 +834,7 @@ typedef struct CarElt
#define FEAT_TCLINSIMU 0x40 //TCL simulation with 500 Hz at single wheels and engine
#define FEAT_ABSINSIMU 0x80 //ABS simulation with 500 Hz at single wheels
#define FEAT_ESPINSIMU 0x100 //ESP simulation with 500 Hz at single wheels
#define FEAT_LIMITEDGROUNDEFFECT 0x200 //Limit for Clift is enabled
#endif /* __CARV1_H__ */

View file

@ -89,7 +89,7 @@ void* GCCRetAddrs(void)
void* operator new (size_t size)
{
void* retAddr = GetRetAddrs();
return GfMemoryManagerAlloc(size, GF_MM_ALLOCTYPE_NEW,retAddr);
return GfMemoryManagerAlloc(size, GF_MM_ALLOCTYPE_NEW, retAddr);
}
//============================================================================*
@ -109,7 +109,7 @@ void operator delete (void* b)
ExternC void* _tgf_win_malloc(size_t size)
{
void* retAddr = GetRetAddrs();
return GfMemoryManagerAlloc(size,GF_MM_ALLOCTYPE_MALLOC,retAddr);
return GfMemoryManagerAlloc(size, GF_MM_ALLOCTYPE_MALLOC, retAddr);
}
//============================================================================*
@ -128,7 +128,7 @@ ExternC void _tgf_win_free(void* b)
ExternC void* _tgf_win_calloc(size_t num, size_t size)
{
void* retAddr = GetRetAddrs();
void* p = GfMemoryManagerAlloc(num * size,GF_MM_ALLOCTYPE_MALLOC,retAddr);
void* p = GfMemoryManagerAlloc(num*size, GF_MM_ALLOCTYPE_MALLOC, retAddr);
memset(p, 0, num * size);
return p;
}
@ -147,7 +147,7 @@ ExternC void* _tgf_win_realloc(void* memblock, size_t size)
return NULL;
}
void* p = GfMemoryManagerAlloc(size,GF_MM_ALLOCTYPE_MALLOC,retAddr);
void* p = GfMemoryManagerAlloc(size, GF_MM_ALLOCTYPE_MALLOC, retAddr);
if (p == NULL)
{
return NULL;
@ -185,7 +185,7 @@ ExternC void* _tgf_win_realloc(void* memblock, size_t size)
//============================================================================*
// API: Override strdup
//----------------------------------------------------------------------------*
ExternC char * _tgf_win_strdup(const char * str)
ExternC char * _tgf_win_strdup(const char* str)
{
void* retAddr = GetRetAddrs();
@ -211,29 +211,39 @@ ExternC char * _tgf_win_strdup(const char * str)
//----------------------------------------------------------------------------*
tMemoryManager* GfMemoryManager(void)
{
// Create the Memory Manager
tMemoryManager* MemoryManager = (tMemoryManager*)
malloc(sizeof(tMemoryManager));
MemoryManager->Size = sizeof(tMemoryManager);
MemoryManager->State = GF_MM_STATE_NULL;
MemoryManager->AddedSpace = 0;
MemoryManager->DoNotFree = false;
MemoryManager->RootOfList.Mark = MM_MARKER_BEGIN;
MemoryManager->RootOfList.Type = GF_MM_ALLOCTYPE_MEMMAN;
MemoryManager->RootOfList.Prev = NULL;
MemoryManager->RootOfList.Next = NULL;
MemoryManager->RootOfList.Size = sizeof(tMemoryManager);
MemoryManager->RootOfList.BLID = GfMM_Counter++;
// Set the pointer to the linking block
MemoryManager->GarbageCollection = (tDSMMLinkBlock*) MemoryManager;
// Initialize variables of the Memory Manager
MemoryManager->Allocated = 0;
MemoryManager->MaxAllocated = 0;
MemoryManager->Requested = 0;
MemoryManager->MaxRequested = 0;
MemoryManager->BigB = 0;
for (int I = 0; I < MAXBLOCKSIZE; I++)
MemoryManager->Hist[I] = 0;
MemoryManager->State = GF_MM_STATE_NULL;
MemoryManager->AddedSpace = 0;
MemoryManager->Group = 0;
MemoryManager->Size = sizeof(tMemoryManager);
MemoryManager->DoNotFree = false;
// Initialize variables of the Linking Block
MemoryManager->RootOfList.Mark = MM_MARKER_BEGIN;
MemoryManager->RootOfList.Type = GF_MM_ALLOCTYPE_MEMMAN;
MemoryManager->RootOfList.Grup = 0;
MemoryManager->RootOfList.BLID = GfMM_Counter++;
MemoryManager->RootOfList.RAdr = NULL;
MemoryManager->RootOfList.Prev = NULL;
MemoryManager->RootOfList.Next = NULL;
MemoryManager->RootOfList.Size = sizeof(tMemoryManager);
return MemoryManager;
}
//============================================================================*
@ -241,14 +251,13 @@ tMemoryManager* GfMemoryManager(void)
//============================================================================*
// Allocate memory
//----------------------------------------------------------------------------*
void* GfMemoryManagerAlloc (size_t size, unsigned int type, void* retAddr)
void* GfMemoryManagerAlloc (size_t size, uint8 type, void* retAddr)
{
if (GfMemoryManagerRunning())
{
// Need additional space for linked list and other data
int bsize =
sizeof(tDSMMLinkBlock) // Data of Memory Manager
+ sizeof(int) // Requested size of the block
+ size // Space allocated for caller
+ sizeof(int) // Marker to detect corrupted blocks
+ GfMM->AddedSpace; // Security margin for debugging
@ -286,7 +295,6 @@ void* GfMemoryManagerAlloc (size_t size, unsigned int type, void* retAddr)
c->Type = type;
c->Size = size;
c->RAdr = retAddr;
c->IDMk = MM_MARKER_ID;
int ID = c->BLID = GfMM_Counter++;
// Update statistics
@ -297,23 +305,10 @@ void* GfMemoryManagerAlloc (size_t size, unsigned int type, void* retAddr)
int* m = (int*) (e + bsize - sizeof(int));
*m = MM_MARKER_END;
// Now we have here
// c: tDSMMLinkBlock* to the current linked list data block
// n: tDSMMLinkBlock* to the next linked list data block
int* s = (int *) ++c;
*s = size;
// Now we have here
// s: (int*) pointer to the size of the allocated block
void* b = (void*) ++s;
// Now we have here
// b: (void*) official pointer to the new data block
void* b = (void*) (c + 1); //c is still pointing to the data
// Hunting memory leaks ...
#define IDTOSTOP 464790 // ID of block you are looking for
#define IDTOSTOP 6506 // ID of block you are looking for
if (ID == IDTOSTOP)
{
@ -327,17 +322,7 @@ void* GfMemoryManagerAlloc (size_t size, unsigned int type, void* retAddr)
}
else
{
int* b = (int*) GlobalAlloc(GMEM_FIXED, sizeof(int) + size);
if (b == NULL) // did malloc succeed?
{
#ifdef ANSI_ISO
throw std::bad_alloc(); // ANSI/ISO compliant behavior
#else
return b;
#endif
}
*b = size;
return ++b;
return (void*) GlobalAlloc(GMEM_FIXED, size);
}
}
//============================================================================*
@ -345,7 +330,7 @@ void* GfMemoryManagerAlloc (size_t size, unsigned int type, void* retAddr)
//============================================================================*
// Release memory
//----------------------------------------------------------------------------*
void GfMemoryManagerFree (void* b, unsigned int type)
void GfMemoryManagerFree (void* b, uint8 type)
{
if (b == NULL) // If already done
return; // return without action
@ -353,24 +338,14 @@ void GfMemoryManagerFree (void* b, unsigned int type)
if (GfMemoryManagerRunning())
{
// Get start of data block ...
int* s = (int*) b;
tDSMMLinkBlock* c = (tDSMMLinkBlock*) --s;
--c;
tDSMMLinkBlock* c = ((tDSMMLinkBlock*) b - 1);
// --c;
// ... Get start of data block
// Now we have here
// b: (void*) official pointer to data block
// s: (int*) to size of allocated block
// c: (tDSMMLinkBlock*) to the current linked list data block
// and will use
// n: (tDSMMLinkBlock*) to the next linked list data block
// p: (tDSMMLinkBlock*) to the previous linked list data block
// Get address to the marker at the end
// Need additional space for linked list and other data
int bsize =
sizeof(tDSMMLinkBlock) // Data of Memory Manager
+ sizeof(int) // Requested size of the block
+ c->Size // Space allocated for caller
+ sizeof(int) // Marker to detect corrupted blocks
+ GfMM->AddedSpace; // Security margin for debugging
@ -382,19 +357,15 @@ void GfMemoryManagerFree (void* b, unsigned int type)
if ((c->Mark != MM_MARKER_BEGIN) || (*m != MM_MARKER_END))
{
// Block is corrupted
if (c->IDMk != MM_MARKER_ID)
fprintf(stderr,
"Called for corrupted block; %p;\n",c);
else
fprintf(stderr,
"Called for corrupted block; %d; at; %p;\n",c->BLID,c);
fprintf(stderr,
"Called for corrupted block; %d; at; %p;\n",c->BLID,c);
// Hunting corrupted blocks ...
if (c->BLID == IDTOSTOP)
{
c->BLID = 0; // set breakpoint here
}
// ... Hunting corrupted blocks
// Hunting corrupted blocks ...
if (c->BLID == IDTOSTOP)
{
c->BLID = 0; // set breakpoint here
}
// ... Hunting corrupted blocks
}
// Check call type (new/delete or malloc/free)
else if (c->Type != type)
@ -451,8 +422,9 @@ void GfMemoryManagerSetup(int AddedSpace)
//============================================================================*
// Initialize the global memory manager
// Returns true if Manager was created, false if it existed before
//----------------------------------------------------------------------------*
bool GfMemoryManagerAllocate(void)
bool GfMemoryManagerInitialize(void)
{
if (GfMM == NULL)
{
@ -465,7 +437,7 @@ bool GfMemoryManagerAllocate(void)
{
GfMemoryManagerRelease();
GfMM = NULL;
return GfMemoryManagerAllocate();
return GfMemoryManagerInitialize();
}
}
return false;
@ -474,24 +446,28 @@ bool GfMemoryManagerAllocate(void)
//============================================================================*
// Destroy the one and only global memory manager and it's allocated data
// Dump = true: Dump info to console
//----------------------------------------------------------------------------*
void GfMemoryManagerRelease(bool Dump)
{
int LeakSizeTotal = 0;
int LeakSizeNewTotal = 0;
int LeakSizeMallocTotal = 0;
unsigned int LeakSizeTotal = 0;
unsigned int LeakSizeNewTotal = 0;
unsigned int LeakSizeMallocTotal = 0;
int MaxLeakSizeTotal = 0;
int MaxLeakSizeNewTotal = 0;
int MaxLeakSizeMallocTotal = 0;
unsigned int MaxLeakSizeTotal = 0;
unsigned int MaxLeakSizeNewTotal = 0;
unsigned int MaxLeakSizeMallocTotal = 0;
if (GfMM != NULL)
{
tDSMMLinkBlock* Block = GfMM->GarbageCollection;
tMemoryManager* MM = GfMM;
fprintf(stderr,"\nCurrent size requested : %d [Byte]",MM->Requested);
fprintf(stderr,"\nCurrent size allocated : %d [Byte]\n",MM->Allocated);
if (Dump)
{
fprintf(stderr,"\nCurrent size requested : %d [Byte]",MM->Requested);
fprintf(stderr,"\nCurrent size allocated : %d [Byte]\n",MM->Allocated);
}
GfMM = NULL;
@ -511,9 +487,12 @@ void GfMemoryManagerRelease(bool Dump)
if (ToFree->Type == 1)
{
fprintf(stderr,
"%04.4d; Block; %04.4d; Size; %06.6d; ReturnTo; %p; Address; %p; new/delete;\n",
++n,ToFree->BLID,ToFree->Size,ToFree->RAdr,ToFree);
if (Dump)
{
fprintf(stderr,
"%04.4d; Block; %04.4d; Size; %06.6d; ReturnTo; %p; Address; %p; new/delete;\n",
++n,ToFree->BLID,ToFree->Size,ToFree->RAdr,ToFree);
}
LeakSizeNewTotal += ToFree->Size;
if (MaxLeakSizeNewTotal < ToFree->Size)
MaxLeakSizeNewTotal = ToFree->Size;
@ -521,8 +500,11 @@ void GfMemoryManagerRelease(bool Dump)
}
else
{
fprintf(stderr,"%04.4d; Block; %04.4d; Size; %06.6d; ReturnTo; %p; Address; %p; malloc/free;\n",
++n,ToFree->BLID,ToFree->Size,ToFree->RAdr,ToFree);
if (Dump)
{
fprintf(stderr,"%04.4d; Block; %04.4d; Size; %06.6d; ReturnTo; %p; Address; %p; malloc/free;\n",
++n,ToFree->BLID,ToFree->Size,ToFree->RAdr,ToFree);
}
LeakSizeMallocTotal += ToFree->Size;
if (MaxLeakSizeMallocTotal < ToFree->Size)
MaxLeakSizeMallocTotal = ToFree->Size;
@ -531,13 +513,15 @@ void GfMemoryManagerRelease(bool Dump)
}
else
{
fprintf(stderr,"%d Block corrupted\n",++n);
if (Dump)
{
fprintf(stderr,"%d Block corrupted\n",++n);
}
CurrentBlock = NULL;
}
}
if (Dump)
{
fprintf(stderr,"\nMemory manager leak statistics:\n\n");
@ -627,6 +611,15 @@ void GfMemoryManagerDoFree(void)
GfMM->DoNotFree = false;
}
//============================================================================*
//============================================================================*
// Set Group ID for allocation of blocks
//----------------------------------------------------------------------------*
void GfMemoryManagerSetGroup(uint16 Group)
{
GfMM->Group = Group;
}
//============================================================================*
//============================================================================*
// Update statistics
@ -647,5 +640,4 @@ void GfMemoryManagerHist(size_t size)
// ... Implementation
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
#endif
// ... WDB test

View file

@ -22,91 +22,134 @@
#include <cstdio>
#include "tgf.h"
// WDB test ...
// Use new Memory Manager ...
#ifdef __DEBUG_MEMORYMANAGER__
//
// Interface
//
TGF_API bool GfMemoryManagerAllocate(void); // Initialize memory manager
TGF_API void GfMemoryManagerRelease(bool Dump = true); // Release memory manager at Shutdown
TGF_API bool GfMemoryManagerRunning(void); // Is the memory manager running?
TGF_API void GfMemoryManagerSetup(int AddedSpace);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
// Interface ...
//----------------------------------------------------------------------------*
//============================================================================*
// Data type WORD
//----------------------------------------------------------------------------*
#ifndef uint16
#define uint16 unsigned short
#endif
//============================================================================*
//============================================================================*
// Data type BYTE
//----------------------------------------------------------------------------*
#ifndef uint8
#define uint8 unsigned char
#endif
//============================================================================*
//============================================================================*
// Prototypes
//----------------------------------------------------------------------------*
TGF_API bool GfMemoryManagerInitialize(void);
// Release memory manager at Shutdown
TGF_API void GfMemoryManagerRelease(bool Dump = true);
// Is the memory manager running?
TGF_API bool GfMemoryManagerRunning(void);
// Setup parameters
TGF_API void GfMemoryManagerSetup(int AddedSpace, uint16 Group = 0);
// Switch to debug mode: keep the allocated blocks
TGF_API void GfMemoryManagerDoAccept(void);
// Switch to normal mode: free the blocks
TGF_API void GfMemoryManagerDoFree(void);
//
// Set the Group ID used while allocation of blocks (old and new blocks)
TGF_API void GfMemoryManagerSetGroup(uint16 Group);
//============================================================================*
//
// Implementation
//
//----------------------------------------------------------------------------*
// ... Interface
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
// Implementation ...
//----------------------------------------------------------------------------*
//============================================================================*
// Memory manager states
//----------------------------------------------------------------------------*
#define GF_MM_STATE_NULL 0 // memory manager was created
#define GF_MM_STATE_INIT 1 // memory manager was initialized
#define GF_MM_STATE_USED 2 // memory manager was used
//============================================================================*
//============================================================================*
// Memory manager allocation types
//----------------------------------------------------------------------------*
#define GF_MM_ALLOCTYPE_MEMMAN 0 // allocation for memory manager
#define GF_MM_ALLOCTYPE_NEW 1 // allocation by new
#define GF_MM_ALLOCTYPE_NEWARRAY 2 // allocation by new
#define GF_MM_ALLOCTYPE_MALLOC 3 // allocation by calloc
#define GF_MM_ALLOCTYPE_MALLOC 2 // allocation by calloc
//============================================================================*
//============================================================================*
// Memory manager check markers
#define MM_MARKER_BEGIN 11223344 // Value of marker at start of the block
#define MM_MARKER_ID 123456789 // Value of marker in front of the ID
#define MM_MARKER_END 44332211 // Value of marker at the end of the block
//----------------------------------------------------------------------------*
#define MM_MARKER_BEGIN 170 // Marker: Start of the block (b 10101010)
#define MM_MARKER_END 1431655765 // (b 01010101 01010101 01010101 01010101)
//============================================================================*
//============================================================================*
// Memory manager histogram
#define MAXBLOCKSIZE 4096 // Definition of the max block size for histogram
//
//----------------------------------------------------------------------------*
//#define MAXBLOCKSIZE 4096 // Definition of the max block size for histogram
#define MAXBLOCKSIZE 1024 // Definition of the max block size for histogram
//============================================================================*
// Memory manager worker functions
void* GfMemoryManagerAlloc(size_t size, unsigned int type, void* retAddr);
void GfMemoryManagerFree(void* b, unsigned int type);
//============================================================================*
// Prototypes of the Memory Manager worker functions
//----------------------------------------------------------------------------*
void* GfMemoryManagerAlloc(size_t size, uint8 type, void* retAddr);
void GfMemoryManagerFree(void* b, uint8 type);
void GfMemoryManagerHist(size_t size);
//
//============================================================================*
//============================================================================*
// Block to link allocated memory blocks in a
// double linked list and some additional flags to check
// integrity of block at call of free
//----------------------------------------------------------------------------*
typedef struct tDSMMLinkBlock
{
unsigned int Mark; // Marker to identify it as tDSMMLinkBlock
int Size; // Size of allocated block
uint8 Mark; // Marker to identify it as start of tDSMMLinkBlock
uint8 Type; // Type of allocation
uint16 Grup; // Allocation group
unsigned int BLID; // ID of allocated memory block
void* RAdr; // Return address of new/malloc
tDSMMLinkBlock* Prev; // Previous memory block
tDSMMLinkBlock* Next; // Next memory block
unsigned int Type; // Type of allocation
unsigned int IDMk; // Marker to check ID is still valid
unsigned int BLID; // ID of allocated memory block
unsigned int Size; // Size of allocated block
} tDSMMLinkBlock;
//============================================================================*
//
//============================================================================*
// Memory Manager
//
//----------------------------------------------------------------------------*
typedef struct
{
tDSMMLinkBlock RootOfList; // Root of the double linked list
tDSMMLinkBlock* GarbageCollection; // Double linked list of allocated memory blocks
size_t Size; // Size of memory manager
int State; // State of memory manager
int AddedSpace; // Number of bytes added to each block
bool DoNotFree; // Do not free the blocks if flag is set
unsigned int Allocated; // Current total of allocated memory [Bytes]
unsigned int MaxAllocated; // Maximum size of allocated memory at a time [Bytes]
unsigned int Requested; // Current total of requested memory [Bytes]
unsigned int MaxRequested; // Maximum size of requested memory at a time [Bytes]
tDSMMLinkBlock* GarbageCollection; // Double linked list of allo. blocks
unsigned int Allocated; // Current total of alloc. mem. [Bytes]
unsigned int MaxAllocated; // Maximum size of alloc. mem. [Bytes]
unsigned int Requested; // Current total of requested mem.
unsigned int MaxRequested; // Maximum size of requested mem.
unsigned int BigB; // Number of big blocks requested
unsigned int Hist[MAXBLOCKSIZE]; // Histogram of the buufer sizes
int State; // State of memory manager
int AddedSpace; // Number of bytes added to each block
uint16 Group; // Allocation group
size_t Size; // Size of memory manager
bool DoNotFree; // Do not free blocks if flag is set
} tMemoryManager;
//
//============================================================================*
#endif // #ifdef __DEBUG_MEMORYMANAGER__
// ... WDB test
// ... Use new Memory Manager
#endif /* __MEMORYMANAGER__H__ */

View file

@ -222,7 +222,7 @@ TGF_API void GfPoolMove(tMemoryPool* oldPool, tMemoryPool* newPool);
// Configuration for the new Memory Manager
//----------------------------------------------------------------------------*
// To enable the hunting for memory leaks uncomment the following line
//#define __DEBUG_MEMORYMANAGER__
#define __DEBUG_MEMORYMANAGER__
#if defined(__DEBUG_MEMORYMANAGER__)
// Use new Memory Manager ...
#if defined(WIN32)

View file

@ -40,34 +40,46 @@
#include <iraceengine.h>
#include <iuserinterface.h>
// WDB test ...
// If defined in tgf.h:
// Use new Memory Manager ...
#ifdef __DEBUG_MEMORYMANAGER__
#include "memmanager.h"
// Use global variables for debugging ...
IUserInterface* piUserItf = 0;
GfModule* pmodUserItf = NULL;
IRaceEngine* piRaceEngine = 0;
GfModule* pmodRaceEngine = NULL;
// ... Use global variables for debugging
// Garbage Collection in case of GfuiApp().restart();
void ReleaseData(void)
{
// Shortcut: Use Memory Manager as garbage collector
GfMemoryManagerRelease(false); // Release the memory manager without dump
/*
// For debugging only ...
if (piUserItf && piRaceEngine)
{
// Shutdown and unload the user interface and race engine modules.
piUserItf->shutdown();
piRaceEngine->shutdown();
// piUserItf->shutdown();
// piRaceEngine->shutdown();
GfModule::unload(pmodUserItf);
GfModule::unload(pmodRaceEngine);
// GfModule::unload(pmodUserItf);
// GfModule::unload(pmodRaceEngine);
// Shutdown the data layer.
//GfData::shutdown(); << causes crashes if called from here
// GfData::shutdown(); << causes crashes if called from here
GfMemoryManagerRelease(false); // Release the memeory manager without dump
// Shortcut: Use Memory Manager as garbage collector
GfMemoryManagerRelease(false); // Release the memory manager without dump
}
// ... For debugging only
*/
}
#endif
// ... WDB test
#endif
// ... Use new Memory Manager
/*
* Function
@ -86,27 +98,32 @@ void ReleaseData(void)
int
main(int argc, char *argv[])
{
// WDB test ...
#ifdef __DEBUG_MEMORYMANAGER__
// If defined in tgf.h:
// Use new Memory Manager ...
#ifdef __DEBUG_MEMORYMANAGER__
#if defined(_DEBUG)
fprintf(stderr,"__DEBUG_MEMORYMANAGER__ enabled\n\n");
fprintf(stderr,"If debugging -> Attach to the process ... \n");
fprintf(stderr,"\nand than press [Enter] to start the program\n");
getchar();
#endif
// THIS HAS TO BE THE FIRST LINE OF CODE!!!
GfMemoryManagerAllocate();
// THIS HAS TO BE THE FIRST LINE OF CODE (except the console output)!!!
GfMemoryManagerInitialize();
// Because there are some memory blocks that are allocated too small
// we get corrupted the following memory blocks.
// To avoid it, we can use an additional size (4 Bytes per block)
// while allocation!
// For hunting of corrupted memory blocks comment the following line
//GfMemoryManagerSetup(4); // Add 4 bytes per block
#endif
// ... WDB test
#else
// Use local variables ...
IUserInterface* piUserItf = 0;
GfModule* pmodUserItf = NULL;
IRaceEngine* piRaceEngine = 0;
GfModule* pmodRaceEngine = NULL;
// ... Use local variables
#endif
// ... Use new Memeory Manager
// Look for the "text-only" option flag in the command-line args.
bool bTextOnly = false;
@ -178,19 +195,10 @@ main(int argc, char *argv[])
}
// Load the user interface module (graphical or text-only UI).
// WDB test ...
#ifdef __DEBUG_MEMORYMANAGER__
pmodUserItf =
#else
GfModule* pmodUserItf =
#endif
GfModule::load("modules/userinterface", (bTextOnly ? "textonly" : "legacymenu"));
// Check that it implements IUserInterface.
#ifdef __DEBUG_MEMORYMANAGER__
#else
IUserInterface* piUserItf = 0;
#endif
if (pmodUserItf)
{
piUserItf = pmodUserItf->getInterface<IUserInterface>();
@ -206,17 +214,9 @@ main(int argc, char *argv[])
GfParmReadFile(ossParm.str().c_str(), GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT);
const char* pszModName = GfParmGetStr(hREParams, "Modules", "racing", "standardgame");
#ifdef __DEBUG_MEMORYMANAGER__
pmodRaceEngine = GfModule::load("modules/racing", pszModName);
#else
GfModule* pmodRaceEngine = GfModule::load("modules/racing", pszModName);
#endif
// Check that it implements IRaceEngine.
#ifdef __DEBUG_MEMORYMANAGER__
#else
IRaceEngine* piRaceEngine = 0;
#endif
if (pmodRaceEngine)
{
piRaceEngine = pmodRaceEngine->getInterface<IRaceEngine>();
@ -231,10 +231,8 @@ main(int argc, char *argv[])
if (piUserItf && piRaceEngine)
{
#ifdef __DEBUG_MEMORYMANAGER__
// Allow to avoid memory leaks at restart
// Allow to use Garbage Collection in case of GfuiApp().restart();
pApp->ReleaseData = &ReleaseData;
#endif
// Enter the user interface.
if (piUserItf->activate())
@ -265,14 +263,15 @@ main(int argc, char *argv[])
std::cerr << "Exiting from " << strAppName
<< " after some error occurred (see above)." << std::endl;
// WDB test ...
// If defined in tgf.h:
// Use new Memory Manager ...
#ifdef __DEBUG_MEMORYMANAGER__
// THIS HAS TO BE THE LAST LINE OF CODE BEFORE RETURN!!!
GfMemoryManagerRelease();
#endif
// ... WDB test
// ... Use new Memory Manager
return (piUserItf && piRaceEngine) ? 0 : 1;
}

View file

@ -272,7 +272,8 @@ void NetClient::SetDriverReady(bool bReady)
msg.pack_int(idx);
msg.pack_int(bReady);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SetDriverReady: packed buffer error\n");
}
@ -332,7 +333,8 @@ bool NetClient::SendDriverInfoPacket(NetDriver *pDriver)
msg.pack_string(pDriver->type, sizeof pDriver->type);
msg.pack_int(pDriver->client);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendDriverInfoPacket: packed buffer error\n");
}
@ -362,7 +364,8 @@ void NetClient::SendReadyToStartPacket()
msg.pack_ubyte(CLIENTREADYTOSTART_PACKET);
msg.pack_stdstring(strDName);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendReadyToStartPacket: packed buffer error\n");
}
@ -388,7 +391,8 @@ void NetClient::SendServerTimeRequest()
{
msg.pack_ubyte(SERVER_TIME_REQUEST_PACKET);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendServerTimeRequest: packed buffer error\n");
}
@ -429,7 +433,8 @@ void NetClient::ReadStartTimePacket(ENetPacket *pPacket)
msg.unpack_ubyte();
m_racestarttime = msg.unpack_double();
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadStartTimePacket: packed buffer error\n");
}
@ -686,7 +691,8 @@ void NetClient::ReadAllDriverReadyPacket(ENetPacket *pPacket)
UnlockNetworkData();
SetRaceInfoChanged(true);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadAllDriverReadyPacket: packed buffer error\n");
}
@ -708,7 +714,8 @@ void NetClient::ReadFinishTimePacket(ENetPacket *pPacket)
pNData->m_finishTime = msg.unpack_double();
UnlockNetworkData();
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadFinishTimePacket: packed buffer error\n");
}
@ -733,7 +740,8 @@ void NetClient::ReadTimePacket(ENetPacket *pPacket)
msg.unpack_ubyte();
time = msg.unpack_double();
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadTimePacket: packed buffer error\n");
}
@ -767,7 +775,8 @@ void NetClient::ReadFilePacket(ENetPacket *pPacket)
msg.unpack_string(filedata, filesize);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadFilePacket: packed buffer error\n");
}

View file

@ -445,7 +445,8 @@ void NetNetwork::SendLapStatusPacket(tCarElt *pCar)
msg.pack_int(pCar->race.laps);
msg.pack_int(pCar->info.startRank);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendLapStatusPacket: packed buffer error\n");
}
@ -517,7 +518,8 @@ void NetNetwork::SendCarStatusPacket(tSituation *s,bool bForce)
msg.pack_float(local[i]->priv.fuel);
}
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendCarStatusPacket: packed buffer error\n");
}
@ -609,7 +611,8 @@ void NetNetwork::SendCarControlsPacket(tSituation *s)
msg.pack_float(local[i]->pub.DynGCg.acc.az);
}
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendCarControlsPacket: packed buffer error\n");
}
@ -639,7 +642,8 @@ void NetNetwork::ReadLapStatusPacket(ENetPacket *pPacket)
lstatus.laps = msg.unpack_int();
lstatus.startRank = msg.unpack_int();
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadLapStatusPacket: packed buffer error\n");
}
@ -718,7 +722,8 @@ void NetNetwork::ReadCarStatusPacket(ENetPacket *pPacket)
UnlockNetworkData();
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadCarStatusPacket: packed buffer error\n");
}
@ -813,7 +818,8 @@ void NetNetwork::ReadCarControlsPacket(ENetPacket *pPacket)
UnlockNetworkData();
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadCarControlsPacket: packed buffer error\n");
}

View file

@ -191,7 +191,8 @@ void NetServer::SendStartTimePacket(int &startTime)
msg.pack_ubyte(RACESTARTTIME_PACKET);
msg.pack_double(m_racestarttime);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendStartTimePacket: packed buffer error\n");
}
@ -500,7 +501,8 @@ bool NetServer::SendPlayerAcceptedPacket(ENetPeer * pPeer)
{
msg.pack_ubyte(PLAYERACCEPTED_PACKET);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendPlayerAcceptedPacket: packed buffer error\n");
}
@ -528,7 +530,8 @@ bool NetServer::SendPlayerRejectedPacket(ENetPeer * pPeer,std::string strReason)
msg.pack_ubyte(PLAYERREJECTED_PACKET);
msg.pack_stdstring(strReason);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendPlayerRejectedPacket: packed buffer error\n");
}
@ -563,7 +566,8 @@ void NetServer::SendDriversReadyPacket()
msg.pack_int(pNData->m_vecReadyStatus[i]);
}
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendDriversReadyPacket: packed buffer error\n");
}
@ -588,7 +592,8 @@ void NetServer::SendRaceSetupPacket()
{
msg.pack_ubyte(RACEINFOCHANGE_PACKET);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendRaceSetupPacket: packed buffer error\n");
}
@ -622,7 +627,8 @@ void NetServer::ReadDriverReadyPacket(ENetPacket *pPacket)
idx = msg.unpack_int();
bReady = msg.unpack_int() ? true : false;
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendRaceSetupPacket: packed buffer error\n");
bReady = false;
@ -669,7 +675,8 @@ void NetServer::ReadDriverInfoPacket(ENetPacket *pPacket, ENetPeer * pPeer)
driver.client = msg.unpack_int() ? true : false;
driver.active = true;
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadDriverInfoPacket: packed buffer error\n");
}
@ -749,7 +756,8 @@ void NetServer::SendWeatherPacket()
msg.pack_ubyte(WEATHERCHANGE_PACKET);
//TODO add weather data here
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendWeatherPacket: packed buffer error\n");
}
@ -778,7 +786,8 @@ void NetServer::SendTimePacket(ENetPacket *pPacketRec, ENetPeer * pPeer)
msg.pack_ubyte(SERVER_TIME_SYNC_PACKET);
msg.pack_double(time);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendTimePacket: packed buffer error\n");
}
@ -843,7 +852,8 @@ void NetServer::SendFilePacket(const char *pszFile)
msg.pack_uint(filesize);
msg.pack_string(buf, size);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendFilePacket: packed buffer error\n");
}
@ -955,7 +965,8 @@ void NetServer::RemovePlayerFromRace(unsigned int idx)
msg.pack_float(vecCarStatus[i].fuel);
}
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("RemovePlayerFromRace: packed buffer error\n");
}
@ -998,7 +1009,8 @@ void NetServer::ReadPacket(ENetEvent event)
l = msg.unpack_int();
msg.unpack_string(name, l);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("ReadPacket: packed buffer error\n");
}
@ -1066,7 +1078,8 @@ void NetServer::SendFinishTimePacket()
msg.pack_ubyte(FINISHTIME_PACKET);
msg.pack_double(time);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendFinishTimePacket: packed buffer error\n");
}
@ -1104,7 +1117,8 @@ void NetServer::SendPrepareToRacePacket()
{
msg.pack_ubyte(PREPARETORACE_PACKET);
}
catch (PackedBufferException &e)
// catch (PackedBufferException &e)
catch (PackedBufferException)
{
GfLogFatal("SendPrepareToRacePacket: packed buffer error\n");
}

View file

@ -1149,7 +1149,8 @@ ReInitialiseGeneticOptimisation()
void
ReImportGeneticParameters()
{
ReLogOptim.info("\n\nImport Genetic Parameters ...\n\n");
ReLogOptim.info("\n\n");
ReLogOptim.info("Import Genetic Parameters ...\n\n");
// Setup pointer to structure
tgenData *Data = &TGeneticParameter::Data;
@ -1363,7 +1364,8 @@ ReImportGeneticParameters()
ReLogOptim.info("Write parameters to initial xml file\n");
GfParmWriteFileSDHeader (Data->XmlFileName, Data->Handle, Data->CarType, Data->AuthorName);
ReLogOptim.info("\n... Import Genetic Parameters\n\n");
ReLogOptim.info("\n");
ReLogOptim.info("... Import Genetic Parameters\n\n");
}
//
@ -1481,7 +1483,8 @@ SelectParameterAndMutation(tgenData *Data)
int P = 0;
double Scale = Data->Loops * Data->Loops / Data->Scale;
ReLogOptim.info("\nRandom parameter variation scale: %g\n",Scale);
ReLogOptim.info("\n");
ReLogOptim.info("Random parameter variation scale: %g\n",Scale);
// Loop over wanted selections
for (int I = 0; I < N; I++)
@ -1532,7 +1535,8 @@ SelectParameterAndMutation(tgenData *Data)
} while (P == -1); // Repeat until valid selection
}
// ReLogOptim.info("\nParameter: %g (Factor: %g) P: %d\n\n",Parameter,factor,P);
// ReLogOptim.info("\n");
// ReLogOptim.info("Parameter: %g (Factor: %g) P: %d\n\n",Parameter,factor,P);
// Get parameter from index
Param = Data->GP[P];
@ -1720,7 +1724,8 @@ ReEvolution()
if (Data->First)
{
// Run once ...
ReLogOptim.info("\nStart Optimisation\n");
ReLogOptim.info("\n");
ReLogOptim.info("Start Optimisation\n");
// ... run once
}

View file

@ -21,7 +21,37 @@
#include "sim.h"
tdble rho = 1.290; /* air density, prepare for variable environment */
tdble rho = 1.290f; /* air density, prepare for variable environment */
// Christos plausibhility check ...
tdble Max_Cl_given_Cd (tdble Cd)
{
// if Cd = 1, then all air hitting the surface is stopped.
// In any case, horizontal speed of air particles is given by
tdble ux = 1 - Cd;
// We assume no energy lost and thus can calculate the maximum
// possible vertical speed imparted to the paticles
tdble uy = sqrt(1 - ux*ux);
// So now Cl is just the imparted speed
return uy;
}
tdble Max_SCl_given_Cd (tdble Cd, tdble A)
{
tdble Cl = Max_Cl_given_Cd (Cd);
return A * Cl * rho / 2.0f;
}
tdble MaximumLiftGivenDrag (tdble drag, tdble A)
{
// We know the drag, C/2 \rho A.
// We must calculate the drag coefficient
tdble Cd = (drag / A) * 2.0f / rho;
return Max_SCl_given_Cd (Cd, A);
}
// ... Christos plausibhility check
void
SimAeroConfig(tCar *car)
@ -35,6 +65,44 @@ SimAeroConfig(tCar *car)
car->aero.Clift[1] = GfParmGetNum(hdle, SECT_AERODYNAMICS, PRM_RCL, (char*)NULL, 0.0f);
car->aero.CdBody = 0.645f * Cx * FrntArea;
car->aero.Cd = car->aero.CdBody;
float max_lift = MaximumLiftGivenDrag (0.5f * rho * Cx * FrntArea, FrntArea);
float current_lift = 2.0f * (car->aero.Clift[0] + car->aero.Clift[1]);
if (current_lift > max_lift)
{
if (car->features & FEAT_LIMITEDGROUNDEFFECT)
{
fprintf (stderr, "\n\nError: car %s, driver %s: lift coefficients (%f, %f), generate a lift of %f, while maximum theoretical value is %f -> CLift reduced\n\n",
car->carElt->_carName,
car->carElt->_name,
car->aero.Clift[0],
car->aero.Clift[1],
current_lift,
max_lift);
car->aero.Clift[0] *= max_lift/current_lift;
car->aero.Clift[1] *= max_lift/current_lift;
}
else
{
fprintf (stderr, "\n\nWarning: car %s, driver %s: lift coefficients (%f, %f), generate a lift of %f, while maximum theoretical value is %f\n\n",
car->carElt->_carName,
car->carElt->_name,
car->aero.Clift[0],
car->aero.Clift[1],
current_lift,
max_lift);
}
}
else
{
fprintf (stderr, "\n\nInfo: car %s, driver %s: lift coefficients (%f, %f), generate a lift of %f, while maximum theoretical value is %f\n\n",
car->carElt->_carName,
car->carElt->_name,
car->aero.Clift[0],
car->aero.Clift[1],
current_lift,
max_lift);
}
}
@ -217,10 +285,10 @@ SimWingConfig(tCar *car, int index)
else if (wing->WingType == 2)
{
wing->AoAatZero = GfParmGetNum(hdle, WingSect[index], PRM_AOAATZERO, (char*)NULL, 0);
wing->AoAatZero = MAX(MIN(wing->AoAatZero, 0), -PI_6);
wing->AoStall = GfParmGetNum(hdle, WingSect[index], PRM_ANGLEOFSTALL, (char*)NULL, PI_6*0.5);
wing->AoStall = MAX(MIN(wing->AoStall, PI_4), 0.017453293f);
wing->Stallw = GfParmGetNum(hdle, WingSect[index], PRM_STALLWIDTH, (char*)NULL, 0.034906585);
wing->AoAatZero = MAX(MIN(wing->AoAatZero, 0), (tdble) -PI_6);
wing->AoStall = GfParmGetNum(hdle, WingSect[index], PRM_ANGLEOFSTALL, (char*)NULL, (tdble)(PI_6*0.5));
wing->AoStall = MAX(MIN(wing->AoStall, (tdble) PI_4), 0.017453293f);
wing->Stallw = GfParmGetNum(hdle, WingSect[index], PRM_STALLWIDTH, (char*)NULL, 0.034906585f);
wing->Stallw = MAX(MIN(wing->Stallw, wing->AoStall), 0.017453293f);
wing->AR = GfParmGetNum(hdle, WingSect[index], PRM_ASPECTRATIO, (char*)NULL, 0);
}
@ -255,15 +323,15 @@ SimWingConfig(tCar *car, int index)
}
else if (wing->WingType == 2)
{
if (wing->AR > 0.001) wing->Kz1 = 2 * PI * wing->AR / (wing->AR + 2);
else wing->Kz1 = 2 * PI;
wing->Kx = 0.5 * rho * area;
wing->Kz2 = 1.05;
wing->Kz3 = 0.05;
wing->Kx1 = 0.6;
wing->Kx2 = 0.006;
wing->Kx3 = 1.0;
wing->Kx4 = 0.9;
if (wing->AR > 0.001) wing->Kz1 = (tdble) (2 * PI * wing->AR / (wing->AR + 2));
else wing->Kz1 = (tdble)(2 * PI);
wing->Kx = (tdble) (0.5 * rho * area);
wing->Kz2 = 1.05f;
wing->Kz3 = 0.05f;
wing->Kx1 = 0.6f;
wing->Kx2 = 0.006f;
wing->Kx3 = 1.0f;
wing->Kx4 = 0.9f;
}
}
@ -301,21 +369,21 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
if (wing->WingType == 2) //thin wing works for every direction
{
tdble x;
while (aoa > PI) aoa -= 2 * PI;
while (aoa < -PI) aoa += 2 * PI;
while (aoa > PI) aoa -= (tdble) (2 * PI);
while (aoa < -PI) aoa += (tdble) (2 * PI);
/* first calculate coefficients */
if (aoa > PI_2)
{
if (aoa > PI - wing->AoStall) wing->forces.x = wing->Kx1 * (PI - aoa) * (PI - aoa) + wing->Kx2;
else wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
if (aoa > PI - wing->AoStall) wing->forces.x = (tdble) (wing->Kx1 * (PI - aoa) * (PI - aoa) + wing->Kx2);
else wing->forces.x = (tdble) (wing->Kx3 - wing->Kx4 * cos(2*aoa));
if (aoa > PI - wing->AoStall + wing->Stallw)
{x = (tdble)0.0;}
else
{
x = aoa - PI + wing->AoStall - wing->Stallw;
x = x * x / (x * x + wing->Stallw * wing->Stallw);
x = (tdble) (aoa - PI + wing->AoStall - wing->Stallw);
x = (tdble) (x * x / (x * x + wing->Stallw * wing->Stallw));
}
wing->forces.z = -(1-x) * wing->Kz1 * (aoa - PI + wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) + wing->Kz3);
wing->forces.z = (tdble) (-(1-x) * wing->Kz1 * (aoa - PI + wing->AoAatZero) - x * (wing->Kz2 * sin(2*aoa) + wing->Kz3));
}
else if (aoa > 0)
{
@ -345,28 +413,28 @@ SimWingUpdate(tCar *car, int index, tSituation* s)
}
else
{
if (aoa < wing->AoStall - PI) wing->forces.x = wing->Kx1 * (PI + aoa) * (PI + aoa) + wing->Kx2;
if (aoa < wing->AoStall - PI) wing->forces.x = (tdble) (wing->Kx1 * (PI + aoa) * (PI + aoa) + wing->Kx2);
else wing->forces.x = wing->Kx3 - wing->Kx4 * cos(2*aoa);
if (aoa < wing->AoStall - wing->Stallw - PI)
{x = (tdble)0.0;}
else
{
x = aoa - wing->AoStall + wing->Stallw + PI;
x = (tdble) (aoa - wing->AoStall + wing->Stallw + PI);
x = x * x / (x * x + wing->Stallw * wing->Stallw);
}
wing->forces.z = -(1-x) * wing->Kz1 * (aoa + wing->AoAatZero + PI) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3);
wing->forces.z = (tdble) (-(1-x) * wing->Kz1 * (aoa + wing->AoAatZero + PI) - x * (wing->Kz2 * sin(2*aoa) - wing->Kz3));
}
/* add induced drag */
if (wing->AR > 0.001)
{
if (wing->forces.x > 0.0)
wing->forces.x += wing->forces.z * wing->forces.z / (wing->AR * 2.8274); //0.9*PI
else wing->forces.x -= wing->forces.z * wing->forces.z / (wing->AR * 2.8274);
wing->forces.x += (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274)); //0.9*PI
else wing->forces.x -= (tdble) (wing->forces.z * wing->forces.z / (wing->AR * 2.8274));
}
/* then multiply with 0.5*rho*area and the square of velocity */
wing->forces.x *= - car->DynGC.vel.x * fabs(car->DynGC.vel.x) * wing->Kx * (1.0f + (tdble)car->dammage / 10000.0);
wing->forces.x *= (tdble)(- car->DynGC.vel.x * fabs(car->DynGC.vel.x) * wing->Kx * (1.0f + (tdble)car->dammage / 10000.0));
wing->forces.z *= wing->Kx * vt2;
}
else if (car->DynGC.vel.x > 0.0f)

View file

@ -81,6 +81,11 @@ SimCarConfig(tCar *car)
if (strcmp(enabling, VAL_YES) == 0) {
car->features = car->features | FEAT_ESPINSIMU;
}
enabling = GfParmGetStr(hdle, SECT_FEATURES, PRM_LIMITEDGROUNDEFFECT, VAL_NO);
if (strcmp(enabling, VAL_YES) == 0) {
car->features = car->features | FEAT_LIMITEDGROUNDEFFECT;
}
/* continue with car parameters */
car->dimension.x = GfParmGetNum(hdle, SECT_CAR, PRM_LEN, (char*)NULL, 4.7f);