Where is the non-tunable property 'pStateSize' located in the TOMHT tracker?

Hello,
When I use the Matlab coder to create C++ code of the TOMHT tracker, an Error while checking for run-Time errors with Matlab Coder occurs. This error occurs at the line that calls the TOMHTtracker: tracks = tracker(detections,time), where tracker is a trackerTOMHT object.
The error says: Failed to compute constant value for nontunable property 'pStateSize'. In code generation, nontunable properties can only be assigned constant values.
We build our own IMM composed of a CVKF, CAKF and CTUKF. If we use any of these 3 filters instead of our IMM, their are no runtime errors found by the Matlab coder, so we must have made a mistake in the IMM. However, I cannot find the 'pStateSize' property anywhere. I was wondering if you could help me to solve this issue.
Thank you very much,
Joost

 採用された回答

Elad Kivelevitch
Elad Kivelevitch 2021 年 11 月 18 日
編集済み: Elad Kivelevitch 2021 年 11 月 18 日

0 投票

Hi,
I believe the error would be coming from matlabshared.tracking.internal.fusion.ObjectTrack. This is the internal object track object that is managed by the tracker for each target. What it means is that in code generation we could not figure out the state size of the object.
However, I am not sure why you would run into this issue in your code. This could be something we should fix.
Could you provide a little more information. What does your FilterInitializationFcn look like (maybe if you can attach that)?
And also, please let me know which MATLAB release you're currently using.
Thanks,
Elad

7 件のコメント

Joost
Joost 2021 年 11 月 18 日
Hi Elad,
thank you for your quick response. Here is the FilterInitializationFcn. The version that we are using is 2021a. Because the ukf filters didn't seem to run properly for our 2D scenario's, we stripped them to 2d versions. Individually without IMM they work.
function IMM = initukfimm2D(Detection)
%#codegen
UKF = cell(1,3);
% Creating the trackingEKF filters with constant velocity (CV), constant
% acceleration (CA) and constant turn (CT) motion models.
measurementNoise = Detection.MeasurementNoise;
UKF{1} = initcvkf2D(Detection);
UKF{2} = initcaukf2D(Detection);
UKF{3} = initctukf2D(Detection);
for i =1:3
%setMeasurementSizes(UKF{i}, 2, 2);
UKF{i}.MeasurementNoise = measurementNoise;
end
% Assign the function handle of model conversion function to mdlConv.
mdlConv = @switchimm2d;
% Creating the IMM filter object.
IMM = trackingIMM('TrackingFilters', UKF,...
'ModelConversionFcn', mdlConv, 'TransitionProbabilities', 0.87);
Elad Kivelevitch
Elad Kivelevitch 2021 年 11 月 18 日
Got it. Thank you.
I will investigate it and see if I can reproduce the error here and propose a workaround. I will try to get back to you with a workaround ASAP.
Hi Joost,
I have good news to share with you:
  1. I was able to reproduce the error you found. It was, indeed, thrown from the internal object track as I suspected. It was due to the 2-D constant velocity linear Kalman filter object. Coder could not completely lock the size of the state. There is a workaround for the linear Kalman filter, but because it's inside the IMM that workaround is not triggered in the internal object track logic that locks it.
  2. The issue is already fixed in a future release, which will arrive in 2022.
  3. There is a workaround, though, and it is very simple, see below.
