Skip to content

Commit

Permalink
Dsp (#1075)
Browse files Browse the repository at this point in the history
* [INDI common]
Added functions in common routine source.
* Added photon flux calculation
* Added Planck constant and Lumen value #defines
* Updated absolute magnitude and parallax estimations

* [INDIcom] Added relative magnitude calculation

* [INDIcom] Changed log into log10

* [DSP] Added new plugin for Signal processing

This is applicable on BLOBs of INDI::SensorInterface children or
INDI::CCD classes.
Must implement DSP directly into SensorInterface (and CCD if agreed) or
drivers should have this implemented when developers decide?

Features:
- Buffer transformations like DFT or Laplace, Wavelets.
- Convolutions (Lowpass, Highpass filters), downloaded BLOBs from clients
can be used as convolution matrices.
- Primarily written for SensorInterface, can be applied into CCD, for
star or object recognition for example.
- Creates new BLOBs and uploads them to the client separately from the
main BLOB.

TODO:
- Download is possible from KStars (BLOB write-only and FITS/Picture
parsers)
- Cross and auto correlation.

* [DSP] Added BLOB Download in convolution

* [DSP] fixes for spectrograph_simulator.cpp

* [DSP/Sensors] Fixes for Spectrograph

* [Sensors] Fixed StreamManager issue

* [DSP] Added DSP Manager class
Added DSP initial support (not working at the moment) into Sensor
interface and CCD classes

* [DSP] some little corrections

* [DSP] Fixes for streaming into spectrograph simulator

* [DSP][TEST] Fixed DSP for building, needs testing

* [DSP] various fixes

* [DSP] removed unuseful messages

* [DSP] Further fixes for BLOB upload

* [DSP] End of fixes, can merge.

* [DSP] Added Spectrum into Transforms

* [DSP] Fixed runtime issues

* [DSP] added dsp_stats_range_count in libDSP

* [DSP] Added wavelets draft

* [DSP] Changed CCD simulator - added ISNewBLOB forwarding

* [DSP] Errors in circleci

* [DSP] Further circleci errors

* [DSP] Further circleci errors

* [DSP] Updated activation method

* [DSP] updated DFT shift

* [DSP] Removed unused label
  • Loading branch information
Ilia Platone authored and knro committed Jan 27, 2020
1 parent 8deb4a1 commit 4baf11b
Show file tree
Hide file tree
Showing 34 changed files with 994 additions and 848 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -425,6 +425,7 @@ SET(indidriver_CXX_SRC
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/connectionplugins/connectionserial.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/connectionplugins/connectiontcp.cpp
#${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/connectionplugins/ttybase.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/dsp/manager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/dsp/dspinterface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/dsp/transforms.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/dsp/convolution.cpp
Expand Down Expand Up @@ -1825,6 +1826,7 @@ if (INDI_BUILD_DRIVERS OR INDI_BUILD_CLIENT OR INDI_BUILD_QT5_CLIENT)
DESTINATION ${INCLUDE_INSTALL_DIR}/libindi/connectionplugins COMPONENT Devel)

install( FILES
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/dsp/manager.h
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/dsp/dspinterface.h
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/dsp/transforms.h
${CMAKE_CURRENT_SOURCE_DIR}/libs/indibase/dsp/convolution.h
Expand Down
6 changes: 3 additions & 3 deletions drivers.xml
Expand Up @@ -382,9 +382,9 @@
<version>1.0</version>
</device>
</devGroup>
<devGroup group="Detectors">
<device label="Detector Simulator" mdpd="true">
<driver name="Detector Simulator">indi_simulator_detector</driver>
<devGroup group="Spectrographs">
<device label="Spectrograph Simulator" mdpd="true">
<driver name="Spectrograph Simulator">indi_simulator_spectrograph</driver>
<version>1.0</version>
</device>
</devGroup>
Expand Down
12 changes: 3 additions & 9 deletions drivers/ccd/ccd_simulator.cpp
@@ -1,7 +1,6 @@
/*******************************************************************************
Copyright(c) 2017 Jasem Mutlaq. All rights reserved.
Copyright(c) 2010 Gerry Rozema. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
Expand Down Expand Up @@ -60,15 +59,9 @@ void ISNewNumber(const char * dev, const char * name, double values[], char * na
void ISNewBLOB(const char * dev, const char * name, int sizes[], int blobsizes[], char * blobs[], char * formats[],
char * names[], int n)
{
INDI_UNUSED(dev);
INDI_UNUSED(name);
INDI_UNUSED(sizes);
INDI_UNUSED(blobsizes);
INDI_UNUSED(blobs);
INDI_UNUSED(formats);
INDI_UNUSED(names);
INDI_UNUSED(n);
ccdsim->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
}

void ISSnoopDevice(XMLEle * root)
{
ccdsim->ISSnoopDevice(root);
Expand Down Expand Up @@ -226,6 +219,7 @@ bool CCDSim::initProperties()
cap |= CCD_HAS_SHUTTER;
cap |= CCD_HAS_ST4_PORT;
cap |= CCD_HAS_STREAMING;
cap |= CCD_HAS_DSP;

#ifdef HAVE_WEBSOCKET
cap |= CCD_HAS_WEB_SOCKET;
Expand Down
1 change: 0 additions & 1 deletion drivers/ccd/ccd_simulator.h
@@ -1,7 +1,6 @@
/*******************************************************************************
Copyright(c) 2017 Jasem Mutlaq. All rights reserved.
Copyright(c) 2010 Gerry Rozema. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
Expand Down
106 changes: 54 additions & 52 deletions drivers/spectrograph/spectrograph_simulator.cpp
Expand Up @@ -55,16 +55,9 @@ void ISNewNumber(const char *dev, const char *name, double values[], char *names
}

void ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[],
char *names[], int n)
char *names[], int num)
{
INDI_UNUSED(dev);
INDI_UNUSED(name);
INDI_UNUSED(sizes);
INDI_UNUSED(blobsizes);
INDI_UNUSED(blobs);
INDI_UNUSED(formats);
INDI_UNUSED(names);
INDI_UNUSED(n);
receiver->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, num);
}

void ISSnoopDevice(XMLEle *root)
Expand Down Expand Up @@ -92,9 +85,11 @@ bool RadioSim::Connect()
// Let's set a timer that checks teleSpectrographs status every POLLMS milliseconds.
// JM 2017-07-31 SetTimer already called in updateProperties(). Just call it once
//SetTimer(POLLMS);

streamPredicate = 0;
terminateThread = false;
pthread_create(&primary_thread, nullptr, &streamCaptureHelper, this);
// Run threads
std::thread(&RadioSim::streamCaptureHelper, this).detach();
SetTimer(POLLMS);

return true;
Expand Down Expand Up @@ -130,18 +125,18 @@ const char *RadioSim::getDefaultName()
bool RadioSim::initProperties()
{
// We set the Spectrograph capabilities
uint32_t cap = SENSOR_CAN_ABORT | SENSOR_HAS_STREAMING;
SetSpectrographCapability(cap);
uint32_t cap = SENSOR_CAN_ABORT | SENSOR_HAS_STREAMING | SENSOR_HAS_DSP;
SetCapability(cap);

// Must init parent properties first!
INDI::Spectrograph::initProperties();

setMinMaxStep("DETECTOR_CAPTURE", "DETECTOR_CAPTURE_VALUE", 0.001, 86164.092, 0.001, false);
setMinMaxStep("DETECTOR_SETTINGS", "DETECTOR_FREQUENCY", 2.4e+7, 2.0e+9, 1, false);
setMinMaxStep("DETECTOR_SETTINGS", "DETECTOR_SAMPLERATE", 1.0e+6, 2.0e+6, 1, false);
setMinMaxStep("DETECTOR_SETTINGS", "DETECTOR_GAIN", 0.0, 25.0, 0.1, false);
setMinMaxStep("DETECTOR_SETTINGS", "DETECTOR_BANDWIDTH", 0, 0, 0, false);
setMinMaxStep("DETECTOR_SETTINGS", "DETECTOR_BITSPERSAMPLE", 16, 16, 0, false);
setMinMaxStep("SENSOR_INTEGRATION", "SENSOR_INTEGRATION_VALUE", 0.001, 86164.092, 0.001, false);
setMinMaxStep("SPECTROGRAPH_SETTINGS", "SPECTROGRAPH_FREQUENCY", 2.4e+7, 2.0e+9, 1, false);
setMinMaxStep("SPECTROGRAPH_SETTINGS", "SPECTROGRAPH_SAMPLERATE", 1.0e+6, 2.0e+6, 1, false);
setMinMaxStep("SPECTROGRAPH_SETTINGS", "SPECTROGRAPH_GAIN", 0.0, 25.0, 0.1, false);
setMinMaxStep("SPECTROGRAPH_SETTINGS", "SPECTROGRAPH_BANDWIDTH", 0, 0, 0, false);
setMinMaxStep("SPECTROGRAPH_SETTINGS", "SPECTROGRAPH_BITSPERSAMPLE", 16, 16, 0, false);
setIntegrationFileExtension("fits");

// Add Debug, Simulator, and Configuration controls
Expand All @@ -159,8 +154,8 @@ bool RadioSim::updateProperties()
{
if (isConnected())
{
// Let's get parameters now from Spectrograph
setupParams();
// Inital values
setupParams(1000000, 1420000000, 10000, 10);

// Start the timer
SetTimer(POLLMS);
Expand All @@ -172,16 +167,40 @@ bool RadioSim::updateProperties()
/**************************************************************************************
** Setting up Spectrograph parameters
***************************************************************************************/
void RadioSim::setupParams()
void RadioSim::setupParams(float sr, float freq, float bw, float gain)
{
// Our Spectrograph is an 8 bit Spectrograph, 100MHz frequency 1MHz bandwidth.
setParams(1000000.0, 100000000.0, 16, 0.0, 25.0);
setFrequency(freq);
setSampleRate(sr);
setBPS(16);
setBandwidth(bw);
setGain(gain);
}

bool RadioSim::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
{
bool r = false;
if (dev && !strcmp(dev, getDeviceName()) && !strcmp(name, SpectrographSettingsNP.name)) {
for(int i = 0; i < n; i++) {
if (!strcmp(names[i], "SPECTROGRAPH_GAIN")) {
setupParams(getSampleRate(), getFrequency(), getBandwidth(), values[i]);
} else if (!strcmp(names[i], "SPECTROGRAPH_BANDWIDTH")) {
setupParams(getSampleRate(), getFrequency(), values[i], getGain());
} else if (!strcmp(names[i], "SPECTROGRAPH_FREQUENCY")) {
setupParams(getSampleRate(), values[i], getBandwidth(), getGain());
} else if (!strcmp(names[i], "SPECTROGRAPH_SAMPLERATE")) {
setupParams(values[i], getFrequency(), getBandwidth(), getGain());
}
}
IDSetNumber(&SpectrographSettingsNP, nullptr);
}
return processNumber(dev, name, values, names, n) & !r;
}

/**************************************************************************************
** Client is asking us to start an exposure
***************************************************************************************/
bool RadioSim::StartIntegration(float duration)
bool RadioSim::StartIntegration(double duration)
{
IntegrationRequest = duration;
AbortIntegration();
Expand All @@ -203,22 +222,6 @@ bool RadioSim::StartIntegration(float duration)
return true;
}

/**************************************************************************************
** Client is updating capture settings
***************************************************************************************/
bool RadioSim::paramsUpdated(float sr, float freq, float bps, float bw, float gain)
{
INDI_UNUSED(gain);
INDI_UNUSED(freq);
INDI_UNUSED(bps);
INDI_UNUSED(bw);
setBPS(16);
setBandwidth(100000);
setSampleRate(sr);

return true;
}

/**************************************************************************************
** Client is asking us to abort a capture
***************************************************************************************/
Expand Down Expand Up @@ -288,11 +291,12 @@ void RadioSim::grabData()
InIntegration = false;

uint8_t* continuum;
int size = getBufferSize() * 8 / abs(getBPS());
int size = getBufferSize();

//Fill the continuum
continuum = getBuffer();
WhiteNoise(continuum, size, getBPS());
for(int i = 0; i < size; i++)
continuum[i] = rand() % 255;

LOG_INFO("Download complete.");
IntegrationComplete();
Expand Down Expand Up @@ -321,15 +325,13 @@ bool RadioSim::StopStreaming()
return true;
}

void * RadioSim::streamCaptureHelper(void * context)
{
return ((RadioSim *)context)->streamCapture();
}

void * RadioSim::streamCapture()
void RadioSim::streamCaptureHelper()
{
struct itimerval tframe1, tframe2;
double s1, s2, deltas;
double deltas;
getitimer(ITIMER_REAL, &tframe1);
auto s1 = ((double)tframe2.it_value.tv_sec) + ((double)tframe2.it_value.tv_usec / 1e6);
auto s2 = ((double)tframe2.it_value.tv_sec) + ((double)tframe2.it_value.tv_usec / 1e6);

while (true)
{
Expand All @@ -338,8 +340,8 @@ void * RadioSim::streamCapture()
while (streamPredicate == 0)
{
pthread_cond_wait(&cv, &condMutex);
StartIntegration(1.0 / Streamer->getTargetFPS());
}
StartIntegration(1.0 / Streamer->getTargetFPS());

if (terminateThread)
break;
Expand All @@ -352,19 +354,19 @@ void * RadioSim::streamCapture()
grabData();
getitimer(ITIMER_REAL, &tframe1);

s1 = ((double)tframe1.it_value.tv_sec) + ((double)tframe1.it_value.tv_usec / 1e6);
s2 = ((double)tframe2.it_value.tv_sec) + ((double)tframe2.it_value.tv_usec / 1e6);
deltas = fabs(s2 - s1);

if (deltas < IntegrationTime)
usleep(fabs(IntegrationTime - deltas) * 1e6);

uint32_t size = getBufferSize();
int32_t size = getBufferSize();
Streamer->newFrame(getBuffer(), size);

s1 = ((double)tframe1.it_value.tv_sec) + ((double)tframe1.it_value.tv_usec / 1e6);

getitimer(ITIMER_REAL, &tframe2);
}

pthread_mutex_unlock(&condMutex);
return nullptr;
}
14 changes: 9 additions & 5 deletions drivers/spectrograph/spectrograph_simulator.h
Expand Up @@ -21,6 +21,8 @@

#include "indispectrograph.h"
#include "stream/streammanager.h"
#include "dsp/convolution.h"
#include "dsp/transforms.h"

enum Settings
{
Expand All @@ -35,6 +37,8 @@ class RadioSim : public INDI::Spectrograph
RadioSim();
~RadioSim();

bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override;

protected:
// General device functions
bool Connect() override;
Expand All @@ -44,23 +48,23 @@ class RadioSim : public INDI::Spectrograph
bool updateProperties() override;

// Detector specific functions
bool StartIntegration(float duration);
bool paramsUpdated(float sr, float freq, float bps, float bw, float gain);
bool StartIntegration(double duration) override;
bool AbortIntegration() override;
void TimerHit() override;

bool StartStreaming() override;
bool StopStreaming() override;
static void * streamCaptureHelper(void * context);
void streamCaptureHelper();
void * streamCapture();
void grabData();

private:

// Utility functions
float CalcTimeLeft();
void setupParams();
void setupParams(float sr, float freq, float bw, float gain);
struct timeval CapStart;
float IntegrationRequest;
double IntegrationRequest;

int streamPredicate;
pthread_t primary_thread;
Expand Down
10 changes: 7 additions & 3 deletions examples/tutorial_eight/simple_spectrograph.cpp
Expand Up @@ -107,7 +107,7 @@ bool SimpleSpectrograph::initProperties()

// We set the Spectrograph capabilities
uint32_t cap = SENSOR_CAN_ABORT | SENSOR_HAS_COOLER | SENSOR_HAS_SHUTTER;
SetSpectrographCapability(cap);
SetCapability(cap);

// Add Debug, Simulator, and Configuration controls
addAuxControls();
Expand Down Expand Up @@ -157,13 +157,17 @@ bool SimpleSpectrograph::paramsUpdated(float sr, float freq, float bps, float bw
void SimpleSpectrograph::setupParams()
{
// Our Spectrograph is an 8 bit Spectrograph, 100MHz frequency 1MHz samplerate.
setParams(1000000.0, 100000000.0, 8, 10000.0, 1.0);
setFrequency(1000000.0);
setSampleRate(100000000.0);
setBPS(16);
setBandwidth(0.0);
setGain(25.0);
}

/**************************************************************************************
** Client is asking us to start an exposure
***************************************************************************************/
bool SimpleSpectrograph::StartIntegration(float duration)
bool SimpleSpectrograph::StartIntegration(double duration)
{
IntegrationRequest = duration;

Expand Down
6 changes: 3 additions & 3 deletions examples/tutorial_eight/simple_spectrograph.h
Expand Up @@ -38,7 +38,7 @@ class SimpleSpectrograph : public INDI::Spectrograph
bool updateProperties();

// Spectrograph specific functions
bool StartIntegration(float duration);
bool StartIntegration(double duration);
bool paramsUpdated(float sr, float freq, float bps, float bw, float gain);
bool AbortIntegration();
int SetTemperature(double temperature);
Expand All @@ -55,6 +55,6 @@ class SimpleSpectrograph : public INDI::Spectrograph
// Struct to keep timing
struct timeval CapStart { 0, 0 };

float IntegrationRequest { 0 };
float TemperatureRequest { 0 };
double IntegrationRequest { 0 };
double TemperatureRequest { 0 };
};

0 comments on commit 4baf11b

Please sign in to comment.