exponenta event banner

Обнаружение и отслеживание группировки спутников НОО наземными радарами

В этом примере показано, как импортировать файл двухстрочного элемента (TLE) спутниковой группировки, моделировать радиолокационные обнаружения группировки и отслеживать ее.

Задача заполнения и ведения каталога космических объектов, находящихся на орбите Земли, имеет решающее значение для наблюдения за космосом. Эта задача состоит из нескольких процессов: обнаружение и идентификация новых объектов и добавление их в каталог, обновление орбит известных объектов в каталоге, отслеживание изменений орбиты в течение всего срока их существования и прогнозирование повторных вхождений в атмосферу. В этом примере мы изучаем, как обнаруживать и отслеживать новые спутники и добавлять их в каталог.

Для обеспечения безопасности космической деятельности и предотвращения столкновений с другими спутниками или известным мусором важно правильно обнаруживать и отслеживать вновь запускаемые спутники. Космические агентства, как правило, делятся информацией о предварительном запуске, которую можно использовать для выбора стратегии поиска. Обычно используется стратегия поиска спутников на низкой околоземной орбите (НОО), состоящая из радиолокационных систем заборного типа. Радиолокационная система заборного типа осуществляет поиск конечного объема в космосе и обнаруживает спутники при их прохождении через поле зрения. Эта стратегия позволяет быстро обнаруживать и отслеживать вновь запускаемое созвездие. [1]

Импорт спутниковой группировки из файла TLE

Наборы двухлинейных элементов представляют собой общий формат данных для сохранения орбитальной информации спутников. Вы можете использовать satelliteScenario объект для импорта спутниковых орбит, определенных в файле TLE. По умолчанию импортированные орбиты спутника распространяются с использованием алгоритма распространения орбиты SGP4, который обеспечивает хорошую точность для объектов НОО. В этом примере эти орбиты обеспечивают наземную достоверность для проверки способности радиолокационной системы слежения обнаруживать вновь запускаемые спутники.

% Create a satellite scenario
satscene = satelliteScenario;
% Add satellites from TLE file.
tleFile = "leoSatelliteConstellation.tle";
constellation = satellite(satscene, tleFile);

Используйте средство просмотра спутниковых сценариев для визуализации группировки.

play(satscene);

Моделирование синтетических обнаружений и объединения дорожек

Моделирование радаров космического наблюдения

Определить две станции с веерообразными радиолокационными лучами, смотрящими в космос. Вентиляторы прорезают орбиты спутника, чтобы максимизировать количество обнаружений. Радиолокационные станции, расположенные на территории Северной Америки, образуют заграждение Восток-Запад.

% First station coordinates in LLA
station1 = [48 -80 0];

% Second station coordinates in LLA
station2 = [50 -117 0];

Каждая станция оснащена радаром, который моделируется с помощью fusionRadarSensor объект. Для обнаружения спутников в диапазоне НОО РЛС предъявляет следующие требования:

  • Обнаружение объекта 10 дБсм на расстоянии до 2000 км

  • Разрешение объектов по горизонтали и вертикали с точностью 100 м при дальности 2000 км

  • Наличие поля зрения 120 градусов по азимуту и 30 градусов по отметке

  • Поиск в пространстве

% Create fan-shaped monostatic radars
fov = [120;40];
radar1 = fusionRadarSensor(1,...
    'UpdateRate',0.1,... 10 sec
    'ScanMode','No scanning',...
    'MountingAngles',[0 90 0],... look up
    'FieldOfView',fov,... degrees
    'ReferenceRange',2000e3,... m
    'RangeLimits',  [0 2000e3], ... m
    'ReferenceRCS', 10,... dBsm
    'HasFalseAlarms',false,...
    'HasNoise', true,...
    'HasElevation',true,...
    'AzimuthResolution',0.03,... degrees
    'ElevationResolution',0.03,... degrees
    'RangeResolution',2000, ... m % accuracy ~= 2000 * 0.05 (m)
    'DetectionCoordinates','Sensor Spherical',...
    'TargetReportFormat','Detections');

radar2 = clone(radar1);
radar2.SensorIndex = 2;

Цепочка радиолокационной обработки

В этом примере выполняется несколько преобразований координат и преобразования осей, чтобы правильно запустить цепь радиолокационного слежения. На приведенной ниже диаграмме показано, как указанные выше входные сигналы преобразуются и передаются на радар.

