mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
218 lines
No EOL
8.4 KiB
C++
218 lines
No EOL
8.4 KiB
C++
#include "atms_reader.h"
|
|
#include "common/ccsds/ccsds_time.h"
|
|
#include "common/repack.h"
|
|
|
|
namespace jpss
|
|
{
|
|
namespace atms
|
|
{
|
|
ATMSReader::ATMSReader()
|
|
{
|
|
for (int i = 0; i < 22; i++)
|
|
{
|
|
channels[i].resize(96);
|
|
channels_cc[i].resize(4);
|
|
channels_wc[i].resize(4);
|
|
}
|
|
lines = 0;
|
|
scan_pos = -1;
|
|
}
|
|
|
|
ATMSReader::~ATMSReader()
|
|
{
|
|
for (int i = 0; i < 22; i++)
|
|
channels[i].clear();
|
|
}
|
|
|
|
void ATMSReader::work(ccsds::CCSDSPacket &packet)
|
|
{
|
|
// Filter out bad packets
|
|
if (packet.payload.size() < 56)
|
|
return;
|
|
|
|
// Is there a sync signal?
|
|
int scan_synch = packet.payload[10] >> 7;
|
|
|
|
// If there is, trigger a new scanline
|
|
if (scan_synch == 1)
|
|
{
|
|
calib_data[lines]["calibration_pkt"] = last_calib_pkt;
|
|
calib_data[lines]["engineering_pkt"] = last_eng_pkt;
|
|
calib_data[lines]["hotcal_pkt"] = last_hot_pkt;
|
|
|
|
lines++;
|
|
timestamps.push_back(ccsds::parseCCSDSTimeFull(packet, -4383));
|
|
scan_pos = 0;
|
|
|
|
for (int i = 0; i < 22; i++)
|
|
{
|
|
channels[i].resize((lines + 1) * 96);
|
|
channels_cc[i].resize((lines + 1) * 4);
|
|
channels_wc[i].resize((lines + 1) * 4);
|
|
}
|
|
}
|
|
|
|
int16_t beam_angle = 0;
|
|
((uint8_t *)&beam_angle)[1] = packet.payload[8 + 0];
|
|
((uint8_t *)&beam_angle)[0] = packet.payload[8 + 1];
|
|
|
|
// Safeguard
|
|
if (scan_pos < 96 && scan_pos >= 0)
|
|
{
|
|
for (int i = 0; i < 22; i++) // Decode all channels
|
|
channels[i][(lines * 96) + 95 - scan_pos] = (packet.payload[12 + i * 2] << 8 | packet.payload[13 + i * 2]);
|
|
calib_data[lines]["beam_pos_sc"][95 - scan_pos] = beam_angle;
|
|
}
|
|
else if (scan_pos - 96 < 4 && scan_pos - 96 >= 0)
|
|
{
|
|
for (int i = 0; i < 22; i++) // Decode all channels
|
|
channels_cc[i][(lines * 4) + (scan_pos - 96)] = (packet.payload[12 + i * 2] << 8 | packet.payload[13 + i * 2]);
|
|
calib_data[lines]["beam_pos_cc"][scan_pos - 96] = beam_angle;
|
|
}
|
|
else if (scan_pos - 96 - 4 < 4 && scan_pos - 96 - 4 >= 0)
|
|
{
|
|
for (int i = 0; i < 22; i++) // Decode all channels
|
|
channels_wc[i][(lines * 4) + (scan_pos - 96 - 4)] = (packet.payload[12 + i * 2] << 8 | packet.payload[13 + i * 2]);
|
|
calib_data[lines]["beam_pos_wc"][scan_pos - 96 - 4] = beam_angle;
|
|
}
|
|
|
|
scan_pos++;
|
|
}
|
|
|
|
inline double parse_pam_gamma0(uint16_t word) { return 2300.0 + 0.006 * word; }
|
|
inline double parse_4w_2w_r0(uint16_t word) { return 1900.0 + 0.003 * word; }
|
|
inline double parse_4w_2w_alpha(uint16_t word) { return 0.002 + 5e-8 * word; }
|
|
inline double parse_4w_2w_delta(uint16_t word) { return 5e-5 * word; }
|
|
inline double parse_4w_prt_beta(uint16_t word) { return 6e-5 * word - 2.0; }
|
|
inline double parse_calibration_target_offset(uint16_t word) { return -7.5e-6 * word; }
|
|
inline double parse_cold_calibration_offset(uint16_t word) { return 1.5e-5 * word; }
|
|
inline double parse_quadratic_coefficient(uint16_t word) { return 2.6e-5 * word - 0.850; }
|
|
inline double parse_alignement(uint16_t word) { return 2.0e-5 * word - 0.655; }
|
|
inline double parse_2w_prt_a(uint16_t word) { return 3.0e-6 * word; }
|
|
inline double parse_rc(uint16_t word) { return 0.0003 * word; }
|
|
inline double parse_muxresti(uint16_t word) { return 1900.0 + 0.003 * word; }
|
|
|
|
void ATMSReader::work_calib(ccsds::CCSDSPacket &packet)
|
|
{
|
|
// Filter out bad packets
|
|
if (packet.payload.size() < 438)
|
|
return;
|
|
|
|
// Parse calibration packet
|
|
ATMSCalibPkt calib_pkt;
|
|
uint16_t words[215];
|
|
repackBytesTo16bits(&packet.payload[8], 430, words);
|
|
|
|
calib_pkt.pamKav = parse_pam_gamma0(words[0]);
|
|
calib_pkt.pamWg = parse_pam_gamma0(words[1]);
|
|
|
|
for (int i = 0; i < NUM_PRT_KAV; i++)
|
|
{
|
|
calib_pkt.prtCoeffKav[i][0] = parse_4w_2w_r0(words[2 + 4 * i + 0]);
|
|
calib_pkt.prtCoeffKav[i][1] = parse_4w_2w_alpha(words[2 + 4 * i + 1]);
|
|
calib_pkt.prtCoeffKav[i][2] = parse_4w_2w_delta(words[2 + 4 * i + 2]);
|
|
calib_pkt.prtCoeffKav[i][3] = parse_4w_prt_beta(words[2 + 4 * i + 3]);
|
|
}
|
|
|
|
for (int i = 0; i < NUM_PRT_WG; i++)
|
|
{
|
|
calib_pkt.prtCoeffWg[i][0] = parse_4w_2w_r0(words[34 + 4 * i + 0]);
|
|
calib_pkt.prtCoeffWg[i][1] = parse_4w_2w_alpha(words[34 + 4 * i + 1]);
|
|
calib_pkt.prtCoeffWg[i][2] = parse_4w_2w_delta(words[34 + 4 * i + 2]);
|
|
calib_pkt.prtCoeffWg[i][3] = parse_4w_prt_beta(words[34 + 4 * i + 3]);
|
|
}
|
|
|
|
for (int i = 0; i < NUM_ATMS_BANDS; i++)
|
|
calib_pkt.warmBias[i] = parse_calibration_target_offset(words[62 + i]);
|
|
|
|
for (int i = 0; i < NUM_ATMS_BANDS; i++)
|
|
calib_pkt.coldBias[i] = parse_cold_calibration_offset(words[67 + i]);
|
|
|
|
for (int i = 0; i < 22; i++)
|
|
calib_pkt.quadraticCoeffs[i] = parse_quadratic_coefficient(words[72 + i]);
|
|
|
|
// Beam alignement - Skipped
|
|
|
|
for (int i = 0; i < NUM_PRT_COEFFS; i++)
|
|
{
|
|
calib_pkt.prtCoeffShelf[i][0] = parse_4w_2w_r0(words[139 + 4 * i + 0]);
|
|
calib_pkt.prtCoeffShelf[i][1] = parse_4w_2w_alpha(words[139 + 4 * i + 1]);
|
|
calib_pkt.prtCoeffShelf[i][2] = parse_4w_2w_delta(words[139 + 4 * i + 2]);
|
|
calib_pkt.prtCoeffShelf[i][3] = parse_rc(words[139 + 4 * i + 3]);
|
|
}
|
|
|
|
for (int i = 0; i < NUM_PRT_COEFF_2WIRE / 2; i++)
|
|
{
|
|
calib_pkt.prtCoeff2Wire[i * 2 + 0] = parse_4w_2w_r0(words[155 + 2 * i + 0]);
|
|
calib_pkt.prtCoeff2Wire[i * 2 + 1] = parse_2w_prt_a(words[155 + 2 * i + 1]);
|
|
}
|
|
|
|
for (int i = 0; i < NUM_HOUSE_KEEPING; i++)
|
|
{
|
|
calib_pkt.houseKeeping[i] = parse_muxresti(words[211 + i]);
|
|
}
|
|
|
|
calib_pkt.valid = true;
|
|
last_calib_pkt = calib_pkt;
|
|
}
|
|
|
|
void ATMSReader::work_eng(ccsds::CCSDSPacket &packet)
|
|
{
|
|
// Filter out bad packets
|
|
if (packet.payload.size() < 156)
|
|
return;
|
|
|
|
ATMSHealtStatusPkt eng_pkt;
|
|
uint16_t words[74];
|
|
repackBytesTo16bits(&packet.payload[8], 148, words);
|
|
|
|
for (int i = 0; i < NUM_HS_VARS; i++)
|
|
eng_pkt.data[i] = words[i];
|
|
|
|
eng_pkt.valid = true;
|
|
last_eng_pkt = eng_pkt;
|
|
}
|
|
|
|
void ATMSReader::work_hotcal(ccsds::CCSDSPacket &packet)
|
|
{
|
|
// Filter out bad packets
|
|
if (packet.payload.size() < 42)
|
|
return;
|
|
|
|
ATMSHotCalTempPkt hot_pkt;
|
|
uint16_t words[17];
|
|
repackBytesTo16bits(&packet.payload[8], 34, words);
|
|
|
|
for (int i = 0; i < NUM_PRT_KAV; i++)
|
|
hot_pkt.kavPrt[i] = words[i];
|
|
|
|
hot_pkt.kavPamCounts = words[8];
|
|
|
|
for (int i = 0; i < NUM_PRT_WG; i++)
|
|
hot_pkt.wqPrt[i] = words[9 + i];
|
|
|
|
hot_pkt.wgPamCounts = words[16];
|
|
|
|
hot_pkt.valid = true;
|
|
last_hot_pkt = hot_pkt;
|
|
}
|
|
|
|
image::Image ATMSReader::getChannel(int channel)
|
|
{
|
|
return image::Image(channels[channel].data(), 16, 96, lines, 1);
|
|
}
|
|
|
|
nlohmann::json ATMSReader::getCalib()
|
|
{
|
|
for (int i = 0; i < lines; i++)
|
|
for (int c = 0; c < 22; c++)
|
|
for (int z = 0; z < 4; z++)
|
|
calib_data[i]["cold_counts"][c][z] = channels_cc[c][i * 4 + z];
|
|
for (int i = 0; i < lines; i++)
|
|
for (int c = 0; c < 22; c++)
|
|
for (int z = 0; z < 4; z++)
|
|
calib_data[i]["warm_counts"][c][z] = channels_wc[c][i * 4 + z];
|
|
return calib_data;
|
|
}
|
|
} // namespace atms
|
|
} // namespace jpss
|