-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathmain.cpp
484 lines (413 loc) · 15 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
/********************************************************************************/
/* */
/* Copyright (c) 2020 Analog Devices, Inc. All Rights Reserved. */
/* This software is proprietary to Analog Devices, Inc. and its licensors. */
/* */
/********************************************************************************/
#include <aditof/camera.h>
#include <aditof/depth_sensor_interface.h>
#include <aditof/frame.h>
#include <aditof/frame_handler.h>
#include <aditof/system.h>
#include <aditof/version.h>
#include <chrono>
#include <command_parser.h>
#include <ctime>
#include <fstream>
#ifdef USE_GLOG
#include <glog/logging.h>
#else
#include <aditof/log.h>
#include <cstring>
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#endif
#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/stat.h>
#endif
enum : uint16_t {
MAX_FILE_PATH_SIZE = 512,
};
using namespace aditof;
#ifdef _WIN32
int main(int argc, char *argv[]);
#endif
static const char kUsagePublic[] =
R"(Data Collect.
Usage:
data_collect
data_collect [--f <folder>] [--n <ncapture>] [--m <mode>] [--wt <warmup>] [--ccb FILE] [--ip <ip>] [--fw <firmware>] [-s | --split] [-t | --netlinktest] [--ic <imager-configuration>] [-scf <save-configuration-file>] [-lcf <load-configuration-file>]
data_collect (-h | --help)
Options:
-h --help Show this screen.
--f <folder> Output folder (max name 512) [default: ./]
--n <ncapture> Capture frame num. [default: 1]
--m <mode> Mode to capture data in. [default: 0]
--wt <warmup> Warmup Time (sec) [default: 0]
--ccb <FILE> The path to store CCB content
--ip <ip> Camera IP
--fw <firmware> Adsd3500 fw file
--split Save each frame into a separate file (Debug)
--netlinktest Puts server on target in test mode (Debug)
--singlethread Store the frame to file using same tread
--ic <imager-configuration> Select imager configuration: standard, standard-raw,
custom, custom-raw. By default is standard.
--scf <save-configuration-file> Save current configuration to json file
--lcf <load-configuration-file> Load configuration from json file
Note: --m argument supports index (0, 1, etc.)
Valid mode (--m) options are:
0: short-range native
1: long-range native
2: short-range Qnative
3: long-range Qnative
4: pcm-native
5: long-range mixed
6: short-range mixed
)";
int main(int argc, char *argv[]) {
std::map<std::string, struct Argument> command_map = {
{"-h", {"--help", false, "", "", false}},
{"-f", {"--f", false, "", ".", true}},
{"-n", {"--n", false, "", "1", true}},
{"-m", {"--m", false, "", "0", true}},
{"-wt", {"--wt", false, "", "0", true}},
{"-ip", {"--ip", false, "", "", true}},
{"-fw", {"--fw", false, "", "", true}},
{"-ccb", {"--ccb", false, "", "", true}},
{"-s", {"--split", false, "", "", false}},
{"-t", {"--netlinktest", false, "", "", false}},
{"-st", {"--singlethread", false, "", "", false}},
{"-ic", {"--ic", false, "", "", false}},
{"-scf", {"--scf", false, "", "", false}},
{"-lcf", {"--lcf", false, "", "", false}}};
CommandParser command;
std::string arg_error;
command.parseArguments(argc, argv, command_map);
int result = command.checkArgumentExist(command_map, arg_error);
if (result != 0) {
LOG(ERROR) << "Argument " << arg_error << " doesn't exist! "
<< "Please check help menu.";
return -1;
}
result = command.helpMenu();
if (result == 1) {
LOG(INFO) << kUsagePublic;
return 0;
} else if (result == -1) {
LOG(ERROR) << "Usage of argument -h/--help"
<< " is incorrect! Help argument should be used alone!";
return -1;
}
result = command.checkValue(command_map, arg_error);
if (result != 0) {
LOG(ERROR) << "Argument: " << command_map[arg_error].long_option
<< " doesn't have assigned or default value!";
LOG(INFO) << kUsagePublic;
return -1;
}
result = command.checkMandatoryArguments(command_map, arg_error);
if (result != 0) {
LOG(ERROR) << "Mandatory argument: " << arg_error << " missing";
LOG(INFO) << kUsagePublic;
return -1;
}
result = command.checkMandatoryPosition(command_map, arg_error);
if (result != 0) {
LOG(ERROR) << "Mandatory argument " << arg_error
<< " is not on its correct position ("
<< command_map[arg_error].position << ").";
LOG(INFO) << kUsagePublic;
return -1;
}
char folder_path[MAX_FILE_PATH_SIZE]; // Path to store the depth frames
char json_file_path
[MAX_FILE_PATH_SIZE]; // Get the .json file from command line
uint16_t err = 0;
uint32_t n_frames = 0;
uint8_t mode = 0;
uint32_t warmup_time = 0;
std::string ip;
std::string firmware;
std::string configuration = "standard";
google::InitGoogleLogging(argv[0]);
FLAGS_alsologtostderr = 1;
LOG(INFO) << "SDK version: " << aditof::getApiVersion()
<< " | branch: " << aditof::getBranchVersion()
<< " | commit: " << aditof::getCommitVersion();
Status status = Status::OK;
// Parsing the arguments from command line
err = snprintf(json_file_path, sizeof(json_file_path), "%s",
command_map["-lcf"].value.c_str());
if (err < 0) {
LOG(ERROR) << "Error copying the json file path!";
return 0;
}
// Parsing output folder
err = snprintf(folder_path, sizeof(folder_path), "%s",
command_map["-f"].value.c_str());
if (err < 0) {
LOG(ERROR) << "Error copying the output folder path!";
return 0;
}
#ifdef _WIN32
// Create folder if not created already
char dir_path[MAX_PATH];
if (GetFullPathName(folder_path, MAX_PATH, &dir_path[0], NULL) == 0) {
LOG(ERROR) << "Error Unable to get directory. Error:" << GetLastError();
return 0;
}
if (!(CreateDirectory(dir_path, NULL))) {
if (ERROR_ALREADY_EXISTS != GetLastError()) {
LOG(ERROR) << "Error creating directory. Error:", GetLastError();
return 0;
}
}
#else
err = mkdir(folder_path, 0777);
if (err < 0) {
LOG(ERROR) << "Unable to create directory";
return 0;
}
#endif
// Parsing number of frames
n_frames = std::stoi(command_map["-n"].value);
if (!command_map["-m"].value.empty()) {
mode = std::stoi(command_map["-m"].value);
}
// Parsing ip
if (!command_map["-ip"].value.empty()) {
ip = command_map["-ip"].value;
}
// Parsing firmware
if (!command_map["-fw"].value.empty()) {
firmware = command_map["-fw"].value;
}
//Parsing Warm up time
if (!command_map["-wt"].value.empty()) {
warmup_time = std::stoi(command_map["-wt"].value);
if (warmup_time < 0) {
LOG(ERROR) << "Invalid warm up time input!";
}
}
//Parsing CCB path
std::string ccbFilePath;
if (!command_map["-ccb"].value.empty()) {
ccbFilePath = command_map["-ccb"].value;
}
//Parsing split option
bool saveToSingleFile = true;
if (!command_map["-s"].value.empty()) {
saveToSingleFile = false;
}
//Parsing single thread option
bool samethread = 0;
if (!command_map["-st"].value.empty()) {
samethread = true;
}
//Parsing netLinkTest option
bool useNetLinkTest = !command_map["-t"].value.empty();
// Parsing configuration option
std::vector<std::string> configurationlist = {"standard", "standard-raw",
"coustom", "custom-raw"};
std::string configurationValue = command_map["-ic"].value;
if (!configurationValue.empty()) {
unsigned int pos =
std::find(configurationlist.begin(), configurationlist.end(),
configurationValue) -
configurationlist.begin();
if (pos < configurationlist.size()) {
configuration = configurationValue;
}
}
bool saveconfigurationFile = false;
std::string saveconfigurationFileValue = command_map["-scf"].value;
if (!saveconfigurationFileValue.empty()) {
if (saveconfigurationFileValue.find(".json") == std::string::npos) {
saveconfigurationFileValue += ".json";
}
saveconfigurationFile = true;
strcpy(json_file_path, "");
}
LOG(INFO) << "Output folder: " << folder_path;
LOG(INFO) << "Mode: " << command_map["-m"].value;
LOG(INFO) << "Number of frames: " << n_frames;
LOG(INFO) << "Json file: " << json_file_path;
LOG(INFO) << "Warm Up Time is: " << warmup_time << " seconds";
LOG(INFO) << "Configuration is: " << configuration;
if (!ip.empty()) {
LOG(INFO) << "Ip address is: " << ip;
}
if (!firmware.empty()) {
LOG(INFO) << "Firmware file is is: " << firmware;
}
if (!ccbFilePath.empty()) {
LOG(INFO) << "Path to store CCB content: " << ccbFilePath;
}
System system;
std::vector<std::shared_ptr<Camera>> cameras;
if (!ip.empty()) {
ip = "ip:" + ip;
if (useNetLinkTest) {
ip += ":netlinktest";
}
system.getCameraList(cameras, ip);
} else {
system.getCameraList(cameras);
}
if (cameras.empty()) {
LOG(WARNING) << "No cameras found";
return 0;
}
auto camera = cameras.front();
status = camera->initialize(json_file_path);
if (status != Status::OK) {
LOG(ERROR) << "Could not initialize camera!";
return 0;
}
status = camera->setSensorConfiguration(configuration);
if (status != Status::OK) {
LOG(INFO) << "Could not configure camera with " << configuration;
} else {
LOG(INFO) << "Configure camera with " << configuration;
}
if (saveconfigurationFile) {
status = camera->saveDepthParamsToJsonFile(saveconfigurationFileValue);
if (status != Status::OK) {
LOG(INFO) << "Could not save current configuration info to "
<< saveconfigurationFileValue;
} else {
LOG(INFO) << "Current configuration info saved to file "
<< saveconfigurationFileValue;
}
}
aditof::CameraDetails cameraDetails;
camera->getDetails(cameraDetails);
LOG(INFO) << "SD card image version: " << cameraDetails.sdCardImageVersion;
LOG(INFO) << "Kernel version: " << cameraDetails.kernelVersion;
LOG(INFO) << "U-Boot version: " << cameraDetails.uBootVersion;
if (!firmware.empty()) {
std::ifstream file(firmware);
if (!(file.good() &&
file.peek() != std::ifstream::traits_type::eof())) {
LOG(ERROR) << firmware << " not found or is an empty file";
return 0;
}
status = camera->adsd3500UpdateFirmware(firmware);
if (status != Status::OK) {
LOG(ERROR) << "Could not update the adsd3500 firmware";
return 0;
} else {
LOG(INFO) << "Please reboot the board!";
return 0;
}
}
// Get modes
std::vector<uint8_t> availableModes;
status = camera->getAvailableModes(availableModes);
if (status != Status::OK || availableModes.empty()) {
LOG(ERROR) << "Could not aquire modes";
return 0;
}
std::shared_ptr<DepthSensorInterface> depthSensor = camera->getSensor();
std::string sensorName;
status = depthSensor->getName(sensorName);
status = camera->setMode(mode);
if (status != Status::OK) {
LOG(ERROR) << "Could not set camera mode!";
return 0;
}
char time_buffer[128];
time_t rawtime;
time(&rawtime);
struct tm timeinfo;
#ifdef _WIN32
localtime_s(&timeinfo, &rawtime);
#else
localtime_r(&rawtime, &timeinfo);
#endif
strftime(time_buffer, sizeof(time_buffer), "%Y%m%d%H%M%S", &timeinfo);
#if 0
camera->setControl("setFPS", std::to_string(setfps));
if (status != Status::OK) {
LOG(ERROR) << "Error setting camera FPS to " << setfps;
return 0;
}
#endif
// Store CCB to file
if (!ccbFilePath.empty()) {
status = camera->saveModuleCCB(ccbFilePath);
if (status != Status::OK) {
LOG(INFO) << "Failed to store CCB to " << ccbFilePath;
}
}
// Program the camera with cfg passed, set the mode by writing to 0x200 and start the camera
status = camera->start();
if (status != Status::OK) {
LOG(ERROR) << "Could not start camera!";
return 0;
}
aditof::Frame frame;
FrameDetails fDetails;
uint64_t elapsed_time;
auto warmup_start = std::chrono::steady_clock::now();
// Wait until the warmup time is finished
if (warmup_time > 0) {
do {
status = camera->requestFrame(&frame);
if (status != Status::OK) {
LOG(ERROR) << "Could not request frame!";
return 0;
}
auto warmup_end = std::chrono::steady_clock::now();
elapsed_time = std::chrono::duration_cast<std::chrono::seconds>(
warmup_end - warmup_start)
.count();
} while (warmup_time >= elapsed_time);
}
FrameHandler frameSaver;
frameSaver.storeFramesToSingleFile(saveToSingleFile);
frameSaver.setOutputFilePath(folder_path);
//drop first frame
status = camera->requestFrame(&frame);
if (status != Status::OK) {
LOG(ERROR) << "Could not request frame!";
return 0;
}
LOG(INFO) << "Requesting " << n_frames << " frames!";
auto start_time = std::chrono::high_resolution_clock::now();
// Request the frames for the respective mode
for (uint32_t loopcount = 0; loopcount < n_frames; loopcount++) {
status = camera->requestFrame(&frame);
if (status != Status::OK) {
LOG(ERROR) << "Could not request frame!";
return 0;
}
if (useNetLinkTest) {
continue;
}
if (!samethread) {
frameSaver.saveFrameToFileMultithread(frame);
} else {
frameSaver.saveFrameToFile(frame);
}
} // End of for Loop
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> total_time = end_time - start_time;
if (total_time.count() > 0.0) {
double measured_fps = (double)n_frames / total_time.count();
LOG(INFO) << "Measured FPS: " << measured_fps;
}
status = camera->stop();
if (status != Status::OK) {
LOG(INFO) << "Error stopping camera!";
}
return 0;
}