FMCW Radar Postprocessing in Time-variant Indoor Scenarios

Detailed Description

This is an example of how to use the WInProp API for FMCW radar postprocessing in a time-variant indoor scenario. The full example is distributed with the installation.
#include <cstdio>
#include <string>
#include <iostream>

#include "indoor_propagation_fmcw.h"

#include "../Interface/Init.h"     
#include "../FMCW/winprop_fmcw_radar.h"

#ifndef API_DATA_FOLDER
#define API_DATA_FOLDER "../../api/winprop/data/"
#endif // !API_DATA_FOLDER

int main(int argc, char** argv)
{
	int Error = 0;

	/* ------------------ Initialization of scenario --------------------------- */
	WinProp_Scenario WinPropScenario;
	WinProp_Structure_Init_Scenario(&WinPropScenario);
	/* ---------- Load indoor vector database and initialize scenario ------------ */
	/* Assign database name. */
	WinPropScenario.Scenario = WINPROP_SCENARIO_INDOOR;
	char VectorDatabase[500];
	sprintf(VectorDatabase, "%s", API_DATA_FOLDER "../data/indoor/RadarScenario.idb");
	WinPropScenario.VectorDatabase = VectorDatabase;

	/* Define callback functions. */
	WinProp_Callback WinPropCallback;
	WinProp_Structure_Init_Callback(&WinPropCallback);
	WinPropCallback.Percentage = CallbackProgress;
	WinPropCallback.Message = CallbackMessage;
	WinPropCallback.Error = CallbackError;

	/* ------------------------- Set up prediction ------------------------------- */
	if (Error == 0)
	{
		/* Definition of prediction points. */
		int NrPoints = 1;
		WinProp_Receiver WinPropReceiver;
		WinProp_Structure_Init_Receiver(&WinPropReceiver);
		WinPropReceiver.Location.x = 5.8;
		WinPropReceiver.Location.y = -2.;
		WinPropReceiver.Location.z = 0.5;
		WinPropReceiver.GroupID = 230; // Group id of the radar car

		/* Definition of antenna pattern. */
		WinProp_Pattern WinPropPattern;
		WinProp_Structure_Init_Pattern(&WinPropPattern);
		WinPropPattern.Mode = PATTERN_MODE_FILE; // Load pattern from file
		char PatternFileName[500];
		sprintf(PatternFileName, "%s", API_DATA_FOLDER "antennas/RadarAntenna.ffe");
		WinPropPattern.Filename = PatternFileName; // Pattern file (including extension)

		/* Definition of antenna properties. */
		WinProp_Antenna WinPropAntenna;
		WinProp_Structure_Init_Antenna(&WinPropAntenna);
		WinPropAntenna.Enabled = 1;
		WinPropAntenna.Id = 1;
		WinPropAntenna.SiteId = 1;
		WinPropAntenna.Longitude_X = 5.8;
		WinPropAntenna.Latitude_Y = -2.0;
		WinPropAntenna.Height = 0.5; // Antenna height 0.5 meter
		WinPropAntenna.Model = WINPROP_MODEL_SRT; // Use the standard ray tracing
		WinPropAntenna.DataType = PROP_RESULT_POWER; // Compute received power
		WinPropAntenna.Power = 13.; // Power in dBm
		WinPropAntenna.Frequency = 77000.; // Frequency 77 GHz
		WinPropAntenna.Pattern = &WinPropPattern; // Use pattern defined above
		WinPropAntenna.Azimuth = 90.; // Antenna points in eastern direction
		WinPropAntenna.Downtilt = 0.; // Downtilt of 0 degree
		WinPropAntenna.GroupIDMounted = 230; // Group id of the radar car

		char AntennaName[500];
		sprintf(AntennaName, "%s", "radar_antenna");
		WinPropAntenna.Name = AntennaName; // name of the antenna

		/* Definition of ray tracing parameters. */
		Model_RAYTRACING ModelRT;
		WinProp_Structure_Init_Model_RayTracing(&ModelRT);
		ModelRT.MaxNrDiffractions = 1;
		ModelRT.MaxNrReflections = 1;
		ModelRT.MaxNrTransmissions = 0;
		ModelRT.MaxNrReflDiffr = 1;

		/* Definition of outputs to be computed and written in WinProp format. */
		WinProp_Additional WinPropMore;
		WinProp_Propagation_Results OutputResults;
		WinProp_Structure_Init_Additional(&WinPropMore);
		WinProp_Structure_Init_Propagation_Results(&OutputResults);
		WinPropMore.OutputResults = &OutputResults;
		OutputResults.FieldStrength = 1;
		OutputResults.RayFilePropPaths = 1;
		OutputResults.StrFilePropPaths = 1;

		/* Further parameters: */
		WinPropMore.InteractionModel = WINPROP_INTERACTION_MODEL_GTDUTD;
		WinPropMore.MaxNumberPathsUsed = 1;
		WinPropMore.MaxNumberPaths = 60;
		WinPropMore.MaxDynamicPathsEnabled = 1;
		WinPropMore.MaxDynamicPaths = 100.;
		WinPropMore.MaxPathLossEnabled = 1;
		WinPropMore.MaxPathLoss = 200.;

		/* Set time instance(s) and output folder */
		double timeInstances[1] = { 1.0 }; // 1 s
		WinPropMore.TimeInstances = timeInstances;
		WinPropMore.NbrTimeInstances = 1;
		OutputResults.ResultPath = API_DATA_FOLDER "output/fmcw_radar";

		/* Call the WinProp API to open a project and load the vector database. */
		int ProjectHandle = 0;
		Error = WinProp_Open(&ProjectHandle, &WinPropScenario, &WinPropCallback);

		/* ----- Start prediction (including loop over all time instances) ------ */
		WinProp_ResultPointsList* PowerResult = nullptr;
		Error = WinProp_Predict_Points(
			ProjectHandle,
			&WinPropAntenna,
			&WinPropReceiver,
			NrPoints,
			&ModelRT,
			&WinPropMore,
			&PowerResult,
			nullptr,
			nullptr);

		if (Error == 0)
		{
			/* ------------------------- FMCW radar ------------------------------- */

			/* Definition of radar parameters */
			WinProp_FMCW_Para RadarPara;
			RadarPara.Mode = WinProp_FMCW_Para::ParametersMode::SET_PARAMETERS; // set parameters mode
			RadarPara.Freq = 77e9;    // radar frequency
			RadarPara.Tc = 20e-6;     // chirp duration
			RadarPara.B = 1e9;        // sweep bandwidth
			RadarPara.NrChirps = 64;  // number of chirps
			RadarPara.Cohrent = true; // coherent superposition of rays
			RadarPara.NrBins = WinProp_FMCW_Para::FreqBins::FFT_512; // FFT Samples (range domain)

			/* Parameters relevant to output results */
			RadarPara.WindFunc = WinProp_FMCW_Para::Windowing::HANNING;
			RadarPara.GenerateRangeDoppler = true;
			RadarPara.GenerateRangeAngle = false;
			RadarPara.GenerteIQ = false;

			/* Range-Doppler heatmap result */
			WinProp_ResultPlane RangeVelocity;
			WinProp_Structure_Init_ResultPlane(&RangeVelocity);

			/*------- FMCW radar post-processing -------*/
			WinProp_FMCW_Radar FMCW_Radar;
			FMCW_Radar.compute(&RadarPara, 1, &PowerResult->ResultPoints[0].Rays, &WinPropCallback, &RangeVelocity, nullptr);

			/* Use RangeVelocity to find the range and velocity of the targets */

			/* Save values in ASCII file */
			char Filename[200] = API_DATA_FOLDER "output/fmcw_radar/heatmap.txt";
			FILE* OutputFile = fopen(Filename, "w");
			for (size_t i = 0; i < RangeVelocity.Columns; i++)
			{
				for (size_t j = 0; j < RangeVelocity.Lines; j++)
				{
					fprintf(OutputFile, "%.3f\t%.3f\t%.3f\n", 
						RangeVelocity.Matrix[i][j].Location.x, 
						RangeVelocity.Matrix[i][j].Location.y,
						RangeVelocity.Matrix[i][j].Value);
				}
			}

			/* Close file. */
			fclose(OutputFile);

			/* Free memory */
			WinProp_Structure_Free_ResultPlane(&RangeVelocity);
		}

		/* Close project */
		WinProp_Close(ProjectHandle);

		/* Free memory */
		WinProp_Structure_Free_ResultPointsList(PowerResult);

	}


	return 0;
}

int _STD_CALL CallbackMessage(const char * Text)
{
	if (Text == nullptr)
		return 0;

	std::cout << "\n" << Text;

	return(0);
}

int _STD_CALL CallbackError(const char * Text, int Error)
{
	if (Text == nullptr)
		return 0;

	std::cout << "\n";

#ifdef __LINUX
	std::cout << "\033[31m" << "Error (" << Error << "): "; // highlight error in red color
#else
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hConsole, FOREGROUND_RED);
	std::cout << "Error (" << Error << "): ";
#endif // __LINUX
	std::cout << Text;

#ifdef __LINUX
	std::cout << "\033[0m"; // highlight error in red color
#else
	SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN);
#endif // __LINUX

	return 0;
}

int _STD_CALL CallbackProgress(int value, const char* text)
{
	char Line[200];

	sprintf(Line, "\n%d%% %s", value, text);
	std::cout << Line;

	return(0);
}