На первом шаге вычисляется каждая поза спутника в осях NED локальной радиолокационной станции. Для этого сначала получают позу ECEF наземной станции и преобразуют положение и скорость спутника в координаты ECEF. Вход РЛС получают, принимая разности между позицией спутника и позицией наземной станции и поворачивая разности в локальные оси NED наземной станции. См. раздел assembleRadarInputs вспомогательная функция для подробной информации о внедрении.

На втором шаге необходимо добавить требуемую информацию к объекту обнаружения, чтобы трекер мог работать с состоянием ECEF. Вы используете MeasurementParameters свойство в каждом обнаружении объекта для достижения этой цели, как показано в addMeasurementParams поддерживающая функция.

Определение трекера

Модели радаров, определенные выше, обнаруживаются на выходе. Для оценки орбит спутника используется трекер. В Toolbox™ Sensor Fusion and Tracking предусмотрено множество многообъектных трекеров. В этом примере выбирается трекер Joint Probilistic Data Association (JPDA), поскольку он обеспечивает хороший баланс производительности отслеживания и вычислительных затрат.

Необходимо определить фильтр отслеживания для трекера. Для отслеживания спутника можно использовать модель меньшей точности, чем SGP4, например кеплеровскую интеграцию уравнения движения. Часто отсутствие точности в модели движения целей компенсируется обновлениями измерений и включением технологического шума в фильтр. Вспомогательная функция initKeplerUKF определяет фильтр отслеживания.

% Define the tracker
tracker = trackerJPDA('FilterInitializationFcn',@initKeplerUKF,...
    'HasDetectableTrackIDsInput',true,...
    'ClutterDensity',1e-40,...
    'AssignmentThreshold',1e4,...
    'DeletionThreshold',[5 8],...
    'ConfirmationThreshold',[5 8]);

Запуск моделирования

В оставшейся части этого примера рассматривается сценарий моделирования радиолокационных обнаружений и слежения за спутниками. В этом разделе используется отдельный класс помощника helperScenarioGlobeViewer для визуализации. Этот класс помощника можно использовать для отображения данных датчиков и отслеживания с эллипсами неопределенности и отображения истинного положения каждого спутника.

globeDisplay = helperScenarioGlobeViewer;

% Define coverage configuration of each radar and visualize it on the globe
ned1 = dcmecef2ned(station1(1), station1(2));
ned2 = dcmecef2ned(station2(1), station2(2));
covcon(1) = coverageConfig(radar1,lla2ecef(station1),quaternion(ned1,'rotmat','frame'));
covcon(2) = coverageConfig(radar2,lla2ecef(station2),quaternion(ned2, 'rotmat','frame'));
plotCoverage(globeDisplay, covcon)

Сначала создается вся история состояний созвездия в течение 5 часов. Затем вы имитируете радиолокационные обнаружения и генерируете дорожки в цикле.

satscene.StopTime = satscene.StartTime + hours(5);
satscene.SampleTime = 10;
numSteps = ceil(seconds(satscene.StopTime - satscene.StartTime)/satscene.SampleTime);

% Get constellation positions and velocity over the course of the simulation
plats = repmat(...
    struct('PlatformID',0,'Position',[0 0 0], 'Velocity', [0 0 0]),...
    numSteps, 40);
for i=1:numel(constellation)
    [pos, vel] = states(constellation(i),'CoordinateFrame',"Geographic");
    for j=1:numSteps
        plats(j,i).Position = pos(:,j)';
        plats(j,i).Velocity = vel(:,j)';
        plats(j,i).PlatformID = i;
    end
end

% Initialize tracks and tracks log
confTracks = objectTrack.empty(0,1);
trackLog = cell(1,numSteps);

% Initialize radar plots
radarplt = helperRadarPlot(fov);

% Set random seed for reproducible results
s = rng;
rng(2020);
step = 0;
while step < numSteps
    time = step*satscene.SampleTime;
    step = step + 1;
    
    % Generate detections of the constellation following the radar
    % processing chain
    targets1 = assembleRadarInputs(station1, plats(step,:));
    [dets1,numdets1] = radar1(targets1, time);
    dets1 = addMeasurementParams(dets1,numdets1,station1);
    
    targets2 = assembleRadarInputs(station2, plats(step,:));
    [dets2, numdets2] = radar2(targets2, time);
    dets2 = addMeasurementParams(dets2, numdets2, station2);
    
    detections = [dets1; dets2];
    updateRadarPlots(radarplt,targets1, targets2 ,dets1, dets2)
    
    % Generate and update tracks
    detectableInput = isDetectable(tracker,time, covcon);
    if ~isempty(detections) || isLocked(tracker)
        [confTracks,~,~,info] = tracker(detections,time,detectableInput);
