Skip to content

Commit

Permalink
Rework how scanlines are 'aged'.
Browse files Browse the repository at this point in the history
Realised that it takes 2.5s for a full revolution of the radar scanner, so normal
minimal age is 3 (s). Add control so users can change this between 1 (for testing)
and 12 (seems plenty...)

Fixes bug #36.

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Committer: Kees Verruijt <kees@kees-mbp.verruijt.lan>
#
# On branch master
# Your branch is up-to-date with 'origin/master'.
#
# Changes to be committed:
#	modified:   src/br24radar_pi.cpp
#	modified:   src/br24radar_pi.h
#	modified:   src/br24radarcontrol.cpp
#
  • Loading branch information
keesverruijt committed Oct 12, 2014
1 parent c85106f commit 4aaa486
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 25 deletions.
51 changes: 32 additions & 19 deletions src/br24radar_pi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,12 +391,6 @@ int br24radar_pi::Init(void)
m_hdt_source = 0;
m_hdt_prev_source = 0;

for (int i = 0; i < LINES_PER_ROTATION; i++) {
m_scan_range[i][0] = 0;
m_scan_range[i][1] = 0;
m_scan_range[i][2] = 0;
}

memset(&guardZones, 0, sizeof(guardZones));

settings.guard_zone = 0; // this used to be active guard zone, now it means which guard zone window is active
Expand All @@ -421,6 +415,11 @@ int br24radar_pi::Init(void)
// And load the configuration items
LoadConfig();

for (int i = 0; i < LINES_PER_ROTATION; i++) {
m_scan_line[i].age = settings.max_age + 1;
m_scan_line[i].range = 0;
}

// Get a pointer to the opencpn display canvas, to use as a parent for the UI dialog
m_parent_window = GetOCPNCanvasWindow();

Expand Down Expand Up @@ -1186,17 +1185,25 @@ void br24radar_pi::DrawRadarImage(int max_range, wxPoint radar_center)
memset(&bogey_count, 0, sizeof(bogey_count));

// DRAWING PICTURE
GLubyte alpha = 255 * (MAX_OVERLAY_TRANSPARENCY - settings.overlay_transparency) / MAX_OVERLAY_TRANSPARENCY;
const double spoke_width = deg2rad(360) / LINES_PER_ROTATION; // How wide is one spoke?

