$search
00001 00005 #include "streamer.hpp" 00006 00007 #include "cxcore.h" 00008 #include "highgui.h" 00009 00010 int main(int argc, char **argv) { 00011 00012 ros::init(argc, argv, "streamer"); 00013 00014 ros::NodeHandle private_node_handle("~"); 00015 00016 streamerData startupData; 00017 00018 startupData.read_addr = argv[0]; 00019 startupData.read_addr = startupData.read_addr.substr(0, startupData.read_addr.size()-12); 00020 bool inputIsValid = startupData.obtainStartingData(private_node_handle); 00021 00022 if (!inputIsValid) { 00023 ROS_ERROR("Configuration invalid!\n"); 00024 return -1; 00025 } 00026 00027 ros::NodeHandle nh; 00028 00029 ROS_INFO("Establishing streamer node..."); 00030 boost::shared_ptr < streamerNode > streamer_node (new streamerNode (nh, startupData)); 00031 00032 globalNodePtr = &streamer_node; 00033 00034 signal(SIGINT, mySigintHandler); 00035 00036 //streamerNode streamer_node(nh, startupData); 00037 00038 if (wantsToShutdown) { 00039 ros::shutdown(); 00040 00041 return 0; 00042 } 00043 00044 00045 if ((startupData.subscribeMode) || (startupData.resampleMode)) { 00046 streamer_node->runBag(); 00047 } 00048 00049 if (startupData.readMode) { 00050 streamer_node->runRead(); 00051 } 00052 00053 if (startupData.loadMode) { 00054 streamer_node->runLoad(); 00055 } 00056 00057 if ((startupData.captureMode) || (startupData.pollMode)) { 00058 streamer_node->runDevice(); 00059 } 00060 00061 ros::shutdown(); 00062 00063 return 0; 00064 00065 } 00066 00067 void streamerNode::prepareForTermination() { 00068 if (ofs.is_open()) { 00069 ofs.close(); 00070 } 00071 00072 if (ofs_call_log.is_open()) { 00073 ofs_call_log.close(); 00074 } 00075 00076 if (ofs_retrieve_log.is_open()) { 00077 ofs_retrieve_log.close(); 00078 } 00079 00080 if (ofs_internal_log.is_open()) { 00081 ofs_internal_log.close(); 00082 } 00083 00084 if (ofs_write_log.is_open()) { 00085 ofs_write_log.close(); 00086 } 00087 00088 if (ofs_duplicates_log.is_open()) ofs_duplicates_log.close(); 00089 00090 if (ofs_thermistor_log.is_open()) ofs_thermistor_log.close(); 00091 00092 if (configData.serialComms) { 00093 close(mainfd); 00094 } 00095 00096 } 00097 00098 void mySigintHandler(int sig) 00099 { 00100 // Do some custom action. 00101 // For example, publish a stop message to some other nodes. 00102 00103 ROS_WARN("Requested shutdown... terminating feeds..."); 00104 wantsToShutdown = true; 00105 00106 00107 (*globalNodePtr)->prepareForTermination(); 00108 00109 00110 00111 //shutdown(); 00112 00113 // All the default sigint handler does is call shutdown() 00114 00115 } 00116 00117 bool streamerNode::setupDevice() { 00118 00119 if (configData.verboseMode) { ROS_INFO("Entered setupDevice()..."); } 00120 00121 colourMat.release(); 00122 00123 if ((configData.inputDatatype == DATATYPE_8BIT) || (configData.inputDatatype == DATATYPE_MM)) { 00124 00125 ROS_INFO("Setting up device in 8-bit/MM mode..."); 00126 getVideoCapture()->open(device_num); 00127 } else if (configData.inputDatatype == DATATYPE_RAW) { 00128 ROS_INFO("Setting up device in 16-bit mode..."); 00129 00130 int deviceWidth, deviceHeight; 00131 getMainVideoSource()->setup_video_capture(configData.capture_device.c_str(), deviceWidth, deviceHeight, configData.verboseMode); 00132 00133 // Now use this opportunity to test/correct? 00134 00135 if ((!configData.imageDimensionsSpecified) && (!configData.intrinsicsProvided)) { 00136 // Use these values.. 00137 ROS_INFO("Using image size learned from device initialization (%d, %d)", deviceWidth, deviceHeight); 00138 globalCameraInfo.imageSize.at<unsigned short>(0, 0) = deviceWidth; 00139 globalCameraInfo.imageSize.at<unsigned short>(0, 1) = deviceHeight; 00140 globalCameraInfo.cameraSize = Size(globalCameraInfo.imageSize.at<unsigned short>(0, 0), globalCameraInfo.imageSize.at<unsigned short>(0, 1)); 00141 00142 overwriteCameraDims(); 00143 00144 } else { 00145 // Compare the values to what you are using, and produce a warning if necessary... 00146 00147 if ((globalCameraInfo.cameraSize.width != deviceWidth) || (globalCameraInfo.cameraSize.height != deviceHeight)) { 00148 ROS_WARN("Device-based image size estimates (%d, %d) conflict with provided image size (%d, %d)", deviceWidth, deviceHeight, globalCameraInfo.cameraSize.width, globalCameraInfo.cameraSize.height); 00149 } 00150 00151 } 00152 00153 } 00154 00155 ROS_INFO("Device set up!"); 00156 00157 setValidity(true); 00158 00159 return true; 00160 } 00161 00162 void streamerNode::releaseDevice() { 00163 00164 if ((isVideoValid()) && (configData.verboseMode)) { ROS_WARN("setValidity(false) : releaseDevice()"); } 00165 setValidity(false); 00166 00167 if ((configData.inputDatatype == DATATYPE_8BIT) || (configData.inputDatatype == DATATYPE_MM)) { 00168 getVideoCapture()->release(); 00169 } else if (configData.inputDatatype == DATATYPE_RAW) { 00170 00171 getMainVideoSource()->close_video_capture(); 00172 00173 } 00174 } 00175 00176 00177 bool streamerNode::runDevice() { 00178 00179 device_num = atoi(&(configData.capture_device.c_str(), configData.capture_device.at(configData.capture_device.length()-1))); 00180 00181 if (configData.captureMode) { 00182 ROS_INFO("Video stream (device: %d) started...", device_num); 00183 } else if (configData.pollMode) { 00184 ROS_INFO("Video polling (device: %d) started...", device_num); 00185 } 00186 00187 setupDevice(); 00188 00189 while (isVideoValid()) { 00190 if (configData.verboseMode){ ROS_INFO("Starting loop.."); } 00191 if (configData.captureMode) { 00192 if (configData.verboseMode){ ROS_INFO("About to spin"); } 00193 ros::spinOnce(); 00194 if (configData.verboseMode){ ROS_INFO("Spun"); } 00195 if (streamCallback()) { 00196 00197 if (configData.verboseMode){ ROS_INFO("About to process"); } 00198 if (processImage()) { 00199 00200 if (configData.verboseMode){ ROS_INFO("Processed image."); } 00201 00202 if (readyToPublish) { 00203 if (configData.verboseMode){ ROS_INFO("About to publish topics..."); } 00204 publishTopics(); 00205 if (configData.verboseMode){ ROS_INFO("Topics published."); } 00206 writeData(); 00207 if (configData.verboseMode){ ROS_INFO("Data written."); } 00208 } 00209 } 00210 } 00211 00212 } else if (configData.pollMode) { 00213 00214 // Want to keep on calling streamCallback until the time is right to capture the frame 00215 streamCallback(false); 00216 ros::spinOnce(); 00217 00218 } 00219 if (configData.verboseMode){ ROS_INFO("Ending loop."); }; 00220 } 00221 00222 ROS_WARN("About to release device here..."); 00223 releaseDevice(); 00224 00225 if (configData.captureMode) { 00226 ROS_INFO("Video capture terminating..."); 00227 } else if (configData.pollMode) { 00228 ROS_INFO("Video polling terminating..."); 00229 } 00230 00231 return true; 00232 } 00233 00234 bool streamerNode::runLoad() { 00235 ROS_INFO("Image load started..."); 00236 00237 if (!processFolder()) { 00238 ROS_ERROR("Processing of folder failed..."); 00239 return false; 00240 } 00241 00242 do { 00243 00244 frameCounter = 0; 00245 setValidity(true); 00246 00247 while (isVideoValid()) { 00248 ros::spinOnce(); 00249 } 00250 00251 } while (configData.loopFlag && !wantsToShutdown); 00252 00253 return true; 00254 00255 } 00256 00257 bool streamerNode::runRead() { 00258 00259 ROS_INFO("Video reading started..."); 00260 00261 do { 00262 00263 setValidity(true); 00264 00265 ROS_WARN("Opening file (%s)...", configData.filename.c_str()); 00266 if (configData.inputDatatype == DATATYPE_RAW) { 00267 if (getMainVideoSource()->setup_video_file(configData.filename) < 0) { 00268 ROS_ERROR("Source configuration failed."); 00269 } 00270 } else if ((configData.inputDatatype == DATATYPE_8BIT) || (configData.inputDatatype == DATATYPE_MM)) { 00271 getVideoCapture()->open(configData.filename.c_str()); 00272 00273 if(!cap.isOpened()) { // check if we succeeded 00274 ROS_ERROR("File open failed (using OpenCV)."); 00275 } 00276 //capture = cvCaptureFromAVI(configData.filename.c_str()); 00277 } 00278 00279 ROS_WARN("Source configured."); 00280 00281 while (isVideoValid()) { 00282 ros::spinOnce(); 00283 } 00284 00285 ROS_WARN("Video complete."); 00286 00287 if (configData.inputDatatype == DATATYPE_RAW) { 00288 getMainVideoSource()->close_video_file(configData.filename); 00289 } else if ((configData.inputDatatype == DATATYPE_8BIT) || (configData.inputDatatype == DATATYPE_MM)) { 00290 getVideoCapture()->release(); 00291 } 00292 00293 } while (configData.loopFlag && !wantsToShutdown); 00294 00295 ROS_INFO("Video reading terminating..."); 00296 00297 return true; 00298 00299 } 00300 00301 bool streamerNode::runBag() { 00302 00303 if (configData.subscribeMode) { 00304 ROS_INFO("Subscription started..."); 00305 } else if (configData.resampleMode) { 00306 ROS_INFO("Resampling subscription started..."); 00307 } 00308 00309 while (isVideoValid()) { 00310 00311 ros::spinOnce(); 00312 00313 } 00314 00315 if (configData.subscribeMode) { 00316 ROS_INFO("Subscription terminating..."); 00317 } else if (configData.resampleMode) { 00318 ROS_INFO("Resampling subscription terminating..."); 00319 } 00320 00321 return true; 00322 } 00323 00324 00325 bool streamerNode::processFolder() { 00326 00327 DIR * dirp; 00328 struct dirent * entry; 00329 00330 dirp = opendir(configData.folder.c_str()); 00331 00332 if (dirp == NULL) { 00333 ROS_ERROR("Opening of directory (%s) failed.", configData.folder.c_str()); 00334 return false; 00335 } 00336 00337 while ((entry = readdir(dirp)) != NULL) { 00338 if (entry->d_type == DT_REG) { // If the entry is a regular file 00339 inputList.push_back(string(entry->d_name)); 00340 fileCount++; 00341 } 00342 } 00343 00344 closedir(dirp); 00345 00346 sort(inputList.begin(), inputList.end()); 00347 00348 if(fileCount == -1) { 00349 ROS_ERROR("File counting error.\n"); 00350 return false; 00351 } 00352 00353 ROS_INFO("No. of images in folder = %d\n", fileCount); 00354 00355 if (fileCount == 0) { 00356 ROS_ERROR("Returning, because no images are in folder.\n"); 00357 return false; 00358 } 00359 00360 return true; 00361 } 00362 00363 void streamerNode::markCurrentFrameAsDuplicate() { 00364 00365 //camera_info.binning_x = 1; // this one is used for thermistor 00366 camera_info.binning_y = 1; // this one is to be used for duplicates 00367 } 00368 00369 void streamerNode::updateCameraInfo() { 00370 00371 00372 int frameIndex; 00373 ros::Time currTime; 00374 00375 unsigned int bx, by; 00376 00377 if (configData.loadMode) { 00378 // TODO: loadMode: use image timestamp 00379 frameIndex = frameCounter-1; 00380 currTime = ros::Time::now(); 00381 bx = 0; 00382 by = 0; 00383 } else if (configData.readMode) { 00384 // TODO: readMode: use video timestamp 00385 frameIndex = frameCounter-1; 00386 currTime = ros::Time::now(); 00387 bx = 0; 00388 by = 0; 00389 } else if (configData.resampleMode) { 00390 frameIndex = frameCounter-1; 00391 currTime = original_time; 00392 bx = original_bx; 00393 by = original_by; 00394 } else if (configData.subscribeMode) { 00395 frameIndex = frameCounter-1; 00396 currTime = original_time; 00397 bx = original_bx; 00398 by = original_by; 00399 } else if (configData.captureMode) { 00400 frameIndex = frameCounter-1; 00401 currTime = ros::Time::now(); 00402 bx = (unsigned int) (internal_time & 0xffffffffUL); 00403 by = (unsigned int) (internal_time >> 32); 00404 } else if (configData.pollMode) { 00405 frameIndex = frameCounter-1; 00406 currTime = ros::Time::now(); 00407 bx = (unsigned int) (internal_time & 0xffffffffUL); 00408 by = (unsigned int) (internal_time >> 32); 00409 } 00410 00411 camera_info.header.stamp = currTime; 00412 msg_color.header.stamp = currTime; 00413 msg_16bit.header.stamp = currTime; 00414 msg_8bit.header.stamp = currTime; 00415 00416 // Use thermistor value: 00417 00418 if (configData.readThermistor) { 00419 memcpy(&camera_info.binning_x, &lastThermistorReading, sizeof(float)); 00420 } 00421 00422 memcpy(&camera_info.R[0], &firmwareTime, sizeof(float)); 00423 00424 camera_info.binning_y = 0; 00425 00426 } 00427 00428 void streamerNode::assignCameraInfo() { 00429 00430 ROS_INFO("Entered assignCameraInfo()..."); 00431 00432 char frame_id[256]; 00433 sprintf(frame_id, "%s_%s_%s", "thermalvis", nodeName, "optical_frame"); 00434 camera_info.header.frame_id = string(frame_id); 00435 msg_color.header.frame_id = string(frame_id); 00436 msg_16bit.header.frame_id = string(frame_id); 00437 msg_8bit.header.frame_id = string(frame_id); 00438 00439 camera_info.height = globalCameraInfo.imageSize.at<unsigned short>(0, 1); // DEFAULT_IMAGE_HEIGHT 00440 camera_info.width = globalCameraInfo.imageSize.at<unsigned short>(0, 0); // DEFAULT_IMAGE_WIDTH 00441 00442 00443 /* use data from extrinsics file 00444 if (globalExtrinsicsData.distCoeffs0.cols != 5) { //*/ 00445 00446 // /* use data from intrinsics file 00447 if (globalCameraInfo.distCoeffs.cols != 5) { //*/ 00448 00449 camera_info.distortion_model = "rational_polynomial"; 00450 ROS_INFO("Camera model : RATIONAL POLYNOMIAL - (%d) coeffs", globalCameraInfo.distCoeffs.cols); 00451 } else { 00452 camera_info.distortion_model = "plumb_bob"; 00453 ROS_INFO("Camera model : PLUMB BOB - (%d) coeffs", globalCameraInfo.distCoeffs.cols); 00454 } 00455 00456 camera_info.D.clear(); 00457 00458 00459 // /* use data from intrinsics file 00460 for (int iii = 0; iii < globalCameraInfo.distCoeffs.cols; iii++) { //orig 00461 camera_info.D.push_back(globalCameraInfo.distCoeffs.at<double>(0, iii)); //orig 00462 } 00463 00464 /* use data from extrinsics file 00465 for (int iii = 0; iii < globalExtrinsicsData.distCoeffs0.cols; iii++) { 00466 if (configData.camera_number==0){ 00467 camera_info.D.push_back(globalExtrinsicsData.distCoeffs0.at<double>(0, iii)); 00468 }else if(configData.camera_number==1){ 00469 camera_info.D.push_back(globalExtrinsicsData.distCoeffs1.at<double>(0, iii)); 00470 } 00471 } 00472 //*/ 00473 00474 00476 if (globalCameraInfo.cameraMatrix.rows == 3) { 00477 for (unsigned int iii = 0; iii < 3; iii++) { 00478 for (unsigned int jjj = 0; jjj < 3; jjj++) { 00479 camera_info.K[iii*3 + jjj] = globalCameraInfo.cameraMatrix.at<double>(iii,jjj); //orig 00480 } 00481 } 00482 } // */ 00483 00484 /* use data from extrinsics file 00485 if (globalCameraInfo.cameraMatrix.rows == 3) { 00486 for (unsigned int iii = 0; iii < 3; iii++) { 00487 for (unsigned int jjj = 0; jjj < 3; jjj++) { 00488 if (configData.camera_number==0){ 00489 camera_info.K[iii*3 + jjj] = globalExtrinsicsData.cameraMatrix0.at<double>(iii,jjj); 00490 }else if(configData.camera_number==1){ 00491 camera_info.K[iii*3 + jjj] = globalExtrinsicsData.cameraMatrix1.at<double>(iii,jjj); 00492 } 00493 } 00494 } 00495 } // */ 00496 00497 00498 00499 //HGH 00500 if (configData.wantsToAddExtrinsics){ 00501 if (configData.camera_number == 0){ 00502 for (unsigned int iii = 0; iii < 3; iii++) { 00503 for (unsigned int jjj = 0; jjj < 3; jjj++) { 00504 camera_info.R[iii*3 + jjj] = globalExtrinsicsData.R0.at<double>(iii,jjj); 00505 } 00506 } 00507 for (unsigned int iii = 0; iii < 3; iii++) { 00508 for (unsigned int jjj = 0; jjj < 4; jjj++) { 00509 camera_info.P[iii*4 + jjj] = globalExtrinsicsData.P0.at<double>(iii,jjj); 00510 } 00511 } 00512 }else if (configData.camera_number == 1){ 00513 for (unsigned int iii = 0; iii < 3; iii++) { 00514 for (unsigned int jjj = 0; jjj < 3; jjj++) { 00515 camera_info.R[iii*3 + jjj] = globalExtrinsicsData.R1.at<double>(iii,jjj); 00516 } 00517 } 00518 for (unsigned int iii = 0; iii < 3; iii++) { 00519 for (unsigned int jjj = 0; jjj < 4; jjj++) { 00520 camera_info.P[iii*4 + jjj] = globalExtrinsicsData.P1.at<double>(iii,jjj); 00521 } 00522 } 00523 } 00524 00525 } else { 00526 if (globalCameraInfo.R.rows == 3) { 00527 for (unsigned int iii = 0; iii < 3; iii++) { 00528 for (unsigned int jjj = 0; jjj < 3; jjj++) { 00529 camera_info.R[iii*3 + jjj] = globalCameraInfo.R.at<double>(iii,jjj); 00530 } 00531 } 00532 } 00533 00534 if (globalCameraInfo.newCamMat.rows == 3) { 00535 for (unsigned int iii = 0; iii < 3; iii++) { 00536 for (unsigned int jjj = 0; jjj < 3; jjj++) { 00537 camera_info.P[iii*4 + jjj] = globalCameraInfo.newCamMat.at<double>(iii,jjj); 00538 } 00539 } 00540 } 00541 } 00542 00543 00544 if (configData.wantsToUndistort) { 00545 if ((globalCameraInfo.cameraMatrix.rows == 3) && (globalCameraInfo.distCoeffs.cols > 0) && (globalCameraInfo.newCamMat.rows == 3)) { 00546 //HGH initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.R, globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 00547 //HGH 00548 if (configData.wantsToAddExtrinsics){ 00549 if (configData.wantsToRectify){ 00550 if (configData.camera_number == 0){ 00551 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalExtrinsicsData.R0, globalExtrinsicsData.P0, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 00552 }else if (configData.camera_number == 1){ 00553 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalExtrinsicsData.R1, globalExtrinsicsData.P1, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 00554 } 00555 }else{ 00556 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, Mat(), globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 00557 } 00558 }else{ 00559 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, Mat(), globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 00560 } 00561 00562 } 00563 } 00564 00565 ROS_INFO("Camera info assigned."); 00566 00567 } 00568 00569 //HGH 00570 void streamerNode::updateCameraInfoExtrinsics() { 00571 ROS_INFO("Updating camera info..."); 00572 if (configData.camera_number == 0){ 00573 for (unsigned int iii = 0; iii < 3; iii++) { 00574 for (unsigned int jjj = 0; jjj < 4; jjj++) { 00575 camera_info.P[iii*4 + jjj] = globalExtrinsicsData.P0.at<double>(iii,jjj); 00576 } 00577 } 00578 }else if (configData.camera_number == 1){ 00579 for (unsigned int iii = 0; iii < 3; iii++) { 00580 for (unsigned int jjj = 0; jjj < 4; jjj++) { 00581 camera_info.P[iii*4 + jjj] = globalExtrinsicsData.P1.at<double>(iii,jjj); 00582 } 00583 } 00584 } 00585 ROS_INFO("Camera info updated."); 00586 } 00587 00588 bool streamerNode::setCameraInfo(sensor_msgs::SetCameraInfo::Request &req, sensor_msgs::SetCameraInfo::Response &rsp) { 00589 00590 camera_info = req.camera_info; 00591 00592 if (configData.verboseMode) { ROS_INFO("calling assignCameraInfo() from setCameraInfo()..."); } 00593 assignCameraInfo(); 00594 00595 if (camera_calibration_parsers::writeCalibrationIni("../camera_parameters.txt", "gscam", camera_info)) { 00596 ROS_INFO("Camera information written to camera_parameters.txt"); 00597 return true; 00598 } 00599 else { 00600 ROS_ERROR("Could not write camera_parameters.txt"); 00601 return false; 00602 } 00603 } 00604 00605 bool streamerNode::streamCallback(bool capture) { 00606 00607 int currAttempts = 0; 00608 00609 if (configData.verboseMode){ ROS_INFO("Entered callback."); } 00610 if ((configData.inputDatatype == DATATYPE_8BIT) || (configData.inputDatatype == DATATYPE_MM)) { 00611 if (configData.verboseMode){ ROS_INFO("Updating camera info..."); } 00612 updateCameraInfo(); 00613 if (configData.verboseMode){ ROS_INFO("Camera info updated."); } 00614 ofs_call_log << ros::Time::now().toNSec() << endl; 00615 if (configData.verboseMode){ ROS_INFO("Capturing frame (8-bit/MM)..."); } 00616 cap >> frame; 00617 if (configData.verboseMode){ ROS_INFO("Frame captured."); } 00618 ofs_retrieve_log << ros::Time::now().toNSec() << endl; 00619 } else if (configData.inputDatatype == DATATYPE_RAW) { 00620 00621 ros::Time callTime, retrieveTime; 00622 00623 callTime = ros::Time::now(); 00624 if (configData.verboseMode){ ROS_INFO("Capturing frame (16-bit)..."); } 00625 00626 bool frameRead = false; 00627 while ((configData.maxReadAttempts == 0) || (currAttempts <= configData.maxReadAttempts)) { 00628 // Keep on looping, but if max defined, only until curr attempts is high enough 00629 00630 if (configData.verboseMode){ ROS_INFO("Attempting to capture frame..."); } 00631 00632 if (av_read_frame(mainVideoSource->pIFormatCtx, &(mainVideoSource->oPacket)) != 0) { 00633 if (configData.verboseMode){ ROS_WARN("av_read_frame() failed."); } 00634 currAttempts++; 00635 continue; 00636 } 00637 00638 if (configData.verboseMode){ ROS_INFO("Frame captured successfully."); } 00639 00640 retrieveTime = ros::Time::now(); 00641 firmwareTime = mainVideoSource->oPacket.pts; 00642 00643 if (configData.verboseMode){ ROS_INFO("Updating camera info..."); } 00644 updateCameraInfo(); 00645 if (configData.verboseMode){ ROS_INFO("Camera info updated."); } 00646 00647 if (mainVideoSource->bRet < 0) { 00648 if (configData.verboseMode) { ROS_WARN("(mainVideoSource->bRet < 0) failed."); } 00649 currAttempts++; 00650 continue; 00651 } 00652 00653 if (mainVideoSource->oPacket.stream_index != mainVideoSource->ixInputStream) { 00654 if (configData.verboseMode) { ROS_WARN("(mainVideoSource->oPacket.stream_index != mainVideoSource->ixInputStream) failed."); } 00655 currAttempts++; 00656 continue; 00657 } 00658 00659 if (configData.verboseMode){ ROS_INFO("Decoding frame..."); } 00660 avcodec_decode_video2(mainVideoSource->pICodecCtx, mainVideoSource->pFrame, &(mainVideoSource->fFrame),&(mainVideoSource->oPacket)); 00661 if (configData.verboseMode){ ROS_INFO("Frame decoded."); } 00662 00663 av_free_packet(&(mainVideoSource->oPacket)); 00664 if (configData.verboseMode){ ROS_INFO("Frame freed."); } 00665 00666 if (!(mainVideoSource->fFrame)) { 00667 if (configData.verboseMode) { ROS_WARN("(!(mainVideoSource->fFrame)) failed."); } 00668 currAttempts++; 00669 continue; 00670 } 00671 00672 if (capture) { 00673 if (configData.verboseMode){ ROS_INFO("Accepting image..."); } 00674 acceptImage((void*) *(mainVideoSource->pFrame->data)); 00675 if (configData.verboseMode){ ROS_INFO("Image accepted."); } 00676 00677 char outbuff[256]; 00678 00679 uint32_t internal_sec, internal_nsec; 00680 00681 internal_sec = firmwareTime / 1000000; 00682 internal_nsec = (firmwareTime % 1000000) * 1000; 00683 00684 //sprintf(outbuff, "%016d000", firmwareTime); 00685 sprintf(outbuff, "%010d.%09d", internal_sec, internal_nsec); 00686 00687 if (configData.wantsToDumpTimestamps) { 00688 ofs_internal_log << outbuff << endl; 00689 //ofs_retrieve_log << retrieveTime.toNSec() << endl; 00690 //ofs_retrieve_log << retrieveTime.sec << "." << retrieveTime.nsec << endl; 00691 char output_time[256]; 00692 sprintf(output_time,"%010d.%09d", retrieveTime.sec, retrieveTime.nsec); 00693 ofs_retrieve_log << output_time << endl; 00694 ofs_call_log << callTime.toNSec() << endl; 00695 } 00696 00697 } 00698 00699 // Want to exit loop if it actually worked 00700 if (configData.verboseMode){ ROS_INFO("Frame read."); } 00701 break; 00702 00703 } 00704 00705 if (currAttempts >= 1) { 00706 ROS_WARN("Frame reading required (%d) additional attempt.", currAttempts); 00707 } 00708 00709 if (currAttempts > configData.maxReadAttempts) { 00710 ROS_ERROR("Frame reading failed after (%d) attempts.", currAttempts); 00711 setValidity(false); 00712 return false; 00713 } 00714 } 00715 00716 // processImage(); 00717 00718 //ROS_INFO("Exiting callback."); 00719 if (configData.verboseMode){ ROS_INFO("Exiting callback..."); } 00720 00721 return true; 00722 } 00723 00724 void streamerNode::acceptImage(void *ptr) { 00725 00726 if (configData.inputDatatype == DATATYPE_RAW) { 00727 if ((frame.rows == 0) || (frame.type() != CV_16UC1)) { 00728 frame = Mat::zeros(camera_info.height, camera_info.width, CV_16UC1); 00729 } 00730 00731 if (configData.verboseMode){ ROS_INFO("Copying image data to internal matrix... (%d, %d)", camera_info.width, camera_info.height); } 00732 memcpy(&(frame.at<unsigned char>(0,0)), ptr, camera_info.width*camera_info.height*2); 00733 if (configData.verboseMode){ ROS_INFO("Data copied."); } 00734 00735 if (configData.fixDudPixels) { 00736 if (configData.verboseMode){ ROS_INFO("Fixing dud pixels..."); } 00737 fix_bottom_right(frame); 00738 if (configData.verboseMode){ ROS_INFO("Dud pixels fixed."); } 00739 } 00740 00741 } else if (configData.inputDatatype == DATATYPE_8BIT) { 00742 if ((frame.rows == 0) || (frame.type() != CV_8UC1)) { 00743 frame = Mat::zeros(camera_info.height, camera_info.width, CV_8UC1); 00744 } 00745 00746 if (configData.verboseMode){ ROS_INFO("Copying image data to internal matrix.... (%d, %d)", camera_info.width, camera_info.height); } 00747 memcpy(&(frame.at<unsigned char>(0,0)), ptr, camera_info.width*camera_info.height); 00748 if (configData.verboseMode){ ROS_INFO("Data copied."); } 00749 00750 } else if (configData.inputDatatype == DATATYPE_MM){ 00751 if ((frame.rows == 0) || (frame.type() != CV_8UC3)) { 00752 frame = Mat::zeros(camera_info.height, camera_info.width, CV_8UC3); 00753 } 00754 00755 if (configData.verboseMode){ ROS_INFO("Copying image data to internal matrix... (%d, %d)", camera_info.width, camera_info.height); } 00756 memcpy(&(frame.at<unsigned char>(0,0)), ptr, camera_info.width*camera_info.height*3); 00757 if (configData.verboseMode){ ROS_INFO("Data copied."); } 00758 } 00759 00760 00761 00762 } 00763 00764 bool streamerNode::processImage() { 00765 00766 if (frame.rows == 0) { 00767 return false; 00768 } 00769 00770 if (configData.wantsToResize) { 00771 resize(frame, rzMat, Size(configData.desiredCols, configData.desiredRows)); 00772 frame = Mat(rzMat); 00773 } 00774 00775 if (configData.wantsToRemoveDuplicates || configData.wantsToMarkDuplicates || configData.wantsToOutputDuplicates) { 00776 00777 if (matricesAreEqual(frame, lastFrame)) { 00778 00779 if (configData.wantsToMarkDuplicates) { 00780 markCurrentFrameAsDuplicate(); 00781 } 00782 00783 //ROS_INFO("SHOULD GET HERE A."); 00784 if (configData.wantsToOutputDuplicates) { 00785 //ROS_INFO("IS IT WRITING HERE? A"); 00786 ofs_duplicates_log << "1" << endl; 00787 } else { 00788 //ROS_INFO("WHY HERE? A"); 00789 } 00790 // 00791 00792 if (configData.wantsToRemoveDuplicates) { 00793 if (configData.loadMode) { 00794 frameCounter++; 00795 } 00796 return false; 00797 } 00798 00799 } else { 00800 //ROS_ERROR("Not omitting..."); 00801 00802 //ROS_INFO("SHOULD GET HERE."); 00803 if (configData.wantsToOutputDuplicates) { 00804 //ROS_INFO("IS IT WRITING HERE?"); 00805 ofs_duplicates_log << "0" << endl; 00806 } else { 00807 //ROS_INFO("WHY HERE? B"); 00808 } 00809 00810 } 00811 00812 frame.copyTo(lastFrame); 00813 00814 } 00815 00816 00817 if (configData.readThermistor) { 00818 //ROS_WARN("Writing thermistor value... (%f)", lastThermistorReading); 00819 //ofs_thermistor_log << lastThermistorReading << endl; 00820 } 00821 00822 00823 //HGH 00824 //ROS_INFO("Processing image (%d)...", frameCounter); 00825 if (configData.verboseMode){ROS_INFO("Processing image (%d)...", frameCounter);} 00826 00827 00828 if (pastMeanIndex >= (configData.maxPastMeans-1)) { 00829 pastMeanIndex = 0; 00830 } else { 00831 pastMeanIndex++; 00832 } 00833 00834 if (configData.inputDatatype == DATATYPE_RAW) { 00835 00836 _16bitMat = Mat(frame); 00837 00838 00839 if ((configData.outputColorFlag) || (configData.output8bitFlag) || ((configData.wantsToWrite) && ((configData.outputType == "CV_8UC3") || (configData.outputType == "CV_8UC1")) )) { 00840 //printf("%s << Applying adaptiveDownsample ... (%d)\n", __FUNCTION__, configData.normMode); 00841 00842 adaptiveDownsample(_16bitMat, preFilteredMat, configData.normMode, configData.normFactor); //, configData.filterMode); 00843 00844 } 00845 00846 00847 } else if (configData.inputDatatype == DATATYPE_8BIT) { 00848 00849 00850 //ROS_WARN("Entered.. 2"); 00851 00852 if (frame.channels() == 3) { 00853 00854 //ROS_WARN("Entered.. X"); 00855 00856 if (firstFrame) { 00857 isActuallyGray = checkIfActuallyGray(frame); 00858 firstFrame = false; 00859 00860 if (configData.forceInputGray) { 00861 isActuallyGray = true; 00862 ROS_WARN("Forcing input images to be considered gray."); 00863 } 00864 } 00865 00866 } 00867 00868 if ((frame.channels() == 1) || (isActuallyGray)) { 00869 00870 if (frame.channels() == 1) { 00871 workingFrame = Mat(frame); 00872 } else if (isActuallyGray) { 00873 if (((configData.outputColorFlag) || (configData.outputType == "CV_8UC3")) || ((configData.output8bitFlag) || (configData.outputType == "CV_8UC1"))) { 00874 cvtColor(frame, workingFrame, CV_RGB2GRAY); 00875 } 00876 } 00877 00878 //ROS_WARN("Processing..."); 00879 00880 // Need to normalize if appropriate 00881 process8bitImage(workingFrame, preFilteredMat, configData.normMode, configData.normFactor); 00882 00883 } else if (frame.channels() == 3) { 00884 00885 colourMat = Mat(frame); 00886 00887 if ((configData.output8bitFlag) || (configData.outputType == "CV_8UC1")) { 00888 cvtColor(colourMat, preFilteredMat, CV_RGB2GRAY); 00889 } 00890 00891 } 00892 00893 } else if (configData.inputDatatype == DATATYPE_MM) { 00894 00895 //ROS_WARN("Entered.. 3"); 00896 00897 if (frame.channels() != 3) { 00898 00899 ROS_ERROR("Frames must have 3 channels to be used for multi-modal fusion."); 00900 00901 if (firstFrame) { 00902 isActuallyGray = false; 00903 firstFrame = false; 00904 } 00905 00906 } else { 00907 00908 //ROS_ERROR("Processing 3-channel image as an MM..."); 00909 00910 // This is where you'll break the image apart and perform fusion... 00911 00912 Mat thermal, visible; 00913 00914 splitMultimodalImage(frame, thermal, visible); 00915 00916 double fusion_params[2]; 00917 fusion_params[0] = max(min(0.5, 0.5 - (fusionFactor/2.0)), 0.0); 00918 fusion_params[1] = max(min(0.5, 1.0 - (fusionFactor/2.0)), 1.0); 00919 00920 colourMap.fuse_image(thermal, visible, colourMat, fusion_params); 00921 00922 00923 if ((configData.output8bitFlag) || (configData.outputType == "CV_8UC1")) { 00924 cvtColor(colourMat, preFilteredMat, CV_RGB2GRAY); 00925 } 00926 00927 } 00928 00929 } 00930 00931 if (configData.filterMode > 0) { 00932 applyFilter(preFilteredMat, smoothedMat, configData.filterMode, configData.filterParam); 00933 } else { 00934 smoothedMat = preFilteredMat; 00935 } 00936 00937 if (configData.temporalSmoothing) { 00938 if (((configData.outputColorFlag) || ((configData.wantsToWrite) && (configData.outputType == "CV_8UC3"))) || ((configData.output8bitFlag) || ((configData.wantsToWrite) && (configData.outputType == "CV_8UC1")))) { 00939 // If you want to output any kind of 8-bit format... 00940 00941 Scalar means = mean(smoothedMat); 00942 00943 pastMeans[pastMeanIndex] = means[0]; 00944 00945 //ROS_WARN("mean = (%f)", pastMeans[pastMeanIndex]); 00946 00947 double temporalMean = 0.0; 00948 00949 for (int iii = 0; iii < min(frameCounter+1, configData.maxPastMeans); iii++) { 00950 00951 temporalMean += pastMeans[iii]; 00952 00953 } 00954 00955 temporalMean /= min(frameCounter+1, configData.maxPastMeans); 00956 00957 //ROS_WARN("temporalMean = (%f)", temporalMean); 00958 00959 // sign gives temporal vs mean 00960 // 00961 shiftDiff = (((temporalMean - pastMeans[pastMeanIndex]) > 0.0) ? 1.0 : (((temporalMean - pastMeans[pastMeanIndex]) < 0.0) ? -1.0 : 0.0)) * min(abs((pastMeans[pastMeanIndex] - temporalMean)), configData.maxIntensityChange); 00962 00963 _8bitMat = smoothedMat + shiftDiff; 00964 00965 Scalar meanA = mean(_8bitMat); 00966 //ROS_WARN("8-bit mean = (%f)", meanA[0]); 00967 00968 } 00969 00970 } else { 00971 _8bitMat = smoothedMat; 00972 } 00973 00974 if ((configData.inputDatatype != DATATYPE_MM) && ((configData.inputDatatype != DATATYPE_8BIT) || (frame.channels() != 3) || isActuallyGray)) { 00975 //if (1) { 00976 // If it wasn't a 3-channel 8-bit image to start with 00977 //ROS_ERROR("There..."); 00978 //imshow("x", _8bitMat); 00979 //waitKey(1); 00980 00981 if ((configData.outputColorFlag) || ((configData.wantsToWrite) && (configData.outputType == "CV_8UC3"))) { 00982 // And if you want color output 00983 00984 //ROS_INFO("Entered..."); 00985 00986 colourMap.falsify_image(_8bitMat, colourMat, configData.mapParam); 00987 00988 } 00989 } 00990 00991 frameCounter++; 00992 00993 if (!readyToPublish) { 00994 readyToPublish = true; 00995 } 00996 00997 return true; 00998 00999 } 01000 01001 void streamerNode::initializeMessages() { 01002 01003 01004 if (configData.output16bitFlag) { 01005 if (msg_16bit.width == 0) { 01006 if (_16bitMat.rows != 0) { 01007 msg_16bit.width = _16bitMat.cols; 01008 msg_16bit.height = _16bitMat.rows; 01009 msg_16bit.encoding = "mono16"; 01010 msg_16bit.is_bigendian = false; 01011 msg_16bit.step = _16bitMat.cols*2; 01012 msg_16bit.data.resize(_16bitMat.cols*_16bitMat.rows*2); 01013 } 01014 } 01015 01016 } 01017 01018 if (configData.output8bitFlag) { 01019 if (msg_8bit.width == 0) { 01020 if (_8bitMat.rows != 0) { 01021 msg_8bit.width = _8bitMat.cols; 01022 msg_8bit.height = _8bitMat.rows; 01023 msg_8bit.encoding = "mono8"; 01024 msg_8bit.is_bigendian = false; 01025 msg_8bit.step = _8bitMat.cols*1; 01026 msg_8bit.data.resize(_8bitMat.cols*_8bitMat.rows*1); 01027 } 01028 } 01029 } 01030 01031 if (configData.outputColorFlag) { 01032 if (msg_color.width == 0) { 01033 if (colourMat.rows != 0) { 01034 msg_color.width = colourMat.cols; 01035 msg_color.height = colourMat.rows; 01036 msg_color.encoding = "bgr8"; 01037 msg_color.is_bigendian = false; 01038 msg_color.step = colourMat.cols*3; 01039 msg_color.data.resize(colourMat.cols*colourMat.rows*3); 01040 } 01041 } 01042 01043 } 01044 } 01045 01046 void streamerNode::publishTopics() { 01047 01048 01049 initializeMessages(); 01050 01051 01052 /* 01053 if (alphaChanged) { 01054 updateMap(); 01055 } 01056 */ 01057 01058 bool cameraPublished = false; 01059 01060 if (configData.wantsToDumpTimestamps) { 01061 //ROS_WARN("outputFile = (%s)", configData.outputTimeFile.c_str()); 01062 ofs << camera_info.header.stamp.toNSec() << endl; 01063 } 01064 01065 //cout << camera_info.header.stamp.toNSec() << endl; 01066 01067 if ((configData.output16bitFlag) || (configData.wantsToWrite && (configData.outputType == "CV_16UC1"))) { 01068 01069 //_16bitMat_pub.copyTo(testMat); 01070 01071 if (configData.wantsToUndistort) { 01072 if (_16bitMat.data == _16bitMat_pub.data) { 01073 _16bitMat_pub = Mat(_16bitMat.size(), _16bitMat.type()); 01074 } 01075 01076 remap(_16bitMat, _16bitMat_pub, map1, map2, INTER_LINEAR, BORDER_CONSTANT, 0); 01077 } else { 01078 _16bitMat_pub = Mat(_16bitMat); 01079 } 01080 01081 //if (matricesAreEqual(publishTopics() testMat, _16bitMat_pub)) { 01082 //ROS_ERROR("Violation!!"); 01083 //} else { 01084 //ROS_WARN("Non-Violation!!"); 01085 //} 01086 01087 if (configData.output16bitFlag) { 01088 01089 std::copy(&(_16bitMat_pub.at<char>(0,0)), &(_16bitMat_pub.at<char>(0,0))+(_16bitMat_pub.cols*_16bitMat_pub.rows*2), msg_16bit.data.begin()); 01090 01091 01092 01093 if (!cameraPublished) { 01094 01095 pub_16bit.publish(msg_16bit, camera_info); 01096 cameraPublished = true; 01097 } else { 01098 01099 pub_16bit_im.publish(msg_16bit); 01100 } 01101 01102 01103 //HGH 01104 if (configData.republishSource==REPUBLISH_CODE_16BIT){ 01105 01106 if (configData.republishNewTimeStamp){ 01107 //republish with new time stamps 01108 pub_republish.publish(msg_16bit, camera_info, ros::Time::now()); 01109 } else { 01110 pub_republish.publish(msg_16bit, camera_info); 01111 } 01112 } 01113 01114 } 01115 01116 } 01117 01118 if ((configData.output8bitFlag) || (configData.wantsToWrite && (configData.outputType == "CV_8UC1"))) { 01119 01120 if (configData.wantsToUndistort) { 01121 if (_8bitMat.data == _8bitMat_pub.data) { 01122 _8bitMat_pub = Mat(_8bitMat.size(), _8bitMat.type()); 01123 } 01124 01125 remap(_8bitMat, _8bitMat_pub, map1, map2, INTER_LINEAR, BORDER_CONSTANT, 0); 01126 } else { 01127 _8bitMat_pub = Mat(_8bitMat); 01128 } 01129 01130 if (configData.output8bitFlag) { 01131 01132 //HGH 01133 if (configData.drawReticle){ 01134 line(_8bitMat_pub, Point(0,_8bitMat_pub.rows/2), Point(_8bitMat_pub.cols, _8bitMat_pub.rows/2), Scalar(0),1,8); 01135 line(_8bitMat_pub, Point(_8bitMat_pub.cols/2,0), Point(_8bitMat_pub.cols/2, _8bitMat_pub.rows), Scalar(0),1,8); 01136 } 01137 01138 std::copy(&(_8bitMat_pub.at<unsigned char>(0,0)), &(_8bitMat_pub.at<unsigned char>(0,0))+(_8bitMat_pub.cols*_8bitMat_pub.rows), msg_8bit.data.begin()); 01139 01140 01141 if (!cameraPublished) { 01142 pub_8bit.publish(msg_8bit, camera_info); 01143 01144 cameraPublished = true; 01145 } else { 01146 pub_8bit_im.publish(msg_8bit); 01147 01148 } 01149 01150 //HGH 01151 if (configData.republishSource==REPUBLISH_CODE_8BIT_MONO){ 01152 01153 if (configData.republishNewTimeStamp){ 01154 //republish with new time stamps 01155 pub_republish.publish(msg_8bit, camera_info, ros::Time::now()); 01156 } else{ 01157 pub_republish.publish(msg_8bit, camera_info); 01158 } 01159 } 01160 01161 } 01162 01163 } 01164 01165 if ((configData.outputColorFlag) || (configData.wantsToWrite && (configData.outputType == "CV_8UC3"))) { 01166 01167 01168 if (colourMat.rows > 0) { 01169 01170 01171 if (configData.wantsToUndistort) { 01172 if (colourMat.data == colourMat_pub.data) { 01173 colourMat_pub = Mat(colourMat.size(), colourMat.type()); 01174 } 01175 01176 remap(colourMat, colourMat_pub, map1, map2, INTER_LINEAR, BORDER_CONSTANT, 0); 01177 } else { 01178 colourMat_pub = Mat(colourMat); 01179 } 01180 01181 if (configData.outputColorFlag) { 01182 01183 //HGH 01184 if (configData.drawReticle){ 01185 line(colourMat_pub, Point(0,colourMat_pub.rows/2), Point(colourMat_pub.cols, colourMat_pub.rows/2), Scalar(0,255,0),1,8); 01186 line(colourMat_pub, Point(colourMat_pub.cols/2,0), Point(colourMat_pub.cols/2, colourMat_pub.rows), Scalar(0,255,0),1,8); 01187 // //overlay lines: 01188 // for( int j = 0; j < colourMat_pub.rows; j += 32 ){ 01189 // line(colourMat_pub, Point(0, j), Point(colourMat_pub.cols, j), Scalar(0, 255, 0), 1, 8); 01190 // } 01191 } 01192 01193 std::copy(&(colourMat_pub.at<Vec3b>(0,0)[0]), &(colourMat_pub.at<Vec3b>(0,0)[0])+(colourMat_pub.cols*colourMat_pub.rows*3), msg_color.data.begin()); 01194 01195 if (!cameraPublished) { 01196 pub_color.publish(msg_color, camera_info); 01197 cameraPublished = true; 01198 } else { 01199 pub_color_im.publish(msg_color); 01200 } 01201 01202 //HGH 01203 if (configData.republishSource==REPUBLISH_CODE_8BIT_COL){ 01204 01205 if (configData.republishNewTimeStamp){ 01206 //republish with new time stamps 01207 pub_republish.publish(msg_color, camera_info, ros::Time::now()); 01208 }else{ 01209 pub_republish.publish(msg_color, camera_info); 01210 } 01211 01212 } 01213 } 01214 01215 01216 /* 01217 imshow("display", colourMat); 01218 waitKey(1); 01219 */ 01220 } 01221 } 01222 01223 01224 01225 readyToPublish = false; 01226 01227 } 01228 01229 void streamerNode::writeData() { 01230 01231 if (configData.wantsToWrite) { 01232 01233 //ROS_ERROR("wantsToWrite == true"); 01234 01235 if ((frameCounter-1) != lastWritten) { 01236 01237 //ROS_ERROR("Entered write routine..."); 01238 01239 char *outputFilename; 01240 outputFilename = (char*) malloc(256); 01241 01242 if (configData.loadMode && configData.wantsToKeepNames) { 01243 01244 size_t findDot = inputList.at(frameCounter-1).rfind("."); 01245 01246 string partialName; 01247 partialName = inputList.at(frameCounter-1).substr(0, findDot); 01248 01249 sprintf(outputFilename, "%s/%s.%s", configData.outputFolder.c_str(), partialName.c_str(), configData.outputFormatString.c_str()); 01250 01251 } else { 01252 sprintf(outputFilename, "%s/frame%06d.%s", configData.outputFolder.c_str(), frameCounter-1, configData.outputFormatString.c_str()); 01253 } 01254 01255 // ROS_ERROR("Output name = (%s)", outputFilename); 01256 01257 if (configData.outputType == "CV_16UC1") { 01258 if (_16bitMat.rows > 0) { 01259 01260 if (configData.outputFormatString == "png") { 01261 imwrite(outputFilename, _16bitMat_pub, configData.outputFileParams); 01262 } else if ((configData.outputFormatString == "pgm") || (configData.outputFormatString == "ppm")) { 01263 imwrite(outputFilename, _16bitMat_pub); 01264 } 01265 } 01266 } else if (configData.outputType == "CV_8UC3") { 01267 if (colourMat.rows > 0) { 01268 01269 //ROS_ERROR("Actually writing..."); 01270 01271 if ((configData.outputFormatString == "png") || (configData.outputFormatString == "jpg")) { 01272 imwrite(outputFilename, colourMat_pub, configData.outputFileParams); 01273 } else if ((configData.outputFormatString == "bmp") || (configData.outputFormatString == "ppm")) { 01274 imwrite(outputFilename, colourMat_pub); 01275 } 01276 } 01277 } else if (configData.outputType == "CV_8UC1") { 01278 if (_8bitMat.rows > 0) { 01279 if ((configData.outputFormatString == "png") || (configData.outputFormatString == "jpg")) { 01280 imwrite(outputFilename, _8bitMat_pub, configData.outputFileParams); 01281 } else if ((configData.outputFormatString == "bmp") || (configData.outputFormatString == "pgm") || (configData.outputFormatString == "ppm")) { 01282 imwrite(outputFilename, _8bitMat_pub); 01283 } 01284 } 01285 } 01286 lastWritten = frameCounter - 1; 01287 } 01288 } 01289 01290 if (configData.wantsToEncode) { 01291 if (!videoInitialized) { 01292 if (configData.videoType == "CV_16UC1") { 01293 // 0 writes uncompressed, 1 gives user option 01294 vid_writer.open(configData.outputVideo, CV_FOURCC('P','I','M','1'), ((int) configData.framerate), _16bitMat.size(), true); 01295 } else if (configData.videoType == "CV_8UC3") { 01296 vid_writer.open(configData.outputVideo, CV_FOURCC('P','I','M','1'), ((int) configData.framerate), colourMat.size()); // , true); 01297 } else if (configData.videoType == "CV_8UC1") { 01298 vid_writer.open(configData.outputVideo, CV_FOURCC('X', 'V', 'I', 'D'), ((int) configData.framerate), _8bitMat.size(), false); 01299 } 01300 01301 videoInitialized = true; 01302 } 01303 01304 if (configData.videoType == "CV_16UC1") { 01305 vid_writer << _16bitMat; 01306 } else if (configData.videoType == "CV_8UC3") { 01307 vid_writer << colourMat; 01308 } else if (configData.videoType == "CV_8UC1") { 01309 vid_writer << _8bitMat; 01310 } 01311 01312 } 01313 } 01314 01315 void streamerNode::serialCallback(const ros::TimerEvent&) { 01316 01317 if (!configData.serialComms) { 01318 return; 01319 } 01320 01321 if (configData.serialPollingRate == 0.0) { 01322 ROS_WARN("Skipping serial callback because desired frequency is zero (0)."); 01323 return; 01324 } else { 01325 //ROS_WARN("Polling serial device..."); 01326 01327 if (configData.readThermistor) { 01328 01329 newThermistorReading = getThermistorReading(); 01330 01331 //ROS_INFO("newVal = (%f) vs oldVal = (%f)", newThermistorReading, lastThermistorReading); 01332 01333 // If new value is valid 01334 if ((newThermistorReading > -20.0) && (newThermistorReading < 60.0)) { 01335 01336 // If the historical value is valid 01337 if (lastThermistorReading != 0.0) { 01338 01339 01340 if (abs(newThermistorReading - lastThermistorReading) < configData.maxThermistorDiff) { 01341 lastThermistorReading = newThermistorReading; 01342 } 01343 01344 01345 } else { 01346 lastThermistorReading = newThermistorReading; 01347 } 01348 01349 } 01350 01351 //ROS_WARN("Thermistor value = (%f)", lastThermistorReading); 01352 } 01353 01354 if (configData.calibrationMode > 0) { 01355 if (alternateCounter >= configData.alternatePeriod) { 01356 01357 if (configData.calibrationMode == CALIBMODE_ALT_OUTPUT) { 01358 if (altStatus) { 01359 sprintf(serialCommand, "vidout raw\r"); 01360 } else { 01361 sprintf(serialCommand, "vidout ins\r"); 01362 } 01363 altStatus = !altStatus; 01364 } else if (configData.calibrationMode == CALIBMODE_ALT_SHUTTER) { 01365 if (performingNuc) { 01366 01367 if (configData.verboseMode) { ROS_INFO("About to switch shutter"); } 01368 01369 if (altStatus) { 01370 sprintf(serialCommand, "close\r"); 01371 } else { 01372 sprintf(serialCommand, "open\r"); 01373 } 01374 altStatus = !altStatus; 01375 01376 } else { 01377 ROS_INFO("About to perform a NUC"); 01378 sprintf(serialCommand, "nuc\r"); 01379 } 01380 01381 performingNuc = !performingNuc; 01382 } else if (configData.calibrationMode == CALIBMODE_LONG_SHUTTER) { 01383 01384 if (configData.verboseMode) { ROS_INFO("About to switch shutter"); } 01385 01386 if (altStatus) { 01387 sprintf(serialCommand, "close\r"); 01388 } else { 01389 sprintf(serialCommand, "open\r"); 01390 } 01391 01392 altStatus = !altStatus; 01393 } 01394 01395 int bytesToWrite = 0; 01396 01397 while (serialCommand[bytesToWrite] != '\r') { 01398 bytesToWrite++; 01399 } 01400 bytesToWrite++; 01401 01402 int n; 01403 //char buff[256]; 01404 01405 ROS_INFO("Sending NUCSET command: (%d) %s", bytesToWrite, serialCommand); 01406 n = write(mainfd, serialCommand, bytesToWrite); 01407 if (n!=bytesToWrite) puts("write() failed!\n"); 01408 01409 01410 01411 alternateCounter = 0; 01412 } 01413 alternateCounter++; 01414 } 01415 01416 } 01417 01418 if (updateDetectorMode) { 01419 01420 string detectorCode; 01421 01422 if (configData.detectorMode == DETECTOR_MODE_RAW) { 01423 detectorCode = "raw"; 01424 } else if (configData.detectorMode == DETECTOR_MODE_LUM) { 01425 detectorCode = "lum"; 01426 } else if (configData.detectorMode == DETECTOR_MODE_INS) { 01427 detectorCode = "ins"; 01428 } else if (configData.detectorMode == DETECTOR_MODE_RAD) { 01429 detectorCode = "rad"; 01430 } else if (configData.detectorMode == DETECTOR_MODE_TMP) { 01431 detectorCode = "t"; 01432 } 01433 sprintf(serialCommand, "vidout %s\r", detectorCode.substr(0,3).c_str()); 01434 01435 int bytesToWrite = 1; 01436 01437 while (serialCommand[bytesToWrite-1] != '\r') { 01438 bytesToWrite++; 01439 } 01440 01441 ROS_INFO("Changing detector output with command: <%s> (%d bytes) ", string(serialCommand).substr(0,bytesToWrite-1).c_str(), bytesToWrite); 01442 01443 int n; 01444 char buff[256]; 01445 n = write(mainfd, serialCommand, bytesToWrite); 01446 if (n!=bytesToWrite) { 01447 ROS_ERROR("write() failed!"); 01448 } 01449 n = read(mainfd, buff, 256); 01450 01451 // ROS_INFO("Returned is <%s>", buff); 01452 01453 updateDetectorMode = false; 01454 } 01455 01456 if (updateNucInterval) { 01457 01458 // Value is in 100ths of a degree centigrade, so pass 20 to trigger change every 0.2 C 01459 sprintf(serialCommand, "nucset %d %d %d %d\r", configData.maxNucInterval, 0, 0, int(100*configData.maxNucThreshold)); 01460 01461 int bytesToWrite = 0; 01462 01463 while (serialCommand[bytesToWrite] != '\r') { 01464 bytesToWrite++; 01465 } 01466 bytesToWrite++; 01467 01468 01469 ROS_INFO("Sending NUCSET command: (%d) %s", bytesToWrite, serialCommand); 01470 01471 01472 01473 //sprintf(serialCommand, "nucset\r"); 01474 01475 // Send new NUCSET command 01476 01477 int n; 01478 char buff[256]; 01479 n = write(mainfd, serialCommand, bytesToWrite); 01480 if (n!=bytesToWrite) puts("write() failed!\n"); 01481 n = read(mainfd, buff, 256); 01482 01483 ROS_INFO("Returned is (%s)", buff); 01484 01485 updateNucInterval = false; 01486 } 01487 01488 } 01489 01490 void streamerNode::timerCallback(const ros::TimerEvent&) { 01491 01492 if (configData.pauseMode) { 01493 return; 01494 } 01495 01496 if (configData.captureMode || configData.subscribeMode) { 01497 return; 01498 } 01499 01500 if (configData.pollMode || configData.resampleMode) { 01501 01502 if (configData.pollMode) { 01503 01504 //ROS_ERROR("About to call stream"); 01505 01506 streamCallback(); 01507 01508 //ROS_ERROR("Stream called"); 01509 } 01510 01511 if (processImage()) { 01512 01513 //ROS_ERROR("Processed"); 01514 01515 if (readyToPublish) { 01516 if (configData.resampleMode) { 01517 //updateCameraInfo(); 01518 } 01519 publishTopics(); 01520 01521 //ROS_ERROR("Published"); 01522 01523 writeData(); 01524 01525 //ROS_ERROR("Written"); 01526 01527 } 01528 01529 } 01530 01531 //ROS_ERROR("All done."); 01532 01533 01534 return; 01535 } 01536 01537 if (configData.loadMode) { 01538 01539 string filename; 01540 01541 if (configData.folder.at(configData.folder.length()-1) == '/') { 01542 filename = configData.folder + inputList.at(frameCounter); 01543 } else { 01544 filename = configData.folder + "/" + inputList.at(frameCounter); 01545 } 01546 01547 frame = imread(filename, -1); 01548 01549 //ROS_INFO("Read frame (%s)", filename.c_str()); 01550 01551 if (processImage()) { 01552 //ROS_INFO("Image process is true..."); 01553 if (readyToPublish) { 01554 //ROS_INFO("Publishing..."); 01555 updateCameraInfo(); 01556 publishTopics(); 01557 writeData(); 01558 } 01559 01560 } 01561 01562 if (frameCounter >= fileCount) { 01563 if (configData.verboseMode) { ROS_WARN("setValidity(false) : (frameCounter >= fileCount)"); } 01564 setValidity(false); 01565 } 01566 01567 return; 01568 } 01569 01570 bool validFrameRead = true; 01571 01572 // If in read mode... 01573 if (configData.inputDatatype == DATATYPE_RAW) { 01574 01575 do { 01576 //ROS_WARN("Attempting to read frame..."); 01577 if (av_read_frame(mainVideoSource->pIFormatCtx, &(mainVideoSource->packet)) != 0) { 01578 ROS_WARN("Frame invalid..."); 01579 validFrameRead = false; 01580 break; 01581 } 01582 //ROS_WARN("Frame valid!"); 01583 } while (mainVideoSource->packet.stream_index != mainVideoSource->videoStream); 01584 01585 01586 if (validFrameRead) { 01587 01588 01589 avcodec_decode_video2(mainVideoSource->pCodecCtx, mainVideoSource->pFrame, &(mainVideoSource->frameFinished), &(mainVideoSource->packet)); 01590 01591 acceptImage((void*) *(mainVideoSource->pFrame->data)); 01592 01593 if (processImage()) { 01594 if (readyToPublish) { 01595 updateCameraInfo(); 01596 publishTopics(); 01597 writeData(); 01598 } 01599 } 01600 01601 01602 01603 av_free_packet(&(mainVideoSource->packet)); 01604 01605 } else { 01606 if (configData.verboseMode) { ROS_WARN("setValidity(false) : (validFrameRead)"); } 01607 setValidity(false); 01608 } 01609 01610 } else if ((configData.inputDatatype == DATATYPE_8BIT) || (configData.inputDatatype == DATATYPE_MM)) { 01611 01612 ROS_WARN("About to read in frame..."); 01613 01614 if(!cap.isOpened()) { 01615 ROS_ERROR("Actually, device isn't open..."); 01616 } else { 01617 ROS_INFO("Device is open..."); 01618 } 01619 01620 ROS_INFO("framecount = (%f)", cap.get(CV_CAP_PROP_FRAME_COUNT)); 01621 01622 ROS_INFO("dim = (%f, %f)", cap.get(CV_CAP_PROP_FRAME_WIDTH), cap.get(CV_CAP_PROP_FRAME_HEIGHT)); 01623 01624 cap >> frame; 01625 //IplImage* tmp_im = cvQueryFrame(capture); 01626 //frame = tmp_im; 01627 01628 ROS_WARN("Frame read"); 01629 01630 //imshow("test", frame); 01631 //waitKey(); 01632 01633 if (&frame == NULL) { 01634 if (configData.verboseMode) { ROS_WARN("setValidity(false) : (&frame == NULL)"); } 01635 setValidity(false); 01636 01637 } else { 01638 if (processImage()) { 01639 if (readyToPublish) { 01640 updateCameraInfo(); 01641 publishTopics(); 01642 writeData(); 01643 } 01644 } 01645 01646 01647 } 01648 01649 } 01650 } 01651 01652 void streamerNode::assignDefaultCameraInfo() { 01653 01654 globalCameraInfo.imageSize = Mat(1, 2, CV_16UC1); 01655 globalCameraInfo.imageSize.at<unsigned short>(0, 1) = DEFAULT_IMAGE_HEIGHT; 01656 globalCameraInfo.imageSize.at<unsigned short>(0, 0) = DEFAULT_IMAGE_WIDTH; 01657 01658 globalCameraInfo.cameraMatrix = Mat::eye(3, 3, CV_64FC1); 01659 globalCameraInfo.distCoeffs = Mat::zeros(1, 8, CV_64FC1); 01660 globalCameraInfo.newCamMat = Mat::eye(3, 3, CV_64FC1); 01661 globalCameraInfo.cameraSize = Size(globalCameraInfo.imageSize.at<unsigned short>(0, 0), globalCameraInfo.imageSize.at<unsigned short>(0, 1)); 01662 01663 } 01664 01665 void streamerNode::overwriteCameraDims() { 01666 01667 camera_info.height = globalCameraInfo.imageSize.at<unsigned short>(0, 1); 01668 camera_info.width = globalCameraInfo.imageSize.at<unsigned short>(0, 0); 01669 01670 } 01671 01672 streamerNode::streamerNode(ros::NodeHandle& nh, streamerData startupData) { 01673 01674 sprintf(nodeName, "%s", ros::this_node::getName().substr(1).c_str()); 01675 01676 ROS_INFO("Initializing node (%s)", nodeName); 01677 01678 firstCall = true; 01679 updateNucInterval = true; 01680 updateDetectorMode = true; 01681 altStatus = true; 01682 performingNuc = false; 01683 alphaChanged = true; 01684 readyToPublish = false; 01685 isActuallyGray = false; 01686 videoInitialized = false; 01687 setValidity(true); 01688 firstFrame = true; 01689 centerPrincipalPoint = true; 01690 firstServerCallbackProcessed = false; 01691 pastMeanIndex = -1; 01692 medianPercentile = 0.50; 01693 alternateCounter = 0; 01694 dodgeTime.sec = 0; 01695 dodgeTime.nsec = 0; 01696 fusionFactor = 0.8; 01697 fileCount = 0; 01698 writeIndex = 0; 01699 frameCounter = 0; 01700 lastWritten = -1; 01701 lastThermistorReading = 0.0; 01702 lastMedian = -1.0; 01703 lastLowerLimit = -1.0; 01704 lastUpperLimit = -1.0; 01705 oldMaxDiff = -1.0; 01706 minVal = 65535.0; 01707 maxVal = 0.0; 01708 01709 configData = startupData; 01710 01711 if (configData.serialComms) { 01712 ROS_INFO("Configuring serial comms..."); 01713 ROS_INFO("Serial comms configured."); 01714 if (!configureSerialComms()) { 01715 if (configData.verboseMode) { ROS_WARN("Serial comms configuration failed. Shutting down."); } 01716 wantsToShutdown = true; 01717 prepareForTermination(); 01718 return; 01719 } 01720 } 01721 01722 ROS_INFO("configData.serialPollingRate = (%f)", configData.serialPollingRate); 01723 01724 if (configData.serialPollingRate > 0.1) { 01725 ROS_INFO("Initializing serial timer at (%f)", 1.0 / ((double) configData.serialPollingRate)); 01726 serial_timer = nh.createTimer(ros::Duration(1.0 / ((double) configData.serialPollingRate)), &streamerNode::serialCallback, this); 01727 } else { 01728 ROS_INFO("Initializing serial timer at (%f)", DEFAULT_SERIAL_POLLING_RATE); 01729 serial_timer = nh.createTimer(ros::Duration(DEFAULT_SERIAL_POLLING_RATE), &streamerNode::serialCallback, this); 01730 } 01731 01732 it = new image_transport::ImageTransport(nh); 01733 01734 string info_name = configData.topicname.substr(0, configData.topicname.find_last_of("/") + 1) + "camera_info"; 01735 ROS_INFO("configData.topicname = (%s)", info_name.c_str()); 01736 01737 if (configData.calibrationMode) { 01738 ros::Duration(1.0).sleep(); // wait a little bit to ensure that the serial comms has been configured.. 01739 } 01740 01741 ROS_INFO("Initializing camera (%s)", configData.topicname.c_str()); 01742 01743 mainVideoSource = new streamerSource; 01744 01745 std::string camera_name; 01746 01747 if (configData.outputFolder.size() == 0) { 01748 configData.outputFolder = configData.read_addr + configData.outputFolder; 01749 } else if (configData.outputFolder[0] != '/') { 01750 configData.outputFolder = configData.read_addr + configData.outputFolder; 01751 } 01752 01753 configData.outputTimeFile = configData.outputFolder + "-timestamps.txt"; 01754 01755 if (configData.wantsToDumpTimestamps) { 01756 ofs.open(configData.outputTimeFile.c_str()); 01757 } 01758 01759 if (configData.intrinsicsProvided) { 01760 01761 ROS_INFO("Reading in calibration data"); 01762 01763 if (configData.intrinsics[0] != '/') { 01764 configData.intrinsics = configData.read_addr + configData.intrinsics; 01765 } 01766 01767 ROS_INFO("intrinsics = %s", configData.intrinsics.c_str()); 01768 01769 // http://www.mathpirate.net/log/2009/11/26/when-in-doubt-link-debug/ 01770 Mat dummyImage(300, 300, CV_8UC1); 01771 GaussianBlur(dummyImage, dummyImage, Size(5, 5), 1.5); 01772 01773 01774 FileStorage fs(configData.intrinsics, FileStorage::READ); 01775 fs["imageSize"] >> globalCameraInfo.imageSize; 01776 fs["cameraMatrix"] >> globalCameraInfo.cameraMatrix; 01777 fs["distCoeffs"] >> globalCameraInfo.distCoeffs; 01778 fs["newCamMat"] >> globalCameraInfo.newCamMat; 01779 fs.release(); 01780 01781 ROS_INFO("Calibration data read."); 01782 01783 //HGH 01784 if (globalCameraInfo.cameraMatrix.empty()){ 01785 ROS_ERROR("Intrinsics file %s invalid! Please check path and filecontent...\n", configData.intrinsics.c_str()); 01786 } 01787 01788 ROS_INFO("Establishing size (%d, %d).", globalCameraInfo.imageSize.at<unsigned short>(0, 0), globalCameraInfo.imageSize.at<unsigned short>(0, 1)); 01789 01790 globalCameraInfo.cameraSize = Size(globalCameraInfo.imageSize.at<unsigned short>(0, 0), globalCameraInfo.imageSize.at<unsigned short>(0, 1)); 01791 01792 //globalCameraInfo.newCamMat = getOptimalNewCameraMatrix(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.cameraSize, configData.alpha, globalCameraInfo.cameraSize, validPixROI, centerPrincipalPoint); 01793 01794 01795 ROS_INFO("Global params determined."); 01796 01797 01798 } else if (configData.imageDimensionsSpecified) { 01799 01800 ROS_INFO("Assigning default intrinsics but with specified image size"); 01801 01802 assignDefaultCameraInfo(); 01803 01804 globalCameraInfo.imageSize.at<unsigned short>(0, 1) = configData.inputHeight; 01805 globalCameraInfo.imageSize.at<unsigned short>(0, 0) = configData.inputWidth; 01806 globalCameraInfo.cameraSize = Size(globalCameraInfo.imageSize.at<unsigned short>(0, 0), globalCameraInfo.imageSize.at<unsigned short>(0, 1)); 01807 01808 // ROS_INFO("Assigned."); 01809 01810 } else { 01811 ROS_INFO("Assigning default intrinsics..."); 01812 01813 assignDefaultCameraInfo(); 01814 01815 ROS_INFO("Default intrinsics assigned."); 01816 } 01817 01818 01819 //HGH 01820 if (configData.autoAlpha) { 01821 01822 if (configData.intrinsicsProvided) { 01823 if (configData.verboseMode) { ROS_INFO("Finding auto alpha..."); } 01824 configData.alpha = findBestAlpha(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.cameraSize); 01825 //HGH 01826 ROS_INFO("Optimal alpha: (%f)", configData.alpha); 01827 } else { 01828 ROS_WARN("Cannot estimate an appropriate alpha coefficient because no intrinsics were provided."); 01829 } 01830 01831 } 01832 01833 01834 if (configData.wantsToAddExtrinsics) { 01835 ROS_INFO("Reading in extrinsics..."); 01836 01837 char rotation_name[256], translation_name[256]; 01838 01839 sprintf(rotation_name, "R_%d", configData.camera_number); 01840 sprintf(translation_name, "T%d", configData.camera_number); 01841 01842 // http://www.mathpirate.net/log/2009/11/26/when-in-doubt-link-debug/ 01843 Mat dummyImage(300, 300, CV_8UC1); 01844 GaussianBlur(dummyImage, dummyImage, Size(5, 5), 1.5); 01845 01846 FileStorage fs(configData.extrinsics, FileStorage::READ); 01847 01848 //HGH 01849 fs[rotation_name] >> globalCameraInfo.R; 01850 fs[translation_name] >> globalCameraInfo.T; 01851 01852 //used to calculate the individual rotation and projection matrices for rectification depending on alpha 01853 fs["R"] >> globalExtrinsicsData.R; 01854 fs["T"] >> globalExtrinsicsData.T; 01855 01856 //we need also both camera matrices and distortion coefficients 01857 fs["cameraMatrix0"] >> globalExtrinsicsData.cameraMatrix0; 01858 fs["cameraMatrix1"] >> globalExtrinsicsData.cameraMatrix1; 01859 fs["distCoeffs0"] >> globalExtrinsicsData.distCoeffs0; 01860 fs["distCoeffs1"] >> globalExtrinsicsData.distCoeffs1; 01861 01862 fs.release(); 01863 01864 if (globalExtrinsicsData.R.empty()){ 01865 ROS_ERROR("Extrinsics file %s invalid! Please check path and filecontent...\n", configData.extrinsics.c_str()); 01866 } 01867 01868 globalCameraInfo.cameraSize = Size(globalCameraInfo.imageSize.at<unsigned short>(0, 0), globalCameraInfo.imageSize.at<unsigned short>(0, 1)); 01869 01870 getRectification(); 01871 01872 } else { 01873 01874 globalCameraInfo.R = Mat::eye(3, 3, CV_64FC1); 01875 globalCameraInfo.T = Mat::zeros(3, 1, CV_64FC1); 01876 } 01877 01878 if (configData.verboseMode) { ROS_INFO("calling assignCameraInfo() from streamerNode()..."); } 01879 assignCameraInfo(); 01880 01881 ROS_INFO("Initializing video source..."); 01882 mainVideoSource->initialize_video_source(); 01883 01884 colourMap.load_standard(configData.mapCode, configData.mapParam); 01885 01886 refreshCameraAdvertisements(); 01887 01888 char cameraInfoName[256]; 01889 sprintf(cameraInfoName, "thermalvis/%s/set_camera_info", nodeName); 01890 ros::ServiceServer set_camera_info = nh.advertiseService(cameraInfoName, &streamerNode::setCameraInfo, this); 01891 01892 01893 if (configData.framerate > 0.0) { 01894 configData.pauseMode = false; 01895 timer = nh.createTimer(ros::Duration(1.0 / ((double) configData.framerate)), &streamerNode::timerCallback, this); 01896 } else { 01897 configData.pauseMode = true; 01898 timer = nh.createTimer(ros::Duration(1.0 / 1.0), &streamerNode::timerCallback, this); 01899 } 01900 01901 // Configure log files 01902 callLogFile = configData.read_addr + "/nodes/streamer/log/call_log.txt"; 01903 retrieveLogFile = configData.read_addr + "/nodes/streamer/log/retrieve_log.txt"; 01904 internalLogFile = configData.read_addr + "/nodes/streamer/log/internal_log.txt"; 01905 writeLogFile = configData.read_addr + "/nodes/streamer/log/write_log.txt"; 01906 duplicatesLogFile = configData.outputFolder + "-duplicates.txt"; 01907 thermistorLogFile = configData.outputFolder + "-thermistor.txt"; 01908 01909 // &PGRCameraNode::publishImage, this, _1 01910 //f = boost::bind(&streamerNode::serverCallback, this, NULL); 01911 //f = boost::bind(serverCallback, _1, _2); 01912 //server.setCallback(f); 01913 01914 ROS_INFO("Establishing server callback..."); 01915 f = boost::bind (&streamerNode::serverCallback, this, _1, _2); 01916 server.setCallback (f); 01917 01918 if (configData.subscribeMode || configData.resampleMode) { 01919 ROS_INFO("syncMode: (%d)", configData.syncMode); 01920 if (configData.syncMode == SYNCMODE_HARD) { 01921 camera_sub = it->subscribeCamera(configData.topicname, 1, &streamerNode::handle_camera, this); 01922 } else if (configData.syncMode == SYNCMODE_SOFT) { 01923 info_sub = nh.subscribe<sensor_msgs::CameraInfo>(info_name, 1, &streamerNode::handle_info, this); 01924 image_sub = it->subscribe(configData.topicname, 1, &streamerNode::handle_image, this); 01925 } else if (configData.syncMode == SYNCMODE_IMAGEONLY) { 01926 image_sub = it->subscribe(configData.topicname, 1, &streamerNode::handle_image, this); 01927 } 01928 } 01929 01930 // Wait for the first server callback to be processed before continuing.. 01931 while (!firstServerCallbackProcessed) { }; 01932 01933 if (configData.wantsToDumpTimestamps) { 01934 ofs_call_log.open(callLogFile.c_str()); 01935 ofs_retrieve_log.open(retrieveLogFile.c_str()); 01936 ofs_internal_log.open(internalLogFile.c_str()); 01937 ofs_write_log.open(writeLogFile.c_str()); 01938 } 01939 01940 if (configData.wantsToOutputDuplicates) { 01941 ROS_ERROR("Outputting duplicates to (%s)\n", duplicatesLogFile.c_str()); 01942 ofs_duplicates_log.open(duplicatesLogFile.c_str()); 01943 } 01944 } 01945 01946 //HGH 01947 void streamerNode::getRectification(){ 01948 01949 Mat Q; 01950 01951 stereoRectify(globalExtrinsicsData.cameraMatrix0, globalExtrinsicsData.distCoeffs0, globalExtrinsicsData.cameraMatrix1, globalExtrinsicsData.distCoeffs1, 01952 globalCameraInfo.cameraSize, 01953 globalExtrinsicsData.R, globalExtrinsicsData.T, 01954 globalExtrinsicsData.R0, globalExtrinsicsData.R1, globalExtrinsicsData.P0, globalExtrinsicsData.P1, 01955 Q, 01956 CALIB_ZERO_DISPARITY, configData.alpha, globalCameraInfo.cameraSize, &globalExtrinsicsData.roi0, &globalExtrinsicsData.roi1); 01957 01958 // ROS_WARN("----- CAM Number %d",configData.camera_number); 01959 // cout << "R0 = " << globalExtrinsicsData.R0 << endl; 01960 // cout << "P0 = " << globalExtrinsicsData.P0 << endl; 01961 // cout << "R1 = " << globalExtrinsicsData.R1 << endl; 01962 // cout << "P1 = " << globalExtrinsicsData.P1 << endl; 01963 // cout << "newCamMat = " << globalCameraInfo.newCamMat << endl; 01964 // printf("roi0 (%d, %d, %d, %d) ", int(globalExtrinsicsData.roi0.x), int(globalExtrinsicsData.roi0.y), int(globalExtrinsicsData.roi0.width), int(globalExtrinsicsData.roi0.height)); 01965 // printf("roi1 (%d, %d, %d, %d) ", int(globalExtrinsicsData.roi1.x), int(globalExtrinsicsData.roi1.y), int(globalExtrinsicsData.roi1.width), int(globalExtrinsicsData.roi1.height)); 01966 // cout << "configData.alpha = " << configData.alpha << endl; 01967 01968 } 01969 01970 void streamerNode::handle_info(const sensor_msgs::CameraInfoConstPtr& info_msg) { 01971 01972 01973 if (configData.syncMode != SYNCMODE_SOFT) { 01974 return; 01975 } 01976 01977 01978 if ((!configData.subscribeMode) && (!configData.resampleMode)) { 01979 return; 01980 } 01981 01982 info_time = ros::Time::now(); 01983 original_time = info_msg->header.stamp; 01984 01985 original_bx = info_msg->binning_x; 01986 original_by = info_msg->binning_y; 01987 01988 //cout << "Handling info..." << info_msg->header.stamp.toNSec() << ", " << info_time.toNSec() << endl; 01989 01990 if (abs(image_time.toNSec() - info_time.toNSec()) < configData.soft_diff_limit) { 01991 //ROS_ERROR("handle_info : image_time == info_time"); 01992 image_time = dodgeTime; 01993 01994 act_on_image(); 01995 } 01996 01997 01998 } 01999 02000 void streamerNode::refreshCameraAdvertisements() { 02001 02002 02003 char colorPubName[256], _16bitPubName[256], _8bitPubName[256]; 02004 02005 sprintf(colorPubName, "thermalvis/%s/image_col", nodeName); 02006 sprintf(_16bitPubName, "thermalvis/%s/image_raw", nodeName); 02007 sprintf(_8bitPubName, "thermalvis/%s/image_mono", nodeName); 02008 02009 bool cameraAdvertised = false; 02010 02011 // Once all copies of the returned Publisher object are destroyed, the topic 02012 // will be automatically unadvertised. 02013 02014 pub_color.shutdown(); 02015 pub_color_im.shutdown(); 02016 pub_16bit.shutdown(); 02017 pub_16bit_im.shutdown(); 02018 pub_8bit.shutdown(); 02019 pub_8bit_im.shutdown(); 02020 02021 //HGH 02022 pub_republish.shutdown(); 02023 pub_republish_im.shutdown(); 02024 02025 char _republishPubName[256]; 02026 sprintf(_republishPubName, configData.republishTopic.c_str()); 02027 02028 02029 02030 if (configData.output16bitFlag) { 02031 02032 //HGH 02033 if (configData.republishSource==REPUBLISH_CODE_16BIT){ 02034 pub_republish = it->advertiseCamera(_republishPubName, 1); 02035 } 02036 02037 if (!cameraAdvertised) { 02038 pub_16bit = it->advertiseCamera(_16bitPubName, 1); 02039 02040 cameraAdvertised = true; 02041 } else { 02042 pub_16bit_im = it->advertise(_16bitPubName, 1); 02043 02044 } 02045 02046 } 02047 02048 if (configData.output8bitFlag) { 02049 02050 //HGH 02051 if (configData.republishSource==REPUBLISH_CODE_8BIT_MONO){ 02052 pub_republish = it->advertiseCamera(_republishPubName, 1); 02053 } 02054 02055 if (!cameraAdvertised) { 02056 pub_8bit = it->advertiseCamera(_8bitPubName, 1); 02057 02058 cameraAdvertised = true; 02059 } else { 02060 pub_8bit_im = it->advertise(_8bitPubName, 1); 02061 02062 } 02063 02064 } 02065 02066 02067 if (configData.outputColorFlag) { 02068 //HGH 02069 if (configData.republishSource==REPUBLISH_CODE_8BIT_COL){ 02070 pub_republish = it->advertiseCamera(_republishPubName, 1); 02071 } 02072 if (!cameraAdvertised) { 02073 pub_color = it->advertiseCamera(colorPubName, 1); 02074 02075 cameraAdvertised = true; 02076 } else { 02077 pub_color_im = it->advertise(colorPubName, 1); 02078 02079 } 02080 } 02081 02082 } 02083 02084 02085 void streamerNode::handle_camera(const sensor_msgs::ImageConstPtr& msg_ptr, const sensor_msgs::CameraInfoConstPtr& info_msg) { 02086 02087 if (configData.syncMode != SYNCMODE_HARD) { 02088 return; 02089 } 02090 02091 if ((!configData.subscribeMode) && (!configData.resampleMode)) { 02092 return; 02093 } 02094 02095 02096 //ROS_ERROR("Handling an image..."); 02097 02098 //cout << "Handling camera..." << msg_ptr->header.stamp.toNSec() << ", " << image_time.toNSec() << endl; 02099 02100 original_time = info_msg->header.stamp; 02101 original_bx = 0; 02102 original_by = 0; 02103 02104 if (configData.inputDatatype == DATATYPE_DEPTH) { 02105 cv_ptr = cv_bridge::toCvCopy(msg_ptr, "16UC1"); 02106 } else { 02107 cv_ptr = cv_bridge::toCvCopy(msg_ptr, enc::BGR8); // For some reason it reads as BGR, not gray 02108 } 02109 02110 02111 act_on_image(); 02112 02113 } 02114 02115 void streamerNode::act_on_image() { 02116 02117 //cout << "Acting on image..." << endl; 02118 02119 updateCameraInfo(); 02120 02121 newImage = Mat(cv_ptr->image); 02122 02123 Mat grayImage; 02124 02125 if (newImage.type() == CV_16UC3) { 02126 cvtColor(newImage, frame, CV_RGB2GRAY); 02127 } else { 02128 frame = Mat(newImage); 02129 } 02130 02131 if (readyToPublish) { 02132 // This means it still hasn't published the last requested frame 02133 //return; 02134 } else { 02135 readyToPublish = true; 02136 } 02137 02138 02139 if (!configData.resampleMode) { 02140 02141 if (processImage()) { 02142 if (readyToPublish) { 02143 updateCameraInfo(); 02144 publishTopics(); 02145 writeData(); 02146 } 02147 } 02148 02149 } 02150 02151 return; 02152 02153 } 02154 02155 void streamerNode::handle_image(const sensor_msgs::ImageConstPtr& msg_ptr) { 02156 02157 if (configData.syncMode == SYNCMODE_HARD) { 02158 return; 02159 } 02160 02161 if ((!configData.subscribeMode) && (!configData.resampleMode)) { 02162 return; 02163 } 02164 02165 //cout << "Handling image..." << msg_ptr->header.stamp.toNSec() << ", " << image_time.toNSec() << endl; 02166 02167 original_time = msg_ptr->header.stamp; 02168 02169 image_time = ros::Time::now(); 02170 cv_ptr = cv_bridge::toCvCopy(msg_ptr, enc::BGR8); // For some reason it reads as BGR, not gray 02171 02172 if (configData.syncMode == SYNCMODE_SOFT) { 02173 if (abs(image_time.toNSec() - info_time.toNSec()) < configData.soft_diff_limit) { 02174 // ROS_ERROR("handle_image : image_time == info_time"); 02175 02176 image_time = dodgeTime; 02177 act_on_image(); 02178 } 02179 } else { 02180 act_on_image(); 02181 } 02182 02183 02184 //ROS_ERROR("image header = (%d)", msg_ptr->header.stamp.toNSec()); 02185 02186 02187 02188 02189 } 02190 02191 streamerData::streamerData() { 02192 02193 intrinsicsProvided = false; 02194 //wantsToRectify = false; 02195 //HGH 02196 wantsToAddExtrinsics = false; 02197 wantsToWrite = false; 02198 wantsToEncode = false; 02199 wantsToKeepNames = false; 02200 wantsToUndistort = false; 02201 wantsToResize = false; 02202 loopFlag = false; 02203 imageDimensionsSpecified = false; 02204 02205 mapCode = CIECOMP; 02206 mapParam = 0; 02207 02208 framerate = -1.0; 02209 02210 soft_diff_limit = 5000000; 02211 02212 } 02213 02214 bool streamerData::obtainStartingData(ros::NodeHandle& nh) { 02215 02216 nh.param<std::string>("source", source, "dev"); 02217 02218 nh.param<std::string>("file", filename, "file"); 02219 nh.param<std::string>("dev", capture_device, "/dev/video0"); 02220 nh.param<std::string>("topic", topicname, "/thermalvis/streamer/image_raw"); 02221 nh.param<std::string>("folder", folder, "folder"); 02222 02223 nh.param<double>("syncDiff", syncDiff, 0.005); 02224 02225 nh.param<std::string>("portAddress", portAddress, "/dev/ttyS0"); 02226 02227 nh.param<double>("alpha", alpha, 0.00); 02228 nh.param<bool>("autoAlpha", autoAlpha, true); 02229 02230 nh.param<bool>("verboseMode", verboseMode, false); 02231 02232 nh.param<int>("map", map, 0); 02233 nh.param<bool>("extremes", extremes, true); 02234 nh.param<std::string>("intrinsics", intrinsics, "intrinsics"); 02235 02236 nh.param<int>("inputWidth", inputWidth, 0); 02237 nh.param<int>("inputHeight", inputHeight, 0); 02238 02239 02240 nh.param<std::string>("extrinsics", extrinsics, "extrinsics"); 02241 02242 nh.param<int>("inputDatatype", inputDatatype, 1); 02243 02244 nh.param<int>("camera_number", camera_number, 0); 02245 nh.param<double>("framerate", framerate, -1.0); 02246 02247 nh.param<double>("writeQuality", writeQuality, 1.0); 02248 02249 nh.param<bool>("output16bit", output16bitFlag, true); 02250 nh.param<bool>("output8bit", output8bitFlag, false); 02251 nh.param<bool>("outputColor", outputColorFlag, true); 02252 02253 nh.param<bool>("loopMode", loopFlag, false); 02254 02255 nh.param<bool>("disableSkimming", disableSkimming, true); 02256 02257 nh.param<bool>("writeImages", wantsToWrite, false); 02258 nh.param<std::string>("outputFolder", outputFolder, "outputFolder"); 02259 02260 nh.param<bool>("serialComms", serialComms, false); 02261 02262 nh.param<int>("calibrationMode", calibrationMode, CALIBMODE_OFF); 02263 02264 if (outputFolder.size() > 0) { 02265 if (outputFolder.at(outputFolder.size()-1) == '/') { 02266 outputFolder = outputFolder.substr(0, outputFolder.size()-1); 02267 } 02268 } else { 02269 ROS_WARN("Specified output folder is 0 characters long.."); 02270 } 02271 02272 02273 if ((wantsToWrite) && (outputFolder.size() > 0)) { 02274 // Create necessary folders 02275 char folderCommand[256]; 02276 sprintf(folderCommand, "mkdir -p %s", outputFolder.c_str()); 02277 02278 int res = system(folderCommand); 02279 02280 if (res == 0) { 02281 ROS_WARN("system() call returned 0..."); 02282 } 02283 } 02284 02285 02286 ROS_INFO("outputFolder = (%s)", outputFolder.c_str()); 02287 02288 nh.param<int>("outputFormat", outputFormat, 4); 02289 nh.param<std::string>("outputType", outputType, "outputType"); 02290 nh.param<bool>("keepOriginalNames", wantsToKeepNames, false); 02291 02292 nh.param<bool>("writeVideo", wantsToEncode, false); 02293 nh.param<std::string>("outputVideo", outputVideo, "outputVideo"); 02294 nh.param<std::string>("videoType", videoType, "videoType"); 02295 02296 nh.param<bool>("undistortImages", wantsToUndistort, false); 02297 //HGH 02298 nh.param<bool>("rectifyImages", wantsToRectify, false); 02299 02300 nh.param<bool>("removeDuplicates", wantsToRemoveDuplicates, false); 02301 02302 if (outputFolder != "outputFolder") { 02303 nh.param<bool>("dumpTimestamps", wantsToDumpTimestamps, false); 02304 } else { 02305 wantsToDumpTimestamps = false; 02306 } 02307 02308 nh.param<bool>("resizeMode", wantsToResize, false); 02309 02310 //nh.param<int>("syncMode", syncMode, SYNCMODE_HARD); 02311 02312 nh.param<int>("rows", desiredRows, -1); 02313 nh.param<int>("cols", desiredCols, -1); 02314 02315 if (wantsToResize) { 02316 if ((desiredRows < 1) || (desiredRows > MAX_ROWS) || (desiredCols < 1) || (desiredCols > MAX_COLS)) { 02317 ROS_ERROR("Resizing values (%d, %d) invalid.",desiredCols, desiredRows); 02318 return false; 02319 02320 } else { 02321 ROS_INFO("Resizing to (%d x %d)", desiredCols, desiredRows); 02322 } 02323 } 02324 02325 if (wantsToUndistort) { 02326 ROS_INFO("Undistorting images..."); 02327 } 02328 02329 nh.param<int>("normMode", normMode, 0); 02330 nh.param<std::string>("normalizationMode", normalizationMode, "normalizationMode"); 02331 02332 nh.param<double>("normFactor", normFactor, 0.0); 02333 02334 if (normalizationMode == "standard") { 02335 normMode = 0; 02336 } else if (normalizationMode == "low_contrast") { 02337 normMode = 1; 02338 } 02339 02340 /* 02341 if (wantsToWrite) { 02342 ROS_INFO("Has chosen to write."); 02343 02344 if (outputFolder == "outputFolder") { 02345 ROS_ERROR("outputFolder incorrectly specified..."); 02346 return false; 02347 } else { 02348 ROS_INFO("outputFolder = (%s)", outputFolder.c_str()); 02349 02350 } 02351 02352 ROS_INFO("Image format = (%d); image type = (%s)", outputFormat, outputType.c_str()); 02353 02354 if (wantsToKeepNames) { 02355 ROS_INFO("(retaining original names)"); 02356 } else { 02357 ROS_INFO("(not retaining original names)"); 02358 } 02359 02360 } 02361 */ 02362 02363 if (wantsToEncode) { 02364 ROS_INFO("Has chosen to encode."); 02365 02366 if (outputVideo == "outputVideo") { 02367 ROS_ERROR("outputVideo incorrectly specified..."); 02368 return false; 02369 } else { 02370 ROS_INFO("outputVideo = (%s)", outputVideo.c_str()); 02371 02372 } 02373 02374 ROS_INFO("Image format = (%s); image type = (%s)", "avi", videoType.c_str()); 02375 02376 } 02377 02378 if (inputDatatype == DATATYPE_8BIT) { 02379 ROS_INFO("Streaming mode: 8-bit"); 02380 } else if (inputDatatype == DATATYPE_RAW) { 02381 ROS_INFO("Streaming mode: 16-bit"); 02382 } else if (inputDatatype == DATATYPE_MM) { 02383 ROS_INFO("Streaming mode: multimodal"); 02384 } 02385 02386 // ROS_INFO("Source = %s", source.c_str()); 02387 02388 readMode = false; 02389 loadMode = false; 02390 captureMode = false; 02391 pollMode = false; 02392 subscribeMode = false; 02393 resampleMode = false; 02394 02395 02396 if (source == "dev") { 02397 02398 if ((framerate < 0) || (framerate > MAX_READ_RATE)) { 02399 ROS_INFO("Framerate set to (%f) so therefore defaulting to capture mode.", framerate); 02400 framerate = MAX_READ_RATE; 02401 captureMode = true; 02402 } else { 02403 ROS_INFO("Requested framerate (%f) - polling mode", framerate); 02404 pollMode = true; 02405 } 02406 02407 ROS_INFO("Reading from a device (%s)", capture_device.c_str()); 02408 02409 } else if (source == "file") { 02410 readMode = true; 02411 02412 if ((framerate < 0.0) || (framerate > MAX_READ_RATE)) { 02413 ROS_INFO("Invalid framerate (%f) so defaulting to (%f).", framerate, DEFAULT_READ_RATE); 02414 framerate = DEFAULT_READ_RATE; 02415 } else { 02416 ROS_INFO("Requested framerate = %f", framerate); 02417 } 02418 02419 ROS_INFO("Reading from a file (%s)", filename.c_str()); 02420 } else if (source == "folder") { 02421 02422 loadMode = true; 02423 02424 if ((framerate < 0.0) || (framerate > MAX_READ_RATE)) { 02425 ROS_WARN("Invalid framerate (%f) so defaulting to (%f).", framerate, DEFAULT_READ_RATE); 02426 framerate = DEFAULT_READ_RATE; 02427 } else { 02428 ROS_INFO("Requested framerate = %f", framerate); 02429 } 02430 02431 ROS_INFO("Loading images from a folder (%s)", folder.c_str()); 02432 02433 02434 } else if (source == "topic") { 02435 02436 ROS_INFO("Subscribing to topic (%s) ", topicname.c_str()); 02437 02438 if ((framerate < 0.0) || (framerate > MAX_READ_RATE)) { 02439 ROS_WARN("Invalid framerate (%f) so defaulting to subscribe mode.", framerate); 02440 framerate = DEFAULT_READ_RATE; 02441 subscribeMode = true; 02442 } else { 02443 ROS_INFO("Requested framerate = %f (resample mode)", framerate); 02444 resampleMode = true; 02445 } 02446 02447 } 02448 02449 02450 //maxIntensityChange = 100 / DEFAULT_READ_RATE; 02451 02452 if (loopFlag == true) { 02453 ROS_INFO("Option to loop has been selected."); 02454 } 02455 02456 if (intrinsics != "intrinsics") { 02457 intrinsicsProvided = true; 02458 ROS_INFO("Intrinsics at (%s) selected.", intrinsics.c_str()); 02459 02460 if ((inputWidth != 0) && (inputHeight != 0)) { 02461 ROS_WARN("Provided image dimensions will be ignored because of provided intrinsics file."); 02462 } 02463 } else { 02464 02465 if ((inputWidth != 0) && (inputHeight != 0)) { 02466 ROS_INFO("Provided image dimensions (%d, %d) will be used.", inputWidth, inputHeight); 02467 imageDimensionsSpecified = true; 02468 } else { 02469 ROS_WARN("No intrinsics or image dimensions provided. Will attempt to estimate camera size..."); 02470 } 02471 02472 02473 //intrinsics = read_addr + "data/calibration/csiro-aslab/miricle-1.yml"; 02474 //ROS_ERROR("No intrinsics supplied. Defaulting to (%s)", intrinsics.c_str()); 02475 } 02476 02477 02478 02479 if (extrinsics != "extrinsics") { 02480 ROS_WARN("Extrinsics at %s selected.", extrinsics.c_str()); 02481 02482 //HGH 02483 //wantsToRectify = false; 02484 02485 //HGH 02486 wantsToAddExtrinsics = true; 02487 if (camera_number < 0) { 02488 ROS_ERROR("Invalid camera number selected (%d) so defaulting to (0).", camera_number); 02489 camera_number = 0; 02490 }else{ 02491 ROS_INFO("Camera number (%d).", camera_number); 02492 } 02493 } 02494 02495 getMapping(map, extremes, mapCode, mapParam); 02496 02497 int modeCount = 0; 02498 02499 if (captureMode) modeCount++; 02500 if (pollMode) modeCount++; 02501 if (readMode) modeCount++; 02502 if (loadMode) modeCount++; 02503 if (subscribeMode) modeCount++; 02504 if (resampleMode) modeCount++; 02505 02506 if (modeCount == 0) { 02507 ROS_ERROR("Either a device, file or topic should be specified for streaming."); 02508 return false; 02509 } else if (modeCount > 1) { 02510 ROS_ERROR("Either a device, file or topic should be specified - not more than one."); 02511 return false; 02512 } 02513 02514 if ((framerate < -1.0) || (framerate > MAX_READ_RATE)) { 02515 framerate = DEFAULT_READ_RATE; 02516 } 02517 02518 // ROS_INFO("normalization mode = (%d)", normMode); 02519 02520 //HGH 02521 nh.param<int>("republishSource", republishSource, NO_REPUBLISH_CODE); 02522 nh.param<std::string>("republishTopic", republishTopic, "specifyTopic/image_raw"); 02523 //check for valid republishSource 02524 switch(republishSource){ 02525 case REPUBLISH_CODE_8BIT_MONO: 02526 ROS_WARN("Republishing mono image as %s", republishTopic.c_str() ); 02527 break; 02528 case REPUBLISH_CODE_8BIT_COL: 02529 ROS_WARN("Republishing color image as %s", republishTopic.c_str() ); 02530 break; 02531 case REPUBLISH_CODE_16BIT: 02532 ROS_WARN("Republishing 16bit image as %s", republishTopic.c_str() ); 02533 break; 02534 default: 02535 republishSource = NO_REPUBLISH_CODE; 02536 break; 02537 } 02538 if (republishSource != NO_REPUBLISH_CODE){ 02539 ROS_INFO("Republish Code: %d", republishSource); 02540 } 02541 02542 nh.param<bool>("republishNewTimeStamp",republishNewTimeStamp,false); 02543 02544 nh.param<std::string>("frameID", frameID, ""); //specify the frameID 02545 02546 nh.param<bool>("drawReticle",drawReticle, false); 02547 02548 02549 02550 return true; 02551 } 02552 02553 void getMapping(int mapIndex, bool extremes, int& mapCode, int& mapParam) { 02554 02555 if (mapIndex == 0) { 02556 mapCode = GRAYSCALE; 02557 } else if (mapIndex == 1) { 02558 mapCode = CIECOMP; 02559 } else if (mapIndex == 2) { 02560 mapCode = BLACKBODY; 02561 } else if (mapIndex == 3) { 02562 mapCode = RAINBOW; 02563 } else if (mapIndex == 4) { 02564 mapCode = IRON; 02565 } else if (mapIndex == 5) { 02566 mapCode = BLUERED; 02567 } else if (mapIndex == 6) { 02568 mapCode = JET; 02569 } else if (mapIndex == 7) { 02570 mapCode = ICE; 02571 } else if (mapIndex == 8) { 02572 mapCode = ICEIRON; 02573 } else if (mapIndex == 9) { 02574 mapCode = ICEFIRE; 02575 } else if (mapIndex == 10) { 02576 mapCode = REPEATED; 02577 } else if (mapIndex == 11) { 02578 mapCode = HIGHLIGHTED; 02579 } else { 02580 mapCode = GRAYSCALE; 02581 } 02582 02583 if (extremes) { 02584 mapParam = 0; 02585 } else { 02586 mapParam = 1; 02587 } 02588 02589 } 02590 02591 bool streamerNode::isVideoValid() { 02592 02593 if (::wantsToShutdown) { 02594 if (configData.verboseMode){ ROS_WARN("Wants to shut down.."); } 02595 setValidity(false); 02596 } 02597 02598 return videoValid; 02599 02600 } 02601 02602 void streamerNode::setValidity(bool val) { 02603 if ((val == false) && (configData.verboseMode)) { ROS_WARN("Validity being set to false.."); } 02604 videoValid = val; 02605 } 02606 02607 streamerSource * streamerNode::getMainVideoSource() { 02608 return mainVideoSource; 02609 } 02610 02611 VideoCapture * streamerNode::getVideoCapture() { 02612 return ∩ 02613 } 02614 02615 void streamerNode::updateMap() { 02616 02617 ROS_WARN("Updating map..."); 02618 02619 if (configData.autoAlpha) { 02620 configData.alpha = findBestAlpha(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.cameraSize); 02621 02622 ROS_INFO("Optimal alpha: (%f)", configData.alpha); 02623 02624 } 02625 02626 Rect* validPixROI = 0; 02627 globalCameraInfo.newCamMat = getOptimalNewCameraMatrix(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.cameraSize, configData.alpha, globalCameraInfo.cameraSize, validPixROI, centerPrincipalPoint); 02628 02629 //HGH initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.R, globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02630 //HGH 02631 if (configData.wantsToAddExtrinsics){ 02632 02633 //update camera info extrinsics... 02634 getRectification(); 02635 updateCameraInfoExtrinsics(); 02636 02637 if (configData.wantsToRectify){ 02638 if (configData.camera_number == 0){ 02639 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalExtrinsicsData.R0, globalExtrinsicsData.P0, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02640 }else if (configData.camera_number == 1){ 02641 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalExtrinsicsData.R1, globalExtrinsicsData.P1, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02642 } 02643 }else{ 02644 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, Mat(), globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02645 } 02646 02647 }else{ 02648 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, Mat() , globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02649 } 02650 02651 alphaChanged = false; 02652 02653 ROS_WARN("Map updated."); 02654 } 02655 02656 void streamerNode::serverCallback(thermalvis::streamerConfig &config, uint32_t level) { 02657 02658 if (configData.verboseMode){ ROS_INFO("Processing reconfigure request..."); } 02659 02660 /* 02661 if (firstCall) { 02662 02663 ROS_INFO("Initial Argument Summary:"); 02664 02665 ROS_INFO("outputFolder = (%s)", configData.outputFolder.c_str()); 02666 02667 ROS_INFO("config.inputDatatype = (%d)", config.inputDatatype); 02668 ROS_INFO("config.writeImages = (%s)", config.writeImages ? "true" : "false" ); 02669 ROS_INFO("config.outputFormat = (%d)", config.outputFormat); 02670 ROS_INFO("config.outputType = (%d)", config.outputType); 02671 ROS_INFO("config.loopMode = (%s)", config.loopMode ? "true" : "false" ); 02672 ROS_INFO("config.undistortImages = (%s)", config.undistortImages ? "true" : "false" ); 02673 02674 //HGH 02675 ROS_INFO("config.rectifyImages = (%s)", config.rectifyImages ? "true" : "false" ); 02676 02677 ROS_INFO("config.alpha = (%f)", config.alpha); 02678 ROS_INFO("config.removeDuplicates = (%s)", config.removeDuplicates ? "true" : "false" ); 02679 02680 firstCall = false; 02681 } 02682 */ 02683 02684 if (configData.detectorMode != config.detectorMode) { 02685 02686 configData.detectorMode = config.detectorMode; 02687 02688 if (!configData.serialComms) { 02689 ROS_WARN("Selecting a detector mode has no effect unless serial comms are enabled."); 02690 } else { 02691 updateDetectorMode = true; 02692 } 02693 02694 02695 } 02696 02697 if (configData.readThermistor != config.readThermistor) { 02698 configData.readThermistor = config.readThermistor; 02699 02700 if (configData.readThermistor) { 02701 ROS_INFO("Wants to read from thermistor"); 02702 //ROS_WARN("Writing thermistor values to (%s)...", thermistorLogFile.c_str()); 02703 //ofs_thermistor_log.open(thermistorLogFile.c_str()); 02704 } else { 02705 //if (ofs_thermistor_log.is_open()) ofs_thermistor_log.close(); 02706 } 02707 02708 } 02709 02710 configData.wantsToMarkDuplicates = config.markDuplicates; 02711 configData.wantsToOutputDuplicates = config.dumpDuplicates; 02712 02713 configData.temporalSmoothing = config.temporalSmoothing; 02714 02715 configData.maxThermistorDiff = config.maxThermistorDiff; 02716 02717 configData.alternatePeriod = config.alternatePeriod; 02718 02719 if (configData.serialPollingRate != config.serialPollingRate) { 02720 configData.serialPollingRate = config.serialPollingRate; 02721 ROS_INFO("Updating period with rate (%f)", configData.serialPollingRate); 02722 02723 if (configData.serialPollingRate > 0.1) { 02724 serial_timer.setPeriod(ros::Duration(1.0 / configData.serialPollingRate)); 02725 } else { 02726 serial_timer.setPeriod(ros::Duration(1.0 / 1.0)); 02727 } 02728 } 02729 02730 if (configData.maxNucInterval != config.maxNucInterval) { 02731 02732 configData.maxNucInterval = config.maxNucInterval; 02733 updateNucInterval = true; 02734 } 02735 02736 if (configData.maxNucThreshold != config.maxNucThreshold) { 02737 02738 configData.maxNucThreshold = config.maxNucThreshold; 02739 updateNucInterval = true; 02740 } 02741 02742 02743 if (!configData.temporalSmoothing) { 02744 lastMedian = -1.0; 02745 } 02746 02747 configData.verboseMode = config.verboseMode; 02748 02749 configData.maxIntensityChange = config.maxShift; 02750 configData.maxPastMeans = config.temporalMemory; 02751 02752 configData.syncDiff = config.syncDiff; 02753 02754 configData.soft_diff_limit = (unsigned long) (configData.syncDiff * 1000000000.0); 02755 02756 configData.loopFlag = config.loopMode; 02757 02758 configData.syncMode = config.syncMode; 02759 02760 configData.normFactor = config.normFactor; 02761 02762 bool updateWriteParams = false; 02763 if ((configData.writeQuality != config.writeQuality) || (configData.outputFormat != config.outputFormat)) { 02764 updateWriteParams = true; 02765 } 02766 02767 if (configData.forceInputGray != config.forceInputGray) { 02768 firstFrame = true; 02769 } 02770 02771 configData.forceInputGray = config.forceInputGray; 02772 02773 configData.fixDudPixels = config.fixDudPixels; 02774 02775 configData.writeQuality = config.writeQuality; 02776 02777 if (config.framerate != 0.0) { 02778 configData.pauseMode = false; 02779 } 02780 02781 if ((config.autoAlpha != configData.autoAlpha) || ((!config.autoAlpha) && (config.alpha != configData.alpha))) { 02782 02783 configData.autoAlpha = config.autoAlpha; 02784 configData.alpha = config.alpha; 02785 02786 alphaChanged = true; 02787 02788 //ROS_WARN("Updating map..."); 02789 updateMap(); 02790 02791 /* 02792 Rect* validPixROI = 0; 02793 globalCameraInfo.newCamMat = getOptimalNewCameraMatrix(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.cameraSize, configData.alpha, globalCameraInfo.cameraSize, validPixROI, centerPrincipalPoint); 02794 02795 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.R, globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02796 */ 02797 02798 } else { 02799 02800 //HGH 02801 if (configData.alpha != config.alpha){ 02802 if (configData.wantsToAddExtrinsics){ 02803 getRectification(); 02804 updateCameraInfoExtrinsics(); 02805 } 02806 } 02807 02808 configData.alpha = config.alpha; 02809 } 02810 02811 fusionFactor = config.fusionFactor; 02812 02813 //ROS_WARN("Progressing..."); 02814 02815 if (config.framerate < 0.0) { 02816 02817 if (configData.pollMode) { 02818 02819 ROS_WARN("Invalid framerate (%f) so switching to capture mode.", config.framerate); 02820 configData.framerate = DEFAULT_READ_RATE; 02821 configData.pollMode = false; 02822 configData.captureMode = true; 02823 02824 } else if (configData.readMode) { 02825 02826 ROS_WARN("Invalid framerate (%f) so defaulting to (%f).", config.framerate, DEFAULT_READ_RATE); 02827 configData.framerate = DEFAULT_READ_RATE; 02828 02829 } else if (configData.loadMode) { 02830 02831 ROS_WARN("Invalid framerate (%f) so defaulting to (%f).", config.framerate, DEFAULT_READ_RATE); 02832 configData.framerate = DEFAULT_READ_RATE; 02833 02834 } else if (configData.resampleMode) { 02835 02836 ROS_WARN("Invalid framerate (%f) so switching to subscribe mode.", config.framerate); 02837 configData.framerate = DEFAULT_READ_RATE; 02838 configData.resampleMode = false; 02839 configData.subscribeMode = true; 02840 02841 } 02842 02843 timer.setPeriod(ros::Duration(1.0 / DEFAULT_READ_RATE)); 02844 02845 } else { 02846 02847 if (configData.captureMode) { 02848 02849 ROS_WARN("Specified framerate (%f) so switching to poll mode.", config.framerate); 02850 configData.framerate = config.framerate; 02851 configData.captureMode = false; 02852 configData.pollMode = true; 02853 02854 } else if (configData.subscribeMode) { 02855 02856 ROS_WARN("Specified framerate (%f) so switching to resample mode.", config.framerate); 02857 configData.framerate = config.framerate; 02858 configData.subscribeMode = false; 02859 configData.resampleMode = true; 02860 02861 } 02862 02863 if (config.framerate > 0.0) { 02864 timer.setPeriod(ros::Duration(1.0 / config.framerate)); 02865 } else { 02866 configData.pauseMode = true; 02867 timer.setPeriod(ros::Duration(1.0 / 1.0)); 02868 } 02869 02870 02871 } 02872 02873 if (config.inputDatatype != configData.inputDatatype) { 02874 if (configData.readMode) { 02875 ROS_WARN("You cannot change the bit-reading mode mid-stream. Consider restarting."); 02876 } else { 02877 ROS_WARN("about to release device..."); 02878 releaseDevice(); 02879 ROS_WARN("device released..."); 02880 configData.inputDatatype = config.inputDatatype; 02881 ROS_WARN("Changing to (%d)", configData.inputDatatype); 02882 setupDevice(); 02883 } 02884 02885 } 02886 02887 configData.filterMode = config.filterMode; 02888 configData.filterParam = config.filterParam; 02889 02890 configData.maxReadAttempts = config.maxReadAttempts; 02891 02892 configData.normMode = config.normMode; 02893 02894 bool wantsToRefreshCameras = false; 02895 02896 if (config.output16bit && !configData.output16bitFlag) { 02897 configData.output16bitFlag = true; 02898 wantsToRefreshCameras = true; 02899 } else if (!config.output16bit && configData.output16bitFlag) { 02900 configData.output16bitFlag = false; 02901 wantsToRefreshCameras = true; 02902 } 02903 02904 if (config.output8bit && !configData.output8bitFlag) { 02905 configData.output8bitFlag = true; 02906 wantsToRefreshCameras = true; 02907 } else if (!config.output8bit && configData.output8bitFlag){ 02908 configData.output8bitFlag = false; 02909 wantsToRefreshCameras = true; 02910 } 02911 02912 if (config.outputColor && !configData.outputColorFlag) { 02913 configData.outputColorFlag = true; 02914 wantsToRefreshCameras = true; 02915 } else if (!config.outputColor && configData.outputColorFlag) { 02916 configData.outputColorFlag = false; 02917 wantsToRefreshCameras = true; 02918 } 02919 02920 if (wantsToRefreshCameras) { 02921 refreshCameraAdvertisements(); 02922 } 02923 02924 getMapping(config.map, config.extremes, configData.mapCode, configData.mapParam); 02925 colourMap.load_standard(configData.mapCode, configData.mapParam); 02926 02927 if ((configData.outputFolder != "outputFolder") && (configData.outputFolder != "")) { 02928 02929 if (config.writeImages) { 02930 02931 if (configData.wantsToWrite != config.writeImages) { 02932 02933 // Create folders if necessary 02934 struct stat st; 02935 if(stat(configData.outputFolder.c_str(),&st) != 0) { 02936 char folderCommand[256]; 02937 sprintf(folderCommand, "mkdir -p %s", configData.outputFolder.c_str()); 02938 int res = system(folderCommand); 02939 02940 if (res == 0) { 02941 ROS_WARN("system() call returned 0..."); 02942 } 02943 } 02944 02945 } 02946 02947 } 02948 02949 configData.wantsToWrite = config.writeImages; 02950 02951 if (configData.wantsToDumpTimestamps != config.dumpTimestamps) { 02952 02953 if (configData.wantsToDumpTimestamps) { 02954 ofs.open(configData.outputTimeFile.c_str(), fstream::ate); 02955 } else { 02956 ofs.close(); 02957 } 02958 02959 } 02960 02961 configData.wantsToDumpTimestamps = config.dumpTimestamps; 02962 02963 } else { 02964 ROS_WARN("No valid output folder specified..."); 02965 configData.wantsToWrite = false; 02966 configData.wantsToDumpTimestamps = false; 02967 } 02968 02969 //HGH 02970 configData.wantsToRectify = config.rectifyImages; 02971 02972 if (config.undistortImages) { 02973 //if (map1.rows == 0) { 02974 //HGH initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.R, globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02975 //HGH 02976 if (configData.wantsToAddExtrinsics){ 02977 if (config.rectifyImages){ 02978 if (configData.camera_number == 0){ 02979 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalExtrinsicsData.R0, globalExtrinsicsData.P0, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02980 }else if (configData.camera_number == 1){ 02981 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalExtrinsicsData.R1, globalExtrinsicsData.P1, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02982 } 02983 //initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, globalCameraInfo.R, globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_16SC2/*CV_32FC1*/, map1, map2); 02984 }else{ 02985 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, Mat(), globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02986 } 02987 }else{ 02988 initUndistortRectifyMap(globalCameraInfo.cameraMatrix, globalCameraInfo.distCoeffs, Mat(), globalCameraInfo.newCamMat, globalCameraInfo.cameraSize, CV_32FC1, map1, map2); 02989 } 02990 // } 02991 } 02992 02993 configData.wantsToUndistort = config.undistortImages; 02994 02995 configData.wantsToRemoveDuplicates = config.removeDuplicates; 02996 02997 configData.outputFormat = config.outputFormat; 02998 02999 //ROS_ERROR("configData.outputFormat = %d", configData.outputFormat); 03000 03001 if (configData.outputFormat == 0) { 03002 configData.outputFormatString = "jpg"; 03003 } else if (configData.outputFormat == 1) { 03004 configData.outputFormatString = "pgm"; 03005 } else if (configData.outputFormat == 2) { 03006 configData.outputFormatString = "bmp"; 03007 } else if (configData.outputFormat == 3) { 03008 configData.outputFormatString = "ppm"; 03009 } else if (configData.outputFormat == 4) { 03010 configData.outputFormatString = "png"; 03011 } 03012 03013 if (updateWriteParams) { 03014 configData.outputFileParams.clear(); 03015 int val; 03016 if (configData.outputFormatString == "png") { 03017 configData.outputFileParams.push_back(CV_IMWRITE_PNG_COMPRESSION); 03018 val = int((1.0-configData.writeQuality) * 9.0); 03019 configData.outputFileParams.push_back(val); 03020 } else if (configData.outputFormatString == "jpg") { 03021 configData.outputFileParams.push_back(CV_IMWRITE_JPEG_QUALITY); 03022 val = int(configData.writeQuality * 100.0); 03023 configData.outputFileParams.push_back(val); 03024 } 03025 //ROS_INFO("Write quality: (%d)", val); 03026 } 03027 03028 //ROS_ERROR("configData.outputFormatString = %s", configData.outputFormatString.c_str()); 03029 03030 if (config.outputType == 0) { 03031 configData.outputType = "CV_8UC1"; 03032 } else if (config.outputType == 1) { 03033 configData.outputType = "CV_8UC3"; 03034 if (configData.outputFormatString == "pgm") { 03035 ROS_WARN("PGM cannot write as CV_8UC3..."); 03036 } 03037 } else if (config.outputType == 2) { 03038 configData.outputType = "CV_16UC1"; 03039 if ((configData.outputFormatString == "jpg") || (configData.outputFormatString == "bmp")) { 03040 ROS_WARN("JPG/BMP cannot write as CV_16UC1..."); 03041 } 03042 } 03043 03044 //HGH 03045 if (configData.drawReticle != config.drawReticle){ 03046 ROS_INFO("config.drawReticle = (%s)", config.drawReticle ? "true" : "false" ); 03047 } 03048 configData.drawReticle = config.drawReticle; 03049 03050 if (!firstServerCallbackProcessed) { 03051 firstServerCallbackProcessed = true; 03052 } 03053 03054 if (configData.verboseMode) { ROS_INFO("Reconfigure request complete..."); } 03055 } 03056 03057 int getMapIndex(string mapping) { 03058 03059 int map; 03060 03061 if (mapping == "GRAYSCALE") { 03062 map = 0; 03063 } else if (mapping == "CIECOMP") { 03064 map = 1; 03065 } else if (mapping == "BLACKBODY") { 03066 map = 2; 03067 } else if (mapping == "RAINBOW") { 03068 map = 3; 03069 } else if (mapping == "IRON") { 03070 map = 4; 03071 } else if (mapping == "BLUERED") { 03072 map = 5; 03073 } else if (mapping == "JET") { 03074 map = 6; 03075 } else if (mapping == "ICE") { 03076 map = 7; 03077 } else if (mapping == "ICEIRON") { 03078 map = 8; 03079 } else if (mapping == "ICEFIRE") { 03080 map = 9; 03081 } else if (mapping == "REPEATED") { 03082 map = 10; 03083 } else if (mapping == "HIGHLIGHTED") { 03084 map = 11; 03085 } else { 03086 map = 0; 03087 } 03088 03089 return map; 03090 } 03091 03092 int streamerNode::mygetch() { 03093 struct termios oldt,newt; 03094 int ch; 03095 tcgetattr( STDIN_FILENO, &oldt ); 03096 newt = oldt; 03097 newt.c_lflag &= ~( ICANON | ECHO ); 03098 tcsetattr( STDIN_FILENO, TCSANOW, &newt ); 03099 ch = getchar(); 03100 tcsetattr( STDIN_FILENO, TCSANOW, &oldt ); 03101 return ch; 03102 } 03103 03104 int streamerNode::open_port() { 03105 int fd; /* File descriptor for the port */ 03106 03107 03108 fd = open(configData.portAddress.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); 03109 if (fd == -1) 03110 { /* Could not open the port */ 03111 fprintf(stderr, "open_port: Unable to open /dev/ttyS1 - %s\n", 03112 strerror(errno)); 03113 } 03114 return (fd); 03115 } 03116 03117 bool streamerNode::configureSerialComms() { 03118 03119 03120 struct termios options; 03121 03122 mainfd = open_port(); 03123 03124 fcntl(mainfd, F_SETFL, FNDELAY); /* Configure port reading */ 03125 /* Get the current options for the port */ 03126 tcgetattr(mainfd, &options); 03127 cfsetispeed(&options, B115200); /* Set the baud rates to 115200 */ 03128 cfsetospeed(&options, B115200); 03129 03130 /* Enable the receiver and set local mode */ 03131 options.c_cflag |= (CLOCAL | CREAD); 03132 options.c_cflag &= ~PARENB; /* Mask the character size to 8 bits, no parity */ 03133 options.c_cflag |= CSTOPB; 03134 options.c_cflag &= ~CSIZE; 03135 options.c_cflag |= CS8; /* Select 8 data bits */ 03136 options.c_cflag &= ~CRTSCTS; /* Disable hardware flow control */ 03137 03138 /* Enable data to be processed as raw input */ 03139 options.c_lflag &= ~(ICANON | ECHO | ISIG); 03140 03141 /* Set the new options for the port */ 03142 tcsetattr(mainfd, TCSANOW, &options); 03143 03144 // Ensure shutter is open... 03145 03146 03147 03148 { 03149 sprintf(serialCommand, "open\r"); 03150 03151 int bytesToWrite = 0; 03152 03153 while (serialCommand[bytesToWrite] != '\r') { 03154 bytesToWrite++; 03155 } 03156 bytesToWrite++; 03157 03158 int n; 03159 //char buff[256]; 03160 03161 ROS_INFO("SerialComms: Opening shutter with (%d) %s", bytesToWrite, serialCommand); 03162 n = write(mainfd, serialCommand, bytesToWrite); 03163 if (n!=bytesToWrite) puts("write() failed!\n"); 03164 } 03165 03166 { 03167 // Trying to clear serial comms buffer... 03168 int n; 03169 char buff[256]; 03170 n = read(mainfd, buff, 256); 03171 //ROS_WARN("Message received = %s\n", buff); 03172 } 03173 03174 int statusNum; 03175 03176 03177 03178 if (configData.disableSkimming) { 03179 // Check current SKIMACTIVE status 03180 sprintf(serialCommand, "SKIMACTIVE\r"); 03181 03182 int bytesToWrite = 0; 03183 03184 while (serialCommand[bytesToWrite] != '\r') { 03185 bytesToWrite++; 03186 } 03187 bytesToWrite++; 03188 03189 int n; 03190 03191 ROS_INFO("SerialComms: Verifying SKIMACTIVE status (%s) ...", serialCommand); 03192 n = write(mainfd, serialCommand, bytesToWrite); 03193 if (n!=bytesToWrite) { 03194 ROS_ERROR("write() failed!"); 03195 } 03196 03197 ros::Duration(1.0).sleep(); 03198 03199 char buff[256]; 03200 n = read(mainfd, buff, 256); 03201 //ROS_WARN("Message received = (%s)\n", buff); 03202 //printf("%s\n", buff); 03203 03204 //istringstream ss_buff( &buff[103]); 03205 03206 statusNum = atof(&buff[17]); 03207 ROS_INFO("SKIMACTIVE status = (%d)\n", statusNum); 03208 03209 } 03210 03211 ros::Duration(1.0).sleep(); 03212 03213 if (configData.disableSkimming) { 03214 sprintf(serialCommand, "SKIMACTIVE 0\r"); 03215 03216 int bytesToWrite = 0; 03217 03218 while (serialCommand[bytesToWrite] != '\r') { 03219 bytesToWrite++; 03220 } 03221 bytesToWrite++; 03222 03223 int n; 03224 //char buff[256]; 03225 03226 ROS_INFO("SerialComms: Disabling mean-shifting with (%d) %s", bytesToWrite, serialCommand); 03227 n = write(mainfd, serialCommand, bytesToWrite); 03228 if (n!=bytesToWrite) puts("write() failed!\n"); 03229 } 03230 03231 { 03232 sprintf(serialCommand, "SAVE\r"); 03233 03234 int bytesToWrite = 0; 03235 03236 while (serialCommand[bytesToWrite] != '\r') { 03237 bytesToWrite++; 03238 } 03239 bytesToWrite++; 03240 03241 int n; 03242 //char buff[256]; 03243 03244 ROS_INFO("SerialComms: Saving current settings..."); 03245 n = write(mainfd, serialCommand, bytesToWrite); 03246 if (n!=bytesToWrite) puts("write() failed!\n"); 03247 } 03248 03249 if (statusNum == 1) { 03250 ROS_ERROR("Camera must now be powercycled: SKIMACTIVE was not originally off."); 03251 return false; 03252 } else { 03253 ROS_WARN("Assuming camera has been powercycled since SKIMACTIVE was saved as off."); 03254 return true; 03255 } 03256 03257 } 03258 03259 03260 float streamerNode::getThermistorReading() { 03261 03262 double retVal; 03263 03264 int n; 03265 char buff[256]; 03266 03267 n = write(mainfd, "THERM\r", 6); 03268 03269 if (n != 6) { 03270 puts("write() failed!\n"); 03271 } 03272 03273 n = read(mainfd, buff, 256); 03274 03275 istringstream ss_buff( &buff[103]); 03276 03277 retVal = atof(&buff[103]); 03278 03279 return retVal; 03280 03281 }