47#ifdef SAF_ENABLE_TRACKER_MODULE
56 *phT3d = (
void*)pData;
79 memset(pData->
R, 0, 3*3*
sizeof(
float));
80 pData->
R[0][0] = powf(sd_xyz,2.0f);
81 pData->
R[1][1] = powf(sd_xyz,2.0f);
82 pData->
R[2][2] = powf(sd_xyz,2.0f);
90 { {0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
91 {0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f},
92 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
93 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
94 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
95 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f} };
96 memset(Qc, 0, 6*6*
sizeof(
float));
100 lti_disc((
float*)F, 6, 6, NULL, (
float*)Qc, pData->
tpars.
dt, (
float*)pData->
A, (
float*)pData->
Q);
101 memset(pData->
H, 0, 3*6*
sizeof(
float));
102 pData->
H[0][0] = 1.0f;
103 pData->
H[1][1] = 1.0f;
104 pData->
H[2][2] = 1.0f;
113 for(i=0; i<pData->
tpars.
Np; i++){
138 for(i=0; i<pData->
tpars.
Np; i++){
163 for(i=0; i<pData->
tpars.
Np; i++)
172 float** target_pos_xyz,
173 float** target_var_xyz,
179 int i, kt, ob, maxIdx, nt;
188#ifdef TRACKER_VERBOSE
189 char c_str[256], tmp[256];
190 memset(c_str, 0, 256*
sizeof(
char));
196 if(nObs>0 && newObs_xyz!=NULL){
197 for(ob=0; ob<nObs; ob++){
206 if (Neff < (
float)pData->
tpars.
Np/4.0f){
207#ifdef TRACKER_VERBOSE
208 printf(
"%s\n",
"Resampling");
211 for(i=0; i<pData->
tpars.
Np; i++)
215 for(i=0; i<pData->
tpars.
Np; i++)
217 for(i=0; i<pData->
tpars.
Np; i++){
225 for(i=0; i<pData->
tpars.
Np; i++){
240 free((*target_pos_xyz));
241 free((*target_var_xyz));
243 (*target_pos_xyz) = NULL;
244 (*target_var_xyz) = NULL;
245 (*target_IDs) = NULL;
247#ifdef TRACKER_VERBOSE
248 printf(
"%s\n",
"No targets");
252 (*target_pos_xyz) =
realloc1d((*target_pos_xyz), S_max->
nTargets*3*
sizeof(
float));
253 (*target_var_xyz) =
realloc1d((*target_var_xyz), S_max->
nTargets*3*
sizeof(
float));
258 for(nt=0; nt<S_max->
nTargets; nt++){
259#ifdef TRACKER_VERBOSE
260 sprintf(tmp,
"ID_%d: [%.5f,%.5f,%.5f] ", S_max->
targetIDs[nt], S_max->
M[nt].m0, S_max->
M[nt].m1, S_max->
M[nt].m2);
264 (*target_IDs)[nt] = S_max->
targetIDs[nt];
265 (*target_pos_xyz)[nt*3] = S_max->
M[nt].m0;
266 (*target_pos_xyz)[nt*3+1] = S_max->
M[nt].m1;
267 (*target_pos_xyz)[nt*3+2] = S_max->
M[nt].m2;
268 (*target_var_xyz)[nt*3] = S_max->
P[nt].p00;
269 (*target_var_xyz)[nt*3+1] = S_max->
P[nt].p11;
270 (*target_var_xyz)[nt*3+2] = S_max->
P[nt].p22;
275 (*target_pos_xyz)[nt*3] *= S_max->
W;
276 (*target_pos_xyz)[nt*3+1] *= S_max->
W;
277 (*target_pos_xyz)[nt*3+2] *= S_max->
W;
278 (*target_var_xyz)[nt*3] *= S_max->
W;
279 (*target_var_xyz)[nt*3+1] *= S_max->
W;
280 (*target_var_xyz)[nt*3+2] *= S_max->
W;
283 for(
int p = 0; p<pData->
tpars.
Np; p++){
286 for(nt2=0; nt2<S_tmp->
nTargets; nt2++){
287 if((*target_IDs)[nt] == S_tmp->
targetIDs[nt2]){
289 (*target_pos_xyz)[nt*3] += (S_tmp->
M[nt2].m0 * S_tmp->
W);
290 (*target_pos_xyz)[nt*3+1] += (S_tmp->
M[nt2].m1 * S_tmp->
W);
291 (*target_pos_xyz)[nt*3+2] += (S_tmp->
M[nt2].m2 * S_tmp->
W);
292 (*target_var_xyz)[nt*3] += (S_tmp->
P[nt2].p00 * S_tmp->
W);
293 (*target_var_xyz)[nt*3+1] += (S_tmp->
P[nt2].p11 * S_tmp->
W);
294 (*target_var_xyz)[nt*3+2] += (S_tmp->
P[nt2].p22 * S_tmp->
W);
301 (*target_pos_xyz)[nt*3] /= w_sum;
302 (*target_pos_xyz)[nt*3+1] /= w_sum;
303 (*target_pos_xyz)[nt*3+2] /= w_sum;
304 (*target_var_xyz)[nt*3] /= w_sum;
305 (*target_var_xyz)[nt*3+1] /= w_sum;
306 (*target_var_xyz)[nt*3+2] /= w_sum;
309#ifdef TRACKER_VERBOSE
310 printf(
"%s\n", c_str);
void tracker3d_reset(void *const hT3d)
Resets an instance of the mighty tracker3d.
void tracker3d_destroy(void **const phT3d)
Destroys an instance of the mighty tracker3d.
void tracker3d_step(void *const hT3d, float *newObs_xyz, int nObs, float **target_pos_xyz, float **target_var_xyz, int **target_IDs, int *nTargets)
Tracker time step to update & predict current target locations and to parse new measurements/observat...
void tracker3d_create(void **const phT3d, tracker3d_config tpars)
Creates an instance of the mighty tracker3d.
#define saf_assert(x, message)
Macro to make an assertion, along with a string explaining its purpose.
#define SAF_CLAMP(a, min, max)
Ensures value "a" is clamped between the "min" and "max" values.
#define SAF_MAX(a, b)
Returns the maximum of the two values.
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
void * realloc1d(void *ptr, size_t dim1_data_size)
1-D realloc (same as realloc, but with error checking)
void * voidPtr
Void pointer (just to improve code readability when working with arrays of handles)
Particle filtering based 3D multi-target tracker (SAF_TRACKER_MODULE)
void tracker3d_update(void *const hT3d, float *Y, int Tinc)
Prediction update.
void tracker3d_particleDestroy(void **phPart)
Destroys an instance of a particle / Monte-Carlo Sample.
void tracker3d_particleReset(void *hPart)
Resets a particle structure to defaults.
void kf_update6_create(void **const phUp6)
Creates helper structure for kf_update6()
void tracker3d_particleCopy(void *hPart1, void *hPart2)
Copies particle structure "hPart1" into structure "hPart2".
void tracker3d_predict(void *const hT3d, int Tinc)
Prediction step.
void lti_disc(float *F, int len_N, int len_Q, float *opt_L, float *opt_Qc, float dt, float *A, float *Q)
LTI_DISC Discretize LTI ODE with Gaussian Noise.
int tracker3d_getMaxParticleIdx(void *const hT3d)
Returns the index of the most important particle.
void tracker3d_particleCreate(void **phPart, float W0, float dt)
Creates an instance of a particle / Monte-Carlo Sample.
float eff_particles(voidPtr *SS, int NP)
Estimate the number of effective particles.
void kf_update6_destroy(void **const phUp6)
Destroys helper structure for kf_update6()
Particle filtering based 3D multi-target tracker (SAF_TRACKER_MODULE)
#define TRACKER3D_MAX_NUM_EVENTS
Maximum number of possible events during update.
#define TRACKER3D_MAX_NUM_PARTICLES
Maximum number of particles.
Monte-Carlo Sample (particle) structure.
P66 * P
Current target variances; nTargets x ([6][6])
float W
Importance weight.
int * targetIDs
Unique ID assigned to each target; nTargets x 1.
int nTargets
Number of targets being tracked.
M6 * M
Current target means; nTargets x ([6])
User parameters for tracker3d.
float dt
Elapsed time (in seconds) between observations/measurements.
float cd
PRIOR probability of noise.
float init_birth
PRIOR probability of birth [0 1].
float measNoiseSD
Measurement noise standard deviation.
int ARE_UNIT_VECTORS
1: if the Cartesian coordinates are given as unit vectors, 0: if not
float beta_death
Coefficient influencing the likelihood that a target will die; always >= 1.
float alpha_death
Coefficient influencing the likelihood that a target will die; always >= 1.
int Np
Number of Monte Carlo samples/particles.
float noiseLikelihood
Likelihood of an estimate being noise/clutter between [0..1].
float W_avg_coeff
Real-time tracking is based on the particle with highest weight.
float noiseSpecDen
Noise spectral density; influences the smoothness of the traget tracks.
Main structure for tracker3d.
int incrementTime
Number steps of "tpars.dt" to increment time by.
float W0
PRIOR importance weight.
float Q[6][6]
Discrete Process Covariance.
tracker3d_config tpars
User parameters struct.
float R[3][3]
Diagonal matrix, measurement noise PRIORs along the x,y,z axes.
int evta[TRACKER3D_MAX_NUM_EVENTS]
Event targets.
voidPtr * SS_resamp
Resampled particles; tpars.Np x 1.
voidPtr str[TRACKER3D_MAX_NUM_EVENTS]
Structure after each event.
voidPtr * SS
The particles; tpars.Np x 1.
float A[6][6]
Transition matrix.
float H[3][6]
Measurement matrix.
void * hKF6
kf_update6 handle