for (int angle = 0 ; angle < LINES_PER_ROTATION; ++angle) {
scan_line * scan = &m_scan_line[angle];

if (!m_scan_range[angle][0] && !m_scan_range[angle][1] && !m_scan_range[angle][2]) {
continue; // test for entries in each prior scan, if all three empty - stop the process
if (scan->age >= settings.max_age) {
continue; // Old data, don't show
}
scan->age++;
GLubyte alpha = 255 * (MAX_OVERLAY_TRANSPARENCY - settings.overlay_transparency) / MAX_OVERLAY_TRANSPARENCY;
/*
if (scan->age > 1 && settings.max_age > 0) {
alpha *= (settings.max_age - scan->age) / settings.max_age;
}
*/

for (int radius = 0; radius < 512; ++radius) {

GLubyte red = 0, green = 0, blue = 0, strength = m_scan_buf[angle][radius];
GLubyte red = 0, green = 0, blue = 0, strength = scan->data[radius];

if (strength > 50) { // Only draw when there is color, saves lots of CPU
switch (settings.display_option) {
Expand Down Expand Up @@ -1228,7 +1235,8 @@ void br24radar_pi::DrawRadarImage(int max_range, wxPoint radar_center)
double arc_heigth = 1;
double angleRad = angle * spoke_width;

draw_blob_gl(angleRad, radius, arc_width, arc_heigth);
double r = radius * (double) scan->range / (double) max_range;
draw_blob_gl(angleRad, r, arc_width, arc_heigth);

/**********************************************************************************************************/
// Guard Section
Expand Down Expand Up @@ -1271,9 +1279,9 @@ void br24radar_pi::RenderSpectrum(wxPoint radar_center, double v_scale_ppm, Plug
memset(&scan_distribution[0], 0, 255);

for (int angle = 0 ; angle < LINES_PER_ROTATION ; angle++) {
if (m_scan_range[angle][0] != 0) {
if (m_scan_line[angle].range != 0 && m_scan_line[angle].age <= 1) {
for (int radius = 1; radius < 510; ++radius) {
alpha = m_scan_buf[angle][radius];
alpha = m_scan_line[angle].data[radius];
if (alpha > 0 && alpha < 255) {
scan_distribution[0] += 1;
scan_distribution[alpha] += 1;
Expand Down Expand Up @@ -1448,6 +1456,7 @@ bool br24radar_pi::LoadConfig(void)
pConf->Read(wxT("BeamWidth"), &settings.beam_width, 2);
pConf->Read(wxT("InterferenceRejection"), &settings.rejection, 0);
pConf->Read(wxT("TargetBoost"), &settings.target_boost, 0);
pConf->Read(wxT("ScanMaxAge"), &settings.max_age, 6);
pConf->Read(wxT("GuardZonesThreshold"), &settings.guard_zone_threshold, 5L);
pConf->Read(wxT("GuardZonesRenderStyle"), &settings.guard_zone_render_style, 0);

Expand Down Expand Up @@ -1537,6 +1546,7 @@ bool br24radar_pi::SaveConfig(void)
pConf->Write(wxT("TargetBoost"), settings.target_boost);
pConf->Write(wxT("GuardZonesThreshold"), settings.guard_zone_threshold);
pConf->Write(wxT("GuardZonesRenderStyle"), settings.guard_zone_render_style);
pConf->Write(wxT("ScanMaxAge"), settings.max_age);

pConf->Write(wxT("ControlsDialogSizeX"), m_BR24Controls_dialog_sx);
pConf->Write(wxT("ControlsDialogSizeY"), m_BR24Controls_dialog_sy);
Expand Down Expand Up @@ -1690,7 +1700,7 @@ void br24radar_pi::SetControlValue(ControlType controlType, int value)
{
wxString msg;

if (settings.master_mode || controlType == CT_TRANSPARENCY) {
if (settings.master_mode || controlType == CT_TRANSPARENCY || controlType == CT_SCAN_AGE) {
switch (controlType) {
case CT_GAIN: {
if (value < 0) { // AUTO gain
Expand Down Expand Up @@ -1804,6 +1814,10 @@ void br24radar_pi::SetControlValue(ControlType controlType, int value)
settings.overlay_transparency = value;
break;
}
case CT_SCAN_AGE: {
settings.max_age = value;
break;
}
default: {
wxLogMessage(wxT("Unhandled control setting for control %d"), controlType);
}
Expand Down Expand Up @@ -2184,16 +2198,15 @@ void MulticastRXThread::process_buffer(radar_frame_pkt * packet, int len)
}
}

unsigned char *dest_data1 = pPlugIn->m_scan_buf[angle_raw];
unsigned char *dest_data1 = pPlugIn->m_scan_line[angle_raw].data;
memcpy(dest_data1, line->data, 512);

// The following line is a quick hack to confirm on-screen where the range ends, by putting a 'ring' of
// returned radar energy at the max range line.
// TODO: create nice actual range circles.
pPlugIn->m_scan_buf[angle_raw][511] = (byte)0xff;
dest_data1[511] = (byte)0xff;

pPlugIn->m_scan_range[angle_raw][2] = pPlugIn->m_scan_range[angle_raw][1];
pPlugIn->m_scan_range[angle_raw][1] = pPlugIn->m_scan_range[angle_raw][0];
pPlugIn->m_scan_range[angle_raw][0] = range_meters;
pPlugIn->m_scan_line[angle_raw].range = range_meters;
pPlugIn->m_scan_line[angle_raw].age = 0;
}
}
19 changes: 13 additions & 6 deletions src/br24radar_pi.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#endif //precompiled headers

#define PLUGIN_VERSION_MAJOR 0
#define PLUGIN_VERSION_MINOR 40722
#define PLUGIN_VERSION_MINOR 41012

#define MY_API_VERSION_MAJOR 1
#define MY_API_VERSION_MINOR 8
Expand Down Expand Up @@ -146,7 +146,8 @@ typedef enum ControlType {
CT_RAIN,
CT_TRANSPARENCY,
CT_REJECTION,
CT_TARGET_BOOST
CT_TARGET_BOOST,
CT_SCAN_AGE
} ControlType;

typedef enum GuardZoneType {
Expand Down Expand Up @@ -190,6 +191,7 @@ struct radar_control_settings {
int range_units; // 0 = "Nautical miles"), 1 = "Statute miles", 2 = "Kilometers", 3 = "Meters"
wxString radar_interface; // IP address of interface to bind to (on UNIX)
int beam_width;
int max_age;
};

struct guard_zone_settings {
Expand All @@ -200,6 +202,12 @@ struct guard_zone_settings {
double end_bearing;
};

struct scan_line {
int range; // range of this scan line in decimeters
int age; // how old this scan line is. We keep old scans on-screen for a while
GLubyte data[512]; // radar return strength
};

// Forward definitions
class MulticastRXThread;
class BR24ControlsDialog;
Expand Down Expand Up @@ -284,10 +292,8 @@ class br24radar_pi : public opencpn_plugin_18
#define GUARD_ZONES (2)
guard_zone_settings guardZones[GUARD_ZONES];

#define LINES_PER_ROTATION (4096)
unsigned char m_scan_buf[LINES_PER_ROTATION][512]; // scan buffer that contains raw radar scan image
int m_scan_range[LINES_PER_ROTATION][3]; // range in decimeters for the corresponding line in m_scan_buf
// kept for 3 rotations, so a scanline is discarded after 3.
#define LINES_PER_ROTATION (4096) // 4G radars can generate up to 4096 lines per rotation
scan_line m_scan_line[LINES_PER_ROTATION];

BR24DisplayOptionsDialog *m_pOptionsDialog;
BR24ControlsDialog *m_pControlDialog;
Expand Down Expand Up @@ -595,6 +601,7 @@ class BR24ControlsDialog: public wxDialog
RadarControlButton *bTransparency;
RadarControlButton *bRejection;
RadarControlButton *bTargetBoost;
RadarControlButton *bScanAge;

// Show Controls

Expand Down
8 changes: 8 additions & 0 deletions src/br24radarcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ enum { // process ID's
ID_TRANSPARENCY,
ID_REJECTION,
ID_TARGET_BOOST,
ID_SCAN_AGE,

ID_RANGE,
ID_GAIN,
Expand Down Expand Up @@ -99,6 +100,7 @@ BEGIN_EVENT_TABLE(BR24ControlsDialog, wxDialog)
EVT_BUTTON(ID_TRANSPARENCY, BR24ControlsDialog::OnRadarControlButtonClick)
EVT_BUTTON(ID_REJECTION, BR24ControlsDialog::OnRadarControlButtonClick)
EVT_BUTTON(ID_TARGET_BOOST, BR24ControlsDialog::OnRadarControlButtonClick)
EVT_BUTTON(ID_SCAN_AGE, BR24ControlsDialog::OnRadarControlButtonClick)

EVT_BUTTON(ID_RANGE, BR24ControlsDialog::OnRadarControlButtonClick)
EVT_BUTTON(ID_GAIN, BR24ControlsDialog::OnRadarControlButtonClick)
Expand Down Expand Up @@ -444,6 +446,12 @@ void BR24ControlsDialog::CreateControls()
bTargetBoost->names = g_target_boost_names;
bTargetBoost->SetValue(pPlugIn->settings.target_boost); // redraw after adding names

// The SCAN AGE button
bScanAge = new RadarControlButton(this, ID_SCAN_AGE, _("Scan Age"), pPlugIn, CT_SCAN_AGE, false, pPlugIn->settings.max_age);
advancedBox->Add(bScanAge, 0, wxALIGN_CENTER_VERTICAL | wxALL, BORDER);
bScanAge->minValue = 1;
bScanAge->maxValue = 12;

topSizer->Hide(advancedBox);

//**************** CONTROL BOX ******************//
Expand Down

0 comments on commit 4aaa486

Please sign in to comment.