In your code, replace the order of the linear Kalman filter with one of the nonlinear filters. For exmaple:
function IMM = initukfimm2D(Detection)
%#codegen
UKF = cell(1,3);
% Creating the trackingEKF filters with constant velocity (CV), constant
% acceleration (CA) and constant turn (CT) motion models.
measurementNoise = Detection.MeasurementNoise;
% THIS IS WHERE THE FIX IS
UKF{2} = initcvkf2D(Detection); %<----- Make this the second filter
UKF{1} = initcaukf2D(Detection); % <----- Make this the first filter
% END FIX
UKF{3} = initctukf2D(Detection);
for i =1:3
%setMeasurementSizes(UKF{i}, 2, 2);
UKF{i}.MeasurementNoise = measurementNoise;
end
% Assign the function handle of model conversion function to mdlConv.
mdlConv = @switchimm2d; % <----- Only if you want to, you could also use the regular switchimm.
% Creating the IMM filter object.
IMM = trackingIMM('TrackingFilters', UKF,...
'ModelConversionFcn', mdlConv, 'TransitionProbabilities', 0.87);
For the sake of completion, I attached the full code for initukfimm2D.m and tracker.m below
initukfimm2D
function IMM = initukfimm2D(Detection)
%#codegen
UKF = cell(1,3);
% Creating the trackingEKF filters with constant velocity (CV), constant
% acceleration (CA) and constant turn (CT) motion models.
measurementNoise = Detection.MeasurementNoise;
UKF{2} = initcvkf2D(Detection);
UKF{1} = initcaukf2D(Detection);
UKF{3} = initctukf2D(Detection);
for i =1:3
%setMeasurementSizes(UKF{i}, 2, 2);
UKF{i}.MeasurementNoise = measurementNoise;
end
% Assign the function handle of model conversion function to mdlConv.
mdlConv = @switchimm;
% Creating the IMM filter object.
IMM = trackingIMM('TrackingFilters', UKF,...
'ModelConversionFcn', mdlConv, 'TransitionProbabilities', 0.87);
end
function cvkf = initcvkf2D(detection)
classToUse = class(detection.Measurement);
H = cast([1 0 0 0; 0 0 1 0], classToUse);
x = H' * detection.Measurement;
R = detection.MeasurementNoise;
P = H' * R * H;
dP = diag(P);
isZero = (dP==0);
P = P + 100*diag(isZero);
cvkf = trackingKF("MotionModel", "2D Constant Velocity", ...
"State", x, "StateCovariance", P, "MeasurementModel", H, ...
"MeasurementNoise", R);
end
function caukf = initcaukf2D(detection)
classToUse = class(detection.Measurement);
H = cast([1 0 0 0 0 0; 0 0 0 1 0 0], classToUse);
x = H' * detection.Measurement;
R = detection.MeasurementNoise;
P = H' * R * H;
dP = diag(P);
isZero = (dP==0);
P = P + 100*diag(isZero);
caukf = trackingUKF(@constacc, @cameas2D, ...
"State", x, "StateCovariance", P, ...
"MeasurementNoise", R);
end
function caukf = initctukf2D(detection)
classToUse = class(detection.Measurement);
H = cast([1 0 0 0 0; 0 0 1 0 0], classToUse);
x = H' * detection.Measurement;
R = detection.MeasurementNoise;
P = H' * R * H;
dP = diag(P);
isZero = (dP==0);
P = P + 100*diag(isZero);
caukf = trackingUKF(@constturn, @ctmeas2D, ...
"State", x, "StateCovariance", P, ...
"MeasurementNoise", R);
end
function z = cameas2D(x, varargin)
z3 = cameas(x, varargin{:});
% Assuming a rectangular measurement
z = z3(1:2);
end
function z = ctmeas2D(x, varargin)
z3 = ctmeas(x, varargin{:});
% Assuming a rectangular measurement
z = z3(1:2);
end
tracker.m
function tracks = tracker(detections, time)
persistent trkr
if isempty(trkr)
trkr = trackerTOMHT("FilterInitializationFcn", @initukfimm2D);
end
tracks = trkr(detections, time);
end
Joost
Joost 2021 年 11 月 19 日
Thank you very much for the solution, switching the order seemed to work. I switched all my code to the code you send because it is cleaner and it also works.
Elad Kivelevitch
Elad Kivelevitch 2021 年 11 月 19 日
That's great. I am happy to hear that you are able to move forward.
Joost
Joost 2021 年 11 月 22 日
Hello Elad,
suddenly I am getting an error using the initukfimm2d function that you send me, when the Coder checks for run time errors. I do not understand why this error did not occur before, and it seems to have to do with the fact that the variable ind changes from a boolean to an array, which results in the run time error. This is the error:
Error using constvel2constturn (line 36)
Index exceeds array dimensions. Index value 4 exceeds valid range [1-1].
and this is line 34 - 36 of constvel2constturn:
ind = true;
if dims<3 % One of the models is not 3D
ind(1:2*dims) = true;
We had to change quite some files because we had to change the constvel2constturn file and give it a different name, and it seems to work. I was wondering if there is a more elegant fix for which we do not have to change so many files.
Kind regards,
Joost
Elad Kivelevitch
Elad Kivelevitch 2021 年 11 月 22 日
Hi Joost,
This seems like something we would like to take the time to look into.
To allow you to move forward, please consider adding your switchimm2D back to the IMM filter. The built-in switchimm function tries to handle multiple cases of 2D to 3D, 3D to 2D, 3D to 3D, etc. There might be a case that isn't supported fully and needs resolution.
Elad

サインインしてコメントする。

その他の回答 (0 件)

製品

リリース

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by