|
| 1 | +/*========================================================================= |
| 2 | +
|
| 3 | +Library: IntersonArray |
| 4 | +
|
| 5 | +Copyright Kitware Inc. 28 Corporate Drive, |
| 6 | +Clifton Park, NY, 12065, USA. |
| 7 | +
|
| 8 | +All rights reserved. |
| 9 | +
|
| 10 | +Licensed under the Apache License, Version 2.0 ( the "License" ); |
| 11 | +you may not use this file except in compliance with the License. |
| 12 | +You may obtain a copy of the License at |
| 13 | +
|
| 14 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 15 | +
|
| 16 | +Unless required by applicable law or agreed to in writing, software |
| 17 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 18 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 19 | +See the License for the specific language governing permissions and |
| 20 | +limitations under the License. |
| 21 | +
|
| 22 | +=========================================================================*/ |
| 23 | +#include <Windows.h> // Sleep |
| 24 | + |
| 25 | +#include "IntersonArrayCxxImagingContainer.h" |
| 26 | +#include "IntersonArrayCxxControlsHWControls.h" |
| 27 | +#include "igtlImageMessage.h" |
| 28 | +#include "igtlServerSocket.h" |
| 29 | + |
| 30 | +#include "IntersonArrayServerRFCLP.h" |
| 31 | + |
| 32 | +typedef IntersonArrayCxx::Imaging::Container ContainerType; |
| 33 | +typedef ContainerType::RFImagePixelType PixelType; |
| 34 | +bool running; |
| 35 | + |
| 36 | +BOOL WINAPI consoleHandler(DWORD signal) { |
| 37 | + |
| 38 | + if (signal == CTRL_C_EVENT) |
| 39 | + { |
| 40 | + running = false; |
| 41 | + } |
| 42 | + |
| 43 | + return TRUE; |
| 44 | +} |
| 45 | + |
| 46 | +struct CallbackClientData |
| 47 | +{ |
| 48 | + int FrameIndex; |
| 49 | + igtl::Socket * socket; |
| 50 | + igtl::ImageMessage * imgMsg; |
| 51 | + igtl::TimeStamp * ts; |
| 52 | +}; |
| 53 | + |
| 54 | +void __stdcall pasteIntoImage( PixelType * buffer, void * clientData ) |
| 55 | +{ |
| 56 | + CallbackClientData * callbackClientData = |
| 57 | + static_cast< CallbackClientData * >( clientData ); |
| 58 | + |
| 59 | + igtl::ImageMessage * message = callbackClientData->imgMsg; |
| 60 | + igtl::Socket * socket = callbackClientData->socket; |
| 61 | + igtl::TimeStamp * ts = callbackClientData->ts; |
| 62 | + |
| 63 | + const int framePixels = ContainerType::MAX_RFSAMPLES * ContainerType::NBOFLINES; |
| 64 | + ++(callbackClientData->FrameIndex); |
| 65 | + |
| 66 | + message->SetMessageID(callbackClientData->FrameIndex); |
| 67 | + ts->GetTime(); |
| 68 | + igtlUint32 sec; |
| 69 | + igtlUint32 nsec; |
| 70 | + ts->GetTimeStamp(&sec, &nsec); |
| 71 | + message->SetTimeStamp(sec, nsec); |
| 72 | + |
| 73 | + std::memcpy(message->GetScalarPointer(), buffer, framePixels * sizeof(PixelType)); |
| 74 | + |
| 75 | + if (!socket) |
| 76 | + { |
| 77 | + return; |
| 78 | + } |
| 79 | + |
| 80 | + message->Pack(); |
| 81 | + socket->Send(message->GetPackPointer(), message->GetPackSize()); |
| 82 | +} |
| 83 | + |
| 84 | +int main( int argc, char * argv[] ) |
| 85 | +{ |
| 86 | + PARSE_ARGS; |
| 87 | + |
| 88 | + typedef IntersonArrayCxx::Controls::HWControls HWControlsType; |
| 89 | + IntersonArrayCxx::Controls::HWControls hwControls; |
| 90 | + |
| 91 | + int ret = EXIT_SUCCESS; |
| 92 | + |
| 93 | + int steering = 0; |
| 94 | + typedef HWControlsType::FoundProbesType FoundProbesType; |
| 95 | + FoundProbesType foundProbes; |
| 96 | + hwControls.FindAllProbes( foundProbes ); |
| 97 | + if( foundProbes.empty() ) |
| 98 | + { |
| 99 | + std::cerr << "Could not find the probe." << std::endl; |
| 100 | + return EXIT_FAILURE; |
| 101 | + } |
| 102 | + hwControls.FindMyProbe( 0 ); |
| 103 | + const unsigned int probeId = hwControls.GetProbeID(); |
| 104 | + if( probeId == 0 ) |
| 105 | + { |
| 106 | + std::cerr << "Could not find the probe." << std::endl; |
| 107 | + return EXIT_FAILURE; |
| 108 | + } |
| 109 | + |
| 110 | + HWControlsType::FrequenciesType frequencies; |
| 111 | + hwControls.GetFrequency( frequencies ); |
| 112 | + |
| 113 | + HWControlsType::FocusType focuses; |
| 114 | + hwControls.GetFocus(focuses); |
| 115 | + |
| 116 | + if( !hwControls.SetFrequencyAndFocus( frequencyIndex, focusIndex, |
| 117 | + steering ) ) |
| 118 | + { |
| 119 | + std::cerr << "Could not set the frequency and focus." << std::endl; |
| 120 | + return EXIT_FAILURE; |
| 121 | + } |
| 122 | + |
| 123 | + if( !hwControls.SendHighVoltage( highVoltage, highVoltage ) ) |
| 124 | + { |
| 125 | + std::cerr << "Could not set the high voltage." << std::endl; |
| 126 | + return EXIT_FAILURE; |
| 127 | + } |
| 128 | + if( !hwControls.EnableHighVoltage() ) |
| 129 | + { |
| 130 | + std::cerr << "Could not enable high voltage." << std::endl; |
| 131 | + return EXIT_FAILURE; |
| 132 | + } |
| 133 | + |
| 134 | + hwControls.DisableHardButton(); |
| 135 | + ContainerType container; |
| 136 | + container.SetHWControls(&hwControls); |
| 137 | + |
| 138 | + const int height_lines = hwControls.GetLinesPerArray(); |
| 139 | + std::cout << "Lines per array: " << height_lines << std::endl; |
| 140 | + const int width_samples = ContainerType::MAX_RFSAMPLES; |
| 141 | + std::cout << "Max RF samples: " << width_samples << std::endl; |
| 142 | + const double ns = ContainerType::MAX_RFSAMPLES; // number of samples |
| 143 | + const double fs = 30000; // [kHz]=[samples/ms] - sampling frequency |
| 144 | + const double depth = sos * ( ns - 1 ) / ( 2 * fs ); |
| 145 | + const double depthCfm = depth/2; |
| 146 | + std::cout << "Depth: " << depth << "mm" << std::endl; |
| 147 | + std::cout << std::endl; |
| 148 | + |
| 149 | + container.SetRFData( true ); |
| 150 | + container.IdleInitScanConverter( depth, width_samples, height_lines, probeId, |
| 151 | + steering, depthCfm, false, false, 0, false ); |
| 152 | + container.HardInitScanConverter( depth, width_samples, height_lines, steering, |
| 153 | + depthCfm ); |
| 154 | + |
| 155 | + CallbackClientData clientData; |
| 156 | + clientData.FrameIndex = 0; |
| 157 | + |
| 158 | + // size parameters |
| 159 | + const short frameRate = hwControls.GetProbeFrameRate(); |
| 160 | + int size[] = { ContainerType::MAX_RFSAMPLES, ContainerType::NBOFLINES, 1 }; // image dimension |
| 161 | + float spacing[] = { sos / (2 * fs), 38.0 / (height_lines - 1), 1.0 / frameRate }; // spacing (mm/pixel) |
| 162 | + int svsize[] = { ContainerType::MAX_RFSAMPLES, ContainerType::NBOFLINES, 1 }; // sub-volume size |
| 163 | + int svoffset[] = { 0, 0, 0 }; // sub-volume offset |
| 164 | + int scalarType = igtl::ImageMessage::TYPE_INT16;// scalar type |
| 165 | + |
| 166 | + //------------------------------------------------------------ |
| 167 | + // Create a new IMAGE type message |
| 168 | + igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New(); |
| 169 | + imgMsg->SetDimensions(size); |
| 170 | + imgMsg->SetSpacing(spacing); |
| 171 | + imgMsg->SetScalarType(scalarType); |
| 172 | + imgMsg->SetDeviceName("IntersonRF"); |
| 173 | + imgMsg->SetSubVolume(svsize, svoffset); |
| 174 | + imgMsg->SetHeaderVersion(IGTL_HEADER_VERSION_2); |
| 175 | + IANA_ENCODING_TYPE codingScheme = IANA_TYPE_US_ASCII; |
| 176 | + |
| 177 | + //Add meta data here |
| 178 | + imgMsg->SetMetaDataElement("Frequency (MHz)", codingScheme, std::to_string(frequencies[frequencyIndex])); |
| 179 | + imgMsg->SetMetaDataElement("Focus (mm)", codingScheme, std::to_string(focuses[focusIndex])); |
| 180 | + imgMsg->SetMetaDataElement("High voltage", codingScheme, std::to_string(highVoltage)); |
| 181 | + imgMsg->SetMetaDataElement("SOS", codingScheme, std::to_string(sos)); |
| 182 | + imgMsg->SetMetaDataElement("FPS", codingScheme, std::to_string(frameRate)); |
| 183 | + imgMsg->SetMetaDataElement("Steering", codingScheme, std::to_string(steering)); |
| 184 | + imgMsg->SetMetaDataElement("Image Type", codingScheme, "RF"); |
| 185 | + imgMsg->SetMetaDataElement("Timestamp seconds", codingScheme, "0"); |
| 186 | + imgMsg->SetMetaDataElement("Timestamp nseconds", codingScheme, "0"); |
| 187 | + |
| 188 | + imgMsg->AllocateScalars(); |
| 189 | + imgMsg->SetEndian(igtl::ImageMessage::ENDIAN_LITTLE); |
| 190 | + igtl::Matrix4x4 matrix; |
| 191 | + matrix[0][0] = 0.0; matrix[1][0] = -1.0; matrix[2][0] = 0.0; matrix[3][0] = 0.0; |
| 192 | + matrix[0][1] = 1.0; matrix[1][1] = 0.0; matrix[2][1] = 0.0; matrix[3][1] = 0.0; |
| 193 | + matrix[0][2] = 0.0; matrix[1][2] = 0.0; matrix[2][2] = 1.0; matrix[3][2] = 0.0; |
| 194 | + matrix[0][3] = 0.0; matrix[1][3] = 0.0; matrix[2][3] = 0.0; matrix[3][3] = 1.0; |
| 195 | + imgMsg->SetMatrix(matrix); |
| 196 | + igtl::TimeStamp::Pointer ts = igtl::TimeStamp::New(); |
| 197 | + clientData.ts = ts.GetPointer(); |
| 198 | + clientData.imgMsg = imgMsg.GetPointer(); |
| 199 | + |
| 200 | + //socket setup |
| 201 | + igtl::ServerSocket::Pointer serverSocket; |
| 202 | + serverSocket = igtl::ServerSocket::New(); |
| 203 | + int r = serverSocket->CreateServer(port); |
| 204 | + |
| 205 | + if (r < 0) |
| 206 | + { |
| 207 | + std::cerr << "Cannot create a server socket." << std::endl; |
| 208 | + exit(0); |
| 209 | + } |
| 210 | + std::cerr << "Created Server socket." << std::endl; |
| 211 | + |
| 212 | + |
| 213 | + igtl::Socket::Pointer socket; |
| 214 | + clientData.socket = socket; |
| 215 | + |
| 216 | + container.SetNewRFImageCallback( &pasteIntoImage, &clientData ); |
| 217 | + |
| 218 | + std::cout << "StartRFReadScan" << std::endl; |
| 219 | + container.StartRFReadScan(); |
| 220 | + Sleep( 100 ); // "time to start" |
| 221 | + std::cout << "StartRFmode" << std::endl; |
| 222 | + if( !hwControls.StartRFmode() ) |
| 223 | + { |
| 224 | + std::cerr << "Could not start RF collection." << std::endl; |
| 225 | + return EXIT_FAILURE; |
| 226 | + } |
| 227 | + |
| 228 | + if (!SetConsoleCtrlHandler(consoleHandler, TRUE)) |
| 229 | + { |
| 230 | + std::cout << "Could not set control handler" << std::endl; |
| 231 | + return 1; |
| 232 | + } |
| 233 | + running = true; |
| 234 | + std::cout << "Server is running, use Ctrl-C to stop" << std::endl; |
| 235 | + while( running ) |
| 236 | + { |
| 237 | + //------------------------------------------------------------ |
| 238 | + // Waiting for Connection |
| 239 | + socket = serverSocket->WaitForConnection(1000); |
| 240 | + clientData.socket = socket.GetPointer(); |
| 241 | + if (socket.IsNotNull()) // if client connected |
| 242 | + { |
| 243 | + Sleep(10000); //chill for a bit |
| 244 | + } |
| 245 | + |
| 246 | + } |
| 247 | + |
| 248 | + std::cout << "Shutting down" << std::endl; |
| 249 | + hwControls.StopAcquisition(); |
| 250 | + container.StopReadScan(); |
| 251 | + if (socket) |
| 252 | + { |
| 253 | + socket->CloseSocket(); |
| 254 | + } |
| 255 | + |
| 256 | + Sleep( 100 ); // "time to stop" |
| 257 | + return ret; |
| 258 | +} |
0 commit comments