#include "model/processor/strategies/ScanConversion.h" #include #include #include "model/processor/BIP.h" ScanConversion::ScanConversion(const Context context, const QString kernelPath, const QObject *parent = Q_NULLPTR) : IProcessStrategy(context, kernelPath, "ScanConversion", parent), _kernelFunctor(KernelFunctor(_kernel)) { _gridPixelXPos = Q_NULLPTR; _gridPixelZPos = Q_NULLPTR; _scanXPos = Q_NULLPTR; _scanZPos = Q_NULLPTR; _gridX = Q_NULLPTR; _gridZ = Q_NULLPTR; _queryX = Q_NULLPTR; _queryZ = Q_NULLPTR; _gridPixelR = Q_NULLPTR; _gridPixelTheta = Q_NULLPTR; } void ScanConversion::cpuProcess(ScenGenOutput_t params) { auto context = _openCLHelper.getContext(); auto queue = BIP::getInstance()->CLQueue; //convex if (!params.linear.value) { if(params.outputWidth.isUpdated || params.outputHeight.isUpdated) { if(_gridPixelXPos) delete[] _gridPixelXPos; if(_gridPixelZPos) delete[] _gridPixelZPos; _gridPixelXPos = new myflt[params.outputWidth.value * params.outputHeight.value]; _gridPixelZPos = new myflt[params.outputWidth.value * params.outputHeight.value]; _width = params.outputWidth.value; _height = params.outputHeight.value; _kernelParameters.width = _width; } if(params.depth.isUpdated || params.probeRadius.isUpdated || params.fieldOfView.isUpdated || params.angle.isUpdated || params.startDepth.isUpdated || params.startDepth.isUpdated || params.outputWidth.isUpdated || params.outputHeight.isUpdated|| params.steering.isUpdated) { auto maxX = params.probeRadius.value*sinf(params.fieldOfView.value/2)+params.depth.value*sinf(params.angle.value/2); auto minX = -1 * maxX; auto maxZ = params.depth.value + params.probeRadius.value; auto minZ = params.probeRadius.value*cosf(params.fieldOfView.value/2)+params.startDepth.value*cosf(params.angle.value/2); // auto baseZ = (maxZ - minZ) / (params.outputHeight.value - 1); // auto baseX = (maxX - minX) / (params.outputWidth.value - 1); // for (auto i = 0; i < params.outputHeight.value; ++i) // { // auto temp = i * baseZ; // auto baseIndex = i * params.outputHeight.value; // for (auto j = 0; j < params.outputWidth.value; ++j) // { // auto b = minX + baseX * j; // _gridPixelXPos[baseIndex+j] = b; // auto a = minZ + temp; // _gridPixelZPos[baseIndex+j] = a; // } // } auto baseZ = (maxZ - minZ) / (params.outputHeight.value - 1); auto baseX = (maxX - minX) / (params.outputWidth.value - 1); for (auto i = 0; i < params.outputHeight.value; ++i) { auto temp = i * baseZ; auto baseIndex = i * params.outputHeight.value; for (auto j = 0; j < params.outputWidth.value; ++j) { auto a = minZ + i * (maxZ - minZ) / (params.outputHeight.value - 1); _gridPixelZPos[baseIndex+j] = a; auto b = minX + baseX * j; _gridPixelXPos[baseIndex+j] = b; } } if(_gridPixelR) delete[] _gridPixelR; _gridPixelR = new myflt[params.outputWidth.value * params.outputHeight.value]; if(_gridPixelTheta) delete[] _gridPixelTheta; _gridPixelTheta = new myflt[params.outputWidth.value * params.outputHeight.value]; auto virtualOriginalZ = params.probeRadius.value * (cosf(params.fieldOfView.value/2) - sinf(params.fieldOfView.value/2) / tanf(params.angle.value/2)); auto virtualOriginalZ2 = powf(virtualOriginalZ, 2); auto minR = params.probeRadius.value - virtualOriginalZ + params.startDepth.value; auto maxR = params.probeRadius.value + params.depth.value; auto minTheta = (-1 * params.angle.value) / 2 - abs(params.steering.value); auto maxTheta = params.angle.value / 2 + abs(params.steering.value); auto strSin = 2 * sinf(params.steering.value); auto maxInterceptTheta = params.fieldOfView.value / 2; auto radius2 = powf(params.probeRadius.value, 2); if(params.steering.value == 0.0f) { for (auto i = 0; i < params.outputWidth.value * params.outputHeight.value; ++i) { auto x = _gridPixelXPos[i]; auto z = _gridPixelZPos[i]; auto pixelTheta = atan2f(x, z - virtualOriginalZ); auto pixelR = sqrtf(powf(x, 2) + powf((z - virtualOriginalZ), 2)); if(pixelR >= minR && pixelR <= maxR && pixelTheta >= minTheta && pixelTheta <= maxTheta) { auto interceptTheta = 0.0f; auto interceptX = 0.0f; auto interceptZ = 0.0f; auto alpha = virtualOriginalZ; auto beta = (virtualOriginalZ - z) / x; if (x == 0.0f) interceptTheta = 0; else { interceptX = (alpha * beta + sqrtf(-1 * powf(alpha, 2) + (powf(beta, 2) + 1)* radius2)) / (powf(beta, 2) + 1); interceptZ = alpha - beta * interceptX; interceptTheta = atan2f(interceptX, interceptZ); } if(interceptTheta > maxInterceptTheta || interceptTheta < (-1 * maxInterceptTheta)) { interceptX = (alpha * beta - sqrtf(-1 * powf(alpha, 2) + (powf(beta, 2) + 1)* radius2)) / (powf(beta, 2) + 1); interceptZ = alpha - beta * interceptX; interceptTheta = atan2f(interceptX, interceptZ); if(interceptTheta > maxInterceptTheta || interceptTheta < (-1 * maxInterceptTheta)) { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } else { auto gridPixelAx = sqrtf(powf((x - params.probeRadius.value * sinf(interceptTheta)), 2) + powf((z - params.probeRadius.value * cosf(interceptTheta)), 2)); if(gridPixelAx >= params.startDepth.value && gridPixelAx <= params.depth.value) { _gridPixelR[i] = params.probeRadius.value + gridPixelAx; _gridPixelTheta[i] = interceptTheta; } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } else { auto gridPixelAx = sqrtf(powf((x - params.probeRadius.value * sinf(interceptTheta)), 2) + powf((z - params.probeRadius.value * cosf(interceptTheta)), 2)); if(gridPixelAx >= params.startDepth.value && gridPixelAx <= params.depth.value) { _gridPixelR[i] = params.probeRadius.value + gridPixelAx; _gridPixelTheta[i] = interceptTheta; } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } else { for (auto i = 0; i < params.outputWidth.value * params.outputHeight.value; ++i) { auto x = _gridPixelXPos[i]; auto z = _gridPixelZPos[i]; auto pixelTheta = atan2f(x, z - virtualOriginalZ); auto pixelR = sqrtf(powf(x, 2) + powf((z - virtualOriginalZ), 2)); if(pixelR >= minR && pixelR <= maxR && pixelTheta >= minTheta && pixelTheta <=maxTheta) { auto ro = pixelR / strSin; auto xo = ro * cosf(params.steering.value - pixelTheta); auto zo = ro * sinf(params.steering.value - pixelTheta) + virtualOriginalZ; if(zo == 0.0f) { auto interceptX = (radius2 - virtualOriginalZ2) / 2 / xo; auto interceptZ = sqrtf(radius2 - powf(interceptX , 2)); auto interceptTheta = atan2f(interceptX, interceptZ); if (interceptTheta > maxInterceptTheta || interceptTheta < (-1 * maxInterceptTheta)) { interceptZ = -1 * sqrtf(radius2 - powf(interceptX , 2)); interceptTheta = atan2(interceptX, interceptZ); if(interceptTheta > maxInterceptTheta || interceptTheta < (-1 * maxInterceptTheta)) { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } else { auto gridPixelAx = sqrtf(powf(x - params.probeRadius.value * sinf(interceptTheta), 2) + powf(z - params.probeRadius.value * cosf(interceptTheta), 2)); if(gridPixelAx >= params.startDepth.value && gridPixelAx <= params.depth.value) { _gridPixelR[i] = params.probeRadius.value + gridPixelAx; _gridPixelTheta[i] = interceptTheta; } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } else { auto gridPixelAx = sqrtf(powf(x - params.probeRadius.value * sinf(interceptTheta), 2) + powf(z - params.probeRadius.value * cosf(interceptTheta), 2)); if(gridPixelAx >= params.startDepth.value && gridPixelAx <= params.depth.value) { _gridPixelR[i] = params.probeRadius.value + gridPixelAx; _gridPixelTheta[i] = interceptTheta; } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } else { auto alpha = (radius2 - virtualOriginalZ2 + 2 * zo * virtualOriginalZ) / 2 / zo; auto beta = xo / zo; auto interceptX = (alpha * beta + sqrtf(-1 * powf(alpha, 2) + (powf(beta,2) + 1) * radius2)) / (powf(beta, 2) + 1); auto interceptZ = alpha - beta * interceptX; auto interceptTheta = atan2f(interceptX, interceptZ); if(interceptTheta > maxInterceptTheta || interceptTheta < (-1 * maxInterceptTheta)) { interceptX = (alpha * beta - sqrtf(-1 * powf(alpha, 2) + (powf(beta,2) + 1) * radius2)) / (powf(beta, 2) + 1); interceptZ = alpha - beta * interceptX; interceptTheta = atan2f(interceptX, interceptZ); if(interceptTheta > maxInterceptTheta || interceptTheta < (-1 * maxInterceptTheta)) { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } else { auto gridPixelAx = sqrtf(powf(x - params.probeRadius.value * sinf(interceptTheta), 2) + powf(z - params.probeRadius.value * cosf(interceptTheta), 2)); if(gridPixelAx >= params.startDepth.value && gridPixelAx <= params.depth.value) { _gridPixelR[i] = params.probeRadius.value + gridPixelAx; _gridPixelTheta[i] = interceptTheta; } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } else { auto gridPixelAx = sqrtf(powf(x - params.probeRadius.value * sinf(interceptTheta), 2) + powf(z - params.probeRadius.value * cosf(interceptTheta), 2)); if(gridPixelAx >= params.startDepth.value && gridPixelAx <= params.depth.value) { _gridPixelR[i] = params.probeRadius.value + gridPixelAx; _gridPixelTheta[i] = interceptTheta; } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } if(_queryX) delete _queryX; if(_queryZ) delete _queryZ; _queryX = _openCLHelper.array2CLBuffer(context, params.outputWidth.value * params.outputHeight.value * sizeof (myflt)); _queryZ = _openCLHelper.array2CLBuffer(context, params.outputWidth.value * params.outputHeight.value * sizeof (myflt)); BIP::getInstance()->CLQueue.enqueueWriteBuffer(*_queryZ, CL_TRUE, 0, params.outputWidth.value * params.outputHeight.value * sizeof (myflt), _gridPixelR); queue.enqueueWriteBuffer(*_queryX, CL_TRUE, 0, params.outputWidth.value * params.outputHeight.value * sizeof (myflt), _gridPixelTheta); } //TODO:: write after convex //scanTheta if(params.rxLineNo.isUpdated || params.minScanAz.isUpdated || params.rxLineDaz.isUpdated) { if(_scanXPos) delete [] _scanXPos; if(_gridX) delete _gridX; _scanXPos = new myflt[params.rxLineNo.value]; for (auto i = 0; i < params.rxLineNo.value ; ++i) { _scanXPos[i] = params.minScanAz.value + i * params.rxLineDaz.value; } _gridX = _openCLHelper.array2CLBuffer(context, static_cast(params.rxLineNo.value * sizeof (myflt))); auto er = queue.enqueueWriteBuffer(*_gridX,CL_TRUE, 0, static_cast(params.rxLineNo.value * sizeof (myflt)), _scanXPos); _kernelParameters.gridXSize = params.rxLineNo.value; } //scanR if(params.rxFocusPointNo.isUpdated || params.minScanAx.isUpdated || params.rxPointDax.isUpdated) { if(_scanZPos) delete [] _scanZPos; if(_gridZ) delete _gridZ; _scanZPos = new myflt[params.rxFocusPointNo.value]; for (auto i = 0; i < params.rxFocusPointNo.value; ++i) { _scanZPos[i] = (params.minScanAx.value + i * params.rxPointDax.value ) +params.probeRadius.value; } _gridZ = _openCLHelper.array2CLBuffer(context, static_cast(params.rxFocusPointNo.value * sizeof (myflt))); auto er = queue.enqueueWriteBuffer(*_gridZ, CL_TRUE, 0, static_cast(params.rxFocusPointNo.value * sizeof (myflt)),_scanZPos); _kernelParameters.gridZSize = params.rxFocusPointNo.value; } } //virtual convex else if(params.virtualConvex.value) { if(params.outputWidth.isUpdated|| params.outputHeight.isUpdated) { if(_gridPixelXPos) delete[] _gridPixelXPos; if(_gridPixelZPos) delete[] _gridPixelZPos; _gridPixelXPos = new myflt[params.outputWidth.value * params.outputHeight.value]; _gridPixelZPos = new myflt[params.outputWidth.value * params.outputHeight.value]; _width = params.outputWidth.value; _height = params.outputHeight.value; _kernelParameters.width = _width; } if(params.depth.isUpdated || params.startDepth.isUpdated || params.fieldOfView.isUpdated || params.vcMaxTheta.isUpdated || params.outputWidth.isUpdated || params.outputHeight.isUpdated) { auto maxZ = params.depth.value; auto minZ = params.startDepth.value * cosf(params.vcMaxTheta.value); auto maxX = params.fieldOfView.value / 2 + maxZ * sinf(params.vcMaxTheta.value); auto minX = -1 * maxX; auto baseZ = (maxZ - minZ) / (params.outputHeight.value - 1); auto baseX = (maxX - minX) / (params.outputWidth.value - 1); for(auto i = 0; i < params.outputHeight.value; i++) { auto temp = i * baseZ; for(auto j = 0; j < params.outputWidth.value; j++) { _gridPixelZPos[i * params.outputHeight.value + j] = minZ + temp; _gridPixelXPos[i * params.outputHeight.value + j] = minX + (baseX * j); } } auto virtualOriginZ = params.fieldOfView.value / 2 / tanf(params.vcMaxTheta.value); if(_gridPixelR) delete[] _gridPixelR; if(_gridPixelTheta) delete[] _gridPixelTheta; _gridPixelR = new myflt[params.outputWidth.value * params.outputHeight.value]; _gridPixelTheta = new myflt[params.outputWidth.value * params.outputHeight.value]; auto strTan = tanf(params.steering.value); for(auto i = 0; i < params.outputWidth.value * params.outputHeight.value; i++) { auto x = _gridPixelXPos[i]; auto z = _gridPixelZPos[i]; auto pixelTheta = atanf(x / (z + virtualOriginZ)); if(pixelTheta >= -params.vcMaxTheta.value - abs(params.steering.value) && pixelTheta <= params.vcMaxTheta.value + abs(params.steering.value)) { if(params.steering.value == 0) { auto gridPixelAx = sqrtf(powf(x - virtualOriginZ * tanf(pixelTheta), 2) + powf(z, 2)); if(gridPixelAx >= params.startDepth.value && gridPixelAx <= params.depth.value) { _gridPixelR[i] = gridPixelAx; _gridPixelTheta[i] = pixelTheta; } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } else { auto a = virtualOriginZ * strTan; auto b = x * strTan + virtualOriginZ + z; auto c = x - z * strTan; auto interceptTheta = atanf((b + sqrtf(powf(b, 2) - 4 * a * c)) / (2 * a)); if(interceptTheta > params.vcMaxTheta.value || interceptTheta < -params.vcMaxTheta.value) { interceptTheta = atanf((b - sqrtf(powf(b, 2) - 4 * a * c)) / (2 * a)); if(interceptTheta > params.vcMaxTheta.value || interceptTheta < -params.vcMaxTheta.value) { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } else { auto gridPixelAx = sqrtf(powf(x - virtualOriginZ * tanf(interceptTheta), 2) + powf(z, 2)); if(gridPixelAx >= params.startDepth.value && gridPixelAx <= params.depth.value) { _gridPixelR[i] = gridPixelAx; _gridPixelTheta[i] = interceptTheta; } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } else { auto gridPixelAx = sqrtf(powf(x - virtualOriginZ * tanf(interceptTheta), 2) + powf(z, 2)); if(gridPixelAx >= params.startDepth.value && gridPixelAx <= params.depth.value) { _gridPixelR[i] = gridPixelAx; _gridPixelTheta[i] = interceptTheta; } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } } } else { _gridPixelR[i] = 0; _gridPixelTheta[i] = 0; } } if(_queryX) delete _queryX; if(_queryZ) delete _queryZ; _queryX = _openCLHelper.array2CLBuffer(context, params.outputWidth.value * params.outputHeight.value * sizeof (myflt)); _queryZ = _openCLHelper.array2CLBuffer(context, params.outputWidth.value * params.outputHeight.value * sizeof (myflt)); BIP::getInstance()->CLQueue.enqueueWriteBuffer(*_queryZ, CL_TRUE, 0, params.outputWidth.value * params.outputHeight.value * sizeof (myflt), _gridPixelR); queue.enqueueWriteBuffer(*_queryX, CL_TRUE, 0, params.outputWidth.value * params.outputHeight.value * sizeof (myflt), _gridPixelTheta); } if(params.minScanAz.isUpdated || params.rxLineNo.isUpdated || params.rxLineDaz.isUpdated) { if(_scanXPos) delete [] _scanXPos; if(_gridX) delete _gridX; _scanXPos = new myflt[params.rxLineNo.value]; for(auto i = 0; i < params.rxLineNo.value; i++) { _scanXPos[i] = params.minScanAz.value + i * params.rxLineDaz.value; } _gridX = _openCLHelper.array2CLBuffer(context, static_cast(params.rxLineNo.value) * sizeof (myflt)); queue.enqueueWriteBuffer(*_gridX, CL_TRUE, 0, static_cast(params.rxLineNo.value) * sizeof (myflt), _scanXPos); _kernelParameters.gridXSize = params.rxLineNo.value; } if(params.rxFocusPointNo.isUpdated || params.minScanAx.isUpdated || params.rxPointDax.isUpdated) { if(_scanZPos) delete[] _scanZPos; if(_gridZ) delete _gridZ; _scanZPos = new myflt [params.rxFocusPointNo.value]; for(auto i = 0; i < params.rxFocusPointNo.value; i++) { _scanZPos[i] = params.minScanAx.value + i * params.rxPointDax.value; } _gridZ = _openCLHelper.array2CLBuffer(context, static_cast(params.rxFocusPointNo.value) * sizeof (myflt)); queue.enqueueWriteBuffer(*_gridZ, CL_TRUE, 0, static_cast(params.rxFocusPointNo.value) * sizeof (myflt), _scanZPos); _kernelParameters.gridZSize = params.rxFocusPointNo.value; } } //linear non convex else { if(params.outputWidth.isUpdated || params.outputHeight.isUpdated) { if(_gridPixelXPos) delete[] _gridPixelXPos; if(_gridPixelZPos) delete[] _gridPixelZPos; _gridPixelXPos = new myflt[params.outputWidth.value * params.outputHeight.value]; _gridPixelZPos = new myflt[params.outputWidth.value * params.outputHeight.value]; if(_queryX) delete _queryX; if(_queryZ) delete _queryZ; _queryX = _openCLHelper.array2CLBuffer(context, params.outputWidth.value * params.outputHeight.value * sizeof (myflt)); _queryZ = _openCLHelper.array2CLBuffer(context, params.outputWidth.value * params.outputHeight.value * sizeof (myflt)); _width = params.outputWidth.value; _height = params.outputHeight.value; _kernelParameters.width = _width; } if(params.depth.isUpdated || params.startDepth.isUpdated || params.fieldOfView.isUpdated || params.steering.isUpdated || params.outputWidth.isUpdated || params.outputHeight.isUpdated) { auto maxZ = params.depth.value; auto minZ = params.startDepth.value; auto maxX = params.fieldOfView.value / 2; auto minX = -1 * maxX; auto baseZ = (maxZ - minZ) / (params.outputHeight.value - 1); auto baseX = (maxX - minX) / (params.outputWidth.value - 1); for(auto i = 0; i < params.outputHeight.value; i++) { auto temp = i * baseZ; auto tan_result = temp * tanf(params.steering.value); for(auto j = 0; j < params.outputWidth.value; j++) { _gridPixelZPos[i * params.outputHeight.value + j] = minZ + temp; _gridPixelXPos[i * params.outputHeight.value + j] = minX + (baseX * j) - tan_result; } } BIP::getInstance()->CLQueue.enqueueWriteBuffer(*_queryX, CL_TRUE, 0, params.outputWidth.value * params.outputHeight.value * sizeof (myflt), _gridPixelXPos); queue.enqueueWriteBuffer(*_queryZ, CL_TRUE, 0, params.outputWidth.value * params.outputHeight.value * sizeof (myflt), _gridPixelZPos); } if(params.fieldOfView.isUpdated || params.rxLineNo.isUpdated || params.rxLineDaz.isUpdated) { if(_scanXPos) delete [] _scanXPos; if(_gridX) delete _gridX; _scanXPos = new myflt[params.rxLineNo.value]; for(auto i = 0; i < params.rxLineNo.value; i++) { _scanXPos[i] = -params.fieldOfView.value / 2 + i * params.rxLineDaz.value; } _gridX = _openCLHelper.array2CLBuffer(context, static_cast(params.rxLineNo.value) * sizeof (myflt)); queue.enqueueWriteBuffer(*_gridX, CL_TRUE, 0, static_cast(params.rxLineNo.value) * sizeof (myflt), _scanXPos); _kernelParameters.gridXSize = params.rxLineNo.value; } if(params.rxFocusPointNo.isUpdated || params.rxPointDax.isUpdated) { if(_scanZPos) delete[] _scanZPos; if(_gridZ) delete _gridZ; _scanZPos = new myflt [params.rxFocusPointNo.value]; for(auto i = 0; i < params.rxFocusPointNo.value; i++) { _scanZPos[i] = params.startDepth.value + i * params.rxPointDax.value; } _gridZ = _openCLHelper.array2CLBuffer(context, static_cast(params.rxFocusPointNo.value) * sizeof (myflt)); queue.enqueueWriteBuffer(*_gridZ, CL_TRUE, 0, static_cast(params.rxFocusPointNo.value) * sizeof (myflt), _scanZPos); _kernelParameters.gridZSize = params.rxFocusPointNo.value; } } } void ScanConversion::finalize() { delete _gridPixelXPos; delete _gridPixelZPos; delete _scanXPos; delete _scanZPos; delete _gridX; delete _gridZ; delete _queryX; delete _queryZ; _gridPixelXPos = Q_NULLPTR; _gridPixelZPos = Q_NULLPTR; _scanXPos = Q_NULLPTR; _scanZPos = Q_NULLPTR; _gridX = Q_NULLPTR; _gridZ = Q_NULLPTR; _queryX = Q_NULLPTR; _queryZ = Q_NULLPTR; } Image* ScanConversion::processKernel(Image *frames, Buffer* scrathPad) { Context context = _openCLHelper.getContext(); auto format = frames->getImageInfo(); auto imageOutput = new Image2D(context, CL_MEM_READ_WRITE, ImageFormat(format.image_channel_order, format.image_channel_data_type), _width, _height); cl::EnqueueArgs eargs(BIP::getInstance()->CLQueue, cl::NDRange(_width, _height)); _openCLHelper.runKernelFunctor(_kernelFunctor, eargs, *(Image2D*)(frames), *imageOutput, *_gridX, *_gridZ, *_queryX, *_queryZ, _kernelParameters); delete frames; return imageOutput; }