%         confTracks = deleteBadTracks(tracker,confTracks);
    end
    trackLog{step} = confTracks;

    % Update globe display
    updateDisplay(globeDisplay,time,plats(step,:),detections,[],confTracks);
            
end

На графике выше показаны орбиты (синие точки) и обнаружения (красные круги) с точки зрения каждого радара.

% Restore previous random seed state
rng(s);
figure;
snap(globeDisplay);

После 5 часов слежения успешно отслеживается примерно половина созвездия. Поддержание путей с частичным охватом орбиты является сложной задачей, поскольку спутники часто могут оставаться незамеченными в течение длительных периодов времени в такой конфигурации. В этом примере имеется только две радиолокационные станции. Ожидается, что дополнительные станции отслеживания позволят повысить эффективность отслеживания. Метрики назначения, которые оценивают производительность отслеживания путем сравнения между истинными объектами и дорожками, показаны ниже.

% Show Assignment metrics
truthIdFcn = @(x)[x.PlatformID];

tam = trackAssignmentMetrics('DistanceFunctionFormat','custom',...
    'AssignmentDistanceFcn',@distanceFcn,...
    'DivergenceDistanceFcn',@distanceFcn,...
    'TruthIdentifierFcn',truthIdFcn,...
    'AssignmentThreshold',1000,...
    'DivergenceThreshold',2000);

for i=1:numSteps
    % Extract the tracker and ground truth at the i-th tracker update
    tracks = trackLog{i};
    truths = plats(i,:);
    % For correct truth-track assignment evaluation, the truth is converted
    % to ECEF
    for j=1:numel(truths)
        R = dcmecef2ned(truths(j).Position(1), truths(j).Position(2));
        truths(j).Velocity = truths(j).Velocity * R;
        truths(j).Position = lla2ecef(truths(j).Position);
    end
    % Extract summary of assignment metrics against tracks and truths
    [trackAM,truthAM] = tam(tracks, truths);

end
% Show cumulative metrics for each individual recorded truth object
results = truthMetricsTable(tam);
results(:,{'TruthID','AssociatedTrackID','BreakLength','EstablishmentLength'})
ans=40×4 table
    TruthID    AssociatedTrackID    BreakLength    EstablishmentLength
    _______    _________________    ___________    ___________________

       1               57                5                 232        
       2               46                0                1283        
       3               32                0                 668        
       4               62               12                 492        
       5               22                0                 436        
       6               54                5                 807        
       7               26                0                 513        
       8               31                0                 665        
       9               43                0                1221        
      10               56                0                1500        
      11               49                0                1339        
      12               41                0                1056        
      13              NaN                0                1800        
      14              NaN                0                1800        
      15              NaN                0                1800        
      16              NaN                0                1800        
      ⋮

В таблице выше перечислены 40 спутников в созвездии запусков и показаны отслеживаемые спутники с соответствующими идентификаторами дорожек. Идентификатор дорожки со значением NaN указывает, что спутник не отслеживается к концу моделирования. Это либо означает, что орбита спутника не прошла через поле зрения одного из двух радаров, либо была сброшена трасса спутника. Трекер может сбросить дорожку из-за недостаточного количества начальных обнаружений, что приводит к большой неопределенности в оценке. Альтернативно, трекер может сбросить трассу, если спутник не будет повторно обнаружен достаточно скоро, так что отсутствие обновлений приводит к расхождению и в конечном итоге удалению.

Резюме

В этом примере вы научились использовать satelliteScenario объект из Aerospace Toolbox™ для импорта информации об орбите из файлов TLE. Спутниковые траектории распространяются с помощью SGP4 и визуализируются с помощью средства просмотра спутниковых сценариев. Вы научились использовать модели радаров и трекеров из Toolbox™ Sensor Fusion and Tracking для моделирования радиолокационной системы слежения космического наблюдения. Построенная система слежения может прогнозировать расчетную орбиту каждого спутника с использованием модели низкой точности.

Вспомогательные функции

initKeplerUKF инициализирует некачественный фильтр Калмана, используя модель движения Кеплериана.

function filter = initKeplerUKF(detection)

radarsphmeas = detection.Measurement;
[x, y, z] = sph2cart(deg2rad(radarsphmeas(1)),deg2rad(radarsphmeas(2)),radarsphmeas(3));
radarcartmeas = [x y z];
Recef2radar = detection.MeasurementParameters.Orientation;
ecefmeas = detection.MeasurementParameters.OriginPosition + radarcartmeas*Recef2radar;
% This is equivalent to:
% Ry90 = [0 0 -1 ; 0 1 0; 1 0 0]; % frame rotation of 90 deg around y axis
% nedmeas(:) = Ry90' * radarcartmeas(:);
% ecefmeas = lla2ecef(lla) +  nedmeas * dcmecef2ned(lla(1),lla(2));
initState = [ecefmeas(1); 0; ecefmeas(2); 0; ecefmeas(3); 0];

sigpos = 2;% m
sigvel = 0.5;% m/s^2

filter = trackingUKF(@keplerorbit,@cvmeas,initState,...
    'StateCovariance', diag(repmat([1000, 10000].^2,1,3)),...
    'ProcessNoise',diag(repmat([sigpos, sigvel].^2,1,3)));

end

function state = keplerorbit(state,dt)
% keplerorbit performs numerical integration to predict the state of
% Keplerian bodies. The state is [x;vx;y;vy;z;vz]

% Runge-Kutta 4th order integration method:
k1 = kepler(state);
k2 = kepler(state + dt*k1/2);
k3 = kepler(state + dt*k2/2);
k4 = kepler(state + dt*k3);

state = state + dt*(k1+2*k2+2*k3+k4)/6;

    function dstate=kepler(state)
        x =state(1,:);
        vx = state(2,:);
        y=state(3,:);
        vy = state(4,:);
        z=state(5,:);
        vz = state(6,:);

        mu = 398600.4405*1e9; % m^3 s^-2
        omega = 7.292115e-5; % rad/s
        
        r = norm([x y z]);
        g = mu/r^2;
        
        % Coordinates are in a non-intertial frame, account for Coriolis
        % and centripetal acceleration
        ax = -g*x/r + 2*omega*vy + omega^2*x;
        ay = -g*y/r - 2*omega*vx + omega^2*y;
        az = -g*z/r;
        dstate = [vx;ax;vy;ay;vz;az];
    end
end

isDetectable используется в примере для определения, какие дорожки можно обнаружить в данный момент времени.

function detectInput = isDetectable(tracker,time,covcon)

if ~isLocked(tracker)
    detectInput = zeros(0,1,'uint32');
    return
end
tracks = tracker.predictTracksToTime('all',time);
if isempty(tracks)
    detectInput = zeros(0,1,'uint32');
else
    alltrackid = [tracks.TrackID];
    isDetectable = zeros(numel(tracks),numel(covcon),'logical');
    for i = 1:numel(tracks)
        track = tracks(i);
        pos_scene = track.State([1 3 5]);
        for j=1:numel(covcon)
            config = covcon(j);
            % rotate position to sensor frame:
            d_scene = pos_scene(:) - config.Position(:);
            scene2sens = rotmat(config.Orientation,'frame');
            d_sens = scene2sens*d_scene(:);
            [az,el] = cart2sph(d_sens(1),d_sens(2),d_sens(3));
            if abs(rad2deg(az)) <= config.FieldOfView(1)/2 && abs(rad2deg(el)) < config.FieldOfView(2)/2
                isDetectable(i,j) = true;
            else
                isDetectable(i,j) = false;
            end
        end
    end
    
    detectInput = alltrackid(any(isDetectable,2))';
end
end

deleteBadTracks используется для удаления дорожек, которые явно расходились. В частности, расходящиеся дорожки в этом примере представляют собой дорожки, текущее положение которых упало на поверхность земли, и дорожки, ковариация которых стала слишком большой.

function tracks = deleteBadTracks(tracker,tracks)
% remove divergent tracks:
%   - tracks with covariance > 1e10 (100 km standard deviation)
%   - tracks with estimated position outside of LEO bounds
n = numel(tracks);
toDelete = zeros(1,n,'logical');
for i=1:numel(tracks)
    [pos, cov] = getTrackPositions(tracks(i),[ 1 0 0 0 0 0 ; 0 0 1 0 0 0; 0 0 0 0 1 0]);
    if norm(pos) < 6500*1e3 || norm(pos) > 8500*1e3 || max(cov,[],'all') > 1e10
        deleteTrack(tracker,tracks(i).TrackID);
        toDelete(i) =true;
    end
end
tracks(toDelete) = [];
end

assembleRadarInput используется для построения позиций созвездия в каждом кадре корпуса радара. Это первый шаг, описанный на диаграмме.

function targets = assembleRadarInputs(station, constellation)
% For each satellite in the constellation, derive its pose with respect to
% the radar frame.
% inputs:
%          - station        :  LLA vector of the radar ground station
%          - constellation  :  Array of structs containing the LLA position
%                              and NED velocity of each satellite
% outputs:
%          - targets        :  Array of structs containing the pose of each
%                              satellite with respect to the radar, expressed in the local
%                              ground radar frame (NED)

% Template structure for the outputs which contains all the field required
% by the radar step method
targetTemplate =  struct( ...
                'PlatformID', 0, ...
                'ClassID', 0, ...
                'Position', zeros(1,3), ...
                'Velocity', zeros(1,3), ...
                'Acceleration', zeros(1,3), ...
                'Orientation', quaternion(1,0,0,0), ...
                'AngularVelocity', zeros(1,3),...
                'Dimensions', struct( ...
                             'Length', 0, ...
                             'Width', 0, ...
                             'Height', 0, ...
                             'OriginOffset', [0 0 0]), ...
                'Signatures', {{rcsSignature}});


% First convert the current satellite pose to ECEF
targetPoses = repmat(targetTemplate, 1, numel(constellation));
for i=1:numel(constellation)
    lla = constellation(i).Position;
    targetPoses(i).Position = lla2ecef(lla);
    vned = constellation(i).Velocity;
    Rned2ecef = dcmecef2ned(lla(1),lla(2))';
    targetPoses(i).Velocity(:) = Rned2ecef*vned(:);
    targetPoses(i).PlatformID = constellation(i).PlatformID;
    % Orientation and angular velocity are left null, assuming satellite to
    % be point targets with a uniform rcs
end

% Then derive the radar pose in ECEF based on the ground station location
Recef2station = dcmecef2ned(station(1), station(2));
radarPose.Orientation = quaternion(Recef2station,'rotmat','frame');
radarPose.Position = lla2ecef(station);
radarPose.Velocity = zeros(1,3);
radarPose.AngularVelocity = zeros(1,3);

% Finally, take the difference and rotate each vector to the ground station
% NED axes
targets = targetPoses;
for i=1: numel(targetPoses)
    thisTgt = targetPoses(i);
    pos = Recef2station*(thisTgt.Position(:) - radarPose.Position(:));
    vel = Recef2station*(thisTgt.Velocity(:) - radarPose.Velocity(:)) - cross(radarPose.AngularVelocity(:),pos(:));
    angVel = thisTgt.AngularVelocity(:) - radarPose.AngularVelocity(:);
    orient = radarPose.Orientation' * thisTgt.Orientation;

    % Store into target structure array
    targets(i).Position(:) = pos;
    targets(i).Velocity(:) = vel;
    targets(i).AngularVelocity(:) = angVel;
    targets(i).Orientation = orient;
end
end

addMeasurementParam реализует шаг 2 в процессе радиолокационной цепи, как описано на диаграмме.

function dets = addMeasurementParams(dets, numdets, station)
% Add radar station information to the measurement parameters
Recef2station = dcmecef2ned(station(1), station(2));
for i=1:numdets
    dets{i}.MeasurementParameters.OriginPosition = lla2ecef(station);
    dets{i}.MeasurementParameters.IsParentToChild = true; % parent = ecef, child = radar
    dets{i}.MeasurementParameters.Orientation = dets{i}.MeasurementParameters.Orientation' * Recef2station;
end
end

distanceFcn используется с метриками назначения для оценки назначения отслеживания.

function d = distanceFcn(track, truth)

estimate = track.State([1 3 5 2 4 6]);
true = [truth.Position(:) ; truth.Velocity(:)];
cov = track.StateCovariance([1 3 5 2 4 6], [1 3 5 2 4 6]);
d = (estimate - true)' / cov * (estimate - true);
end

Ссылка

[1] Шридхаран, Рамасвами и Антонио Ф. Пенса, ред. Перспективы в области космического наблюдения. MIT Press, 2017.