sample code - “get LensInformation”

usage:
   lens
   conv <distance[cm]>
To exit, please enter 'q'.

This sample code is included in SimpleCli.

  1// "use LensInformation" sample
  2#include <chrono>
  3#include <cmath>
  4#include <cstdint>
  5#include <cstdlib>
  6#include <fstream>
  7#include <future>
  8#include <iostream>
  9#include <mutex>
 10#include <sstream>
 11#include <stdexcept>
 12#include <string>
 13#include <thread>
 14#include <vector>
 15
 16#if !defined(__APPLE__)
 17  #if defined(USE_EXPERIMENTAL_FS) // for jetson
 18    #include <experimental/filesystem>
 19    namespace fs = std::experimental::filesystem;
 20  #else
 21    #include <filesystem>
 22    namespace fs = std::filesystem;
 23  #endif
 24#endif
 25
 26#if defined(__APPLE__) || defined(__linux__)
 27  #include <unistd.h>
 28#endif
 29
 30// macro for multibyte character
 31#if defined(_WIN32) || defined(_WIN64)
 32  using CrString = std::wstring;
 33  #define CRSTR(s) L ## s
 34  #define CrCout std::wcout
 35#else
 36  using CrString = std::string;
 37  #define CRSTR(s) s
 38  #define CrCout std::cout
 39#endif
 40
 41
 42#include "CrDeviceProperty.h"
 43#include "CameraRemote_SDK.h"
 44#include "IDeviceCallback.h"
 45#include "CrDebugString.h"   // use CrDebugString.cpp
 46
 47#define PrintError(msg, err) { fprintf(stderr, "Error in %s(%d):" msg ",%s\n", __FUNCTION__, __LINE__, (err ? CrErrorString(err).c_str():"")); }
 48#define GotoError(msg, err) { PrintError(msg, err); goto Error; }
 49
 50bool  m_connected = false;
 51CrString m_modelId;
 52
 53std::mutex m_eventPromiseMutex;
 54std::promise<void>* m_eventPromise = nullptr;
 55void setEventPromise(std::promise<void>* dp)
 56{
 57    std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
 58    m_eventPromise = dp;
 59}
 60
 61class DeviceCallback : public SCRSDK::IDeviceCallback
 62{
 63public:
 64    DeviceCallback() {};
 65    ~DeviceCallback() {};
 66
 67    void OnConnected(SCRSDK::DeviceConnectionVersioin version)
 68    {
 69        CrCout << "Connected to " << m_modelId << "\n";
 70        m_connected = true;
 71        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
 72        if(m_eventPromise) {
 73            m_eventPromise->set_value();
 74            m_eventPromise = nullptr;
 75        }
 76    }
 77
 78    void OnError(CrInt32u error)
 79    {
 80        printf("Connection error:%s\n", CrErrorString(error).c_str());
 81        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
 82        if(m_eventPromise) {
 83            m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
 84            m_eventPromise = nullptr;
 85        }
 86    }
 87
 88    void OnDisconnected(CrInt32u error)
 89    {
 90        CrCout << "Disconnected from " << m_modelId << "\n";
 91        m_connected = false;
 92        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
 93        if(m_eventPromise) {
 94            m_eventPromise->set_value();
 95            m_eventPromise = nullptr;
 96        }
 97    }
 98
 99    void OnCompleteDownload(CrChar* filename, CrInt32u type )
100    {
101        CrCout << "OnCompleteDownload:" << filename << "\n";
102    }
103
104    void OnNotifyContentsTransfer(CrInt32u notify, SCRSDK::CrContentHandle contentHandle, CrChar* filename)
105    {
106        std::cout << "OnNotifyContentsTransfer.\n";
107    }
108
109    void OnWarning(CrInt32u warning)
110    {
111        if (warning == SCRSDK::CrWarning_Connect_Reconnecting) {
112            CrCout << "Reconnecting to " << m_modelId << "\n";
113            return;
114        }
115        std::cout << "OnWarning:" << CrErrorString(warning) << "\n";
116        std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
117        switch(warning) {
118        case SCRSDK::CrWarning_RequestLensInformation_Result_Success:
119            if(m_eventPromise) {
120                m_eventPromise->set_value();
121                m_eventPromise = nullptr;
122            }
123            break;
124        case SCRSDK::CrWarning_RequestLensInformation_Result_DeviceBusy:
125        case SCRSDK::CrWarning_RequestLensInformation_Result_Error:
126            if(m_eventPromise) {
127                m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
128                m_eventPromise = nullptr;
129            }
130            break;
131        }
132    }
133
134    void OnWarningExt(CrInt32u warning, CrInt32 param1, CrInt32 param2, CrInt32 param3) {}
135    void OnLvPropertyChanged() {}
136    void OnLvPropertyChangedCodes(CrInt32u num, CrInt32u* codes) {}
137    void OnPropertyChanged() {}
138    void OnPropertyChangedCodes(CrInt32u num, CrInt32u* codes)
139    {
140        std::cout << "OnPropertyChangedCodes:\n";
141    }
142};
143
144CrString _getModelId(const SCRSDK::ICrCameraObjectInfo* objInfo)
145{
146    CrString id;
147    if (CrString(objInfo->GetConnectionTypeName()) == CRSTR("IP")) {
148        id = CrString(objInfo->GetMACAddressChar());
149    } else {
150        id = CrString((CrChar*)objInfo->GetId());
151    }
152    return CrString(objInfo->GetModel()).append(CRSTR(" (")).append(id).append(CRSTR(")"));
153}
154
155SCRSDK::CrError _getIdPassword(SCRSDK::ICrCameraObjectInfo* objInfo, std::string& fingerprint, std::string& userId, std::string& userPassword)
156{
157    char fpBuff[128] = {0};
158    CrInt32u fpLen = 0;
159    SCRSDK::CrError err = SCRSDK::GetFingerprint(objInfo, fpBuff, &fpLen);
160    if(err) GotoError("", err);
161    fingerprint = std::string(fpBuff, fpLen);
162
163    std::cout << "fingerprint: " << fingerprint.c_str() << "\n";
164    std::cout << "id:";       std::getline(std::cin, userId);
165    std::cout << "password:"; std::getline(std::cin, userPassword);
166    return 0;
167Error:
168    return err;
169}
170
171std::vector<std::string> _split(std::string inputLine, char delimiter)
172{
173    std::vector<std::string> strArray;
174    if (inputLine.empty()) return strArray;
175
176    std::string tmp;
177    std::stringstream ss{inputLine};
178    while (getline(ss, tmp, delimiter)) {
179        strArray.push_back(tmp);
180    }
181    return strArray;
182}
183
184SCRSDK::CrError _getLensInformation(SCRSDK::CrDeviceHandle deviceHandle, SCRSDK::CrLensInformation** lensInfos, uint32_t* numOfList)
185{
186    int result = SCRSDK::CrError_Generic_Unknown;
187    SCRSDK::CrError err = SCRSDK::CrError_None;
188    std::promise<void> eventPromise;
189    std::future<void> eventFuture = eventPromise.get_future();
190
191    setEventPromise(&eventPromise);
192    err = SCRSDK::RequestLensInformation(deviceHandle);
193    if(err) GotoError("", err);
194
195    try{
196        eventFuture.get();
197    } catch(const std::exception&) GotoError("", 0);
198
199    err = SCRSDK::GetLensInformation(deviceHandle, lensInfos, numOfList);
200    if(err || numOfList == 0) GotoError("", err);
201    result = 0;
202Error:
203    setEventPromise(nullptr);
204    return result;
205}
206
207int main(void)
208{
209    int result = -1;
210    SCRSDK::CrError err = SCRSDK::CrError_None;
211    int64_t  m_device_handle = 0;
212    SCRSDK::ICrEnumCameraObjectInfo* enumCameraObjectInfo = nullptr;
213    SCRSDK::ICrCameraObjectInfo* objInfo = nullptr;
214    DeviceCallback deviceCallback;
215    CrInt32u numOfList= 0;
216    SCRSDK::CrLensInformation* lensInfos = nullptr;
217    int iMin=0;
218    int iMax=0;
219
220  #if defined(__APPLE__)
221    #define MAC_MAX_PATH 255
222    char pathBuf[MAC_MAX_PATH] = {0};
223    if(NULL == getcwd(pathBuf, sizeof(pathBuf) - 1)) return 1;
224    CrString path = pathBuf;
225  #else
226    CrString path = fs::current_path().native();
227  #endif
228
229    bool boolRet = SCRSDK::Init();
230    if(!boolRet) GotoError("", 0);
231
232    // enumeration
233    {
234        uint32_t count = 0;
235        uint32_t index = 1;
236
237        err = SCRSDK::EnumCameraObjects(&enumCameraObjectInfo, 3/*timeInSec*/);
238        if(err || !enumCameraObjectInfo) GotoError("no camera", err);
239
240        count = enumCameraObjectInfo->GetCount();
241        if(count >= 2) {
242            for (uint32_t i = 0; i < count; ++i) {
243                auto* info = enumCameraObjectInfo->GetCameraObjectInfo(i);
244                CrCout << '[' << i + 1 << "] " << _getModelId(info) << "\n";
245            }
246
247            std::string inputLine;
248            std::cout << "select camera:"; std::getline(std::cin, inputLine);
249            try { index = stoi(inputLine); } catch(const std::exception&) { GotoError("", 0); }
250            if(index < 1 || index > count) GotoError("", 0);
251        }
252        objInfo = (SCRSDK::ICrCameraObjectInfo*)enumCameraObjectInfo->GetCameraObjectInfo(index - 1);
253        m_modelId = _getModelId(objInfo);
254    }
255
256    // connect
257    {
258        std::string  fingerprint = "";
259        std::string  userId = "";
260        std::string  userPassword = "";
261        std::promise<void> eventPromise;
262        std::future<void> eventFuture = eventPromise.get_future();
263
264        if (objInfo->GetSSHsupport() == SCRSDK::CrSSHsupport_ON) {
265            err = _getIdPassword(objInfo, fingerprint, userId, userPassword); if(err) goto Error;
266        }
267
268        setEventPromise(&eventPromise);
269        err = SCRSDK::Connect(objInfo, &deviceCallback, &m_device_handle,
270            SCRSDK::CrSdkControlMode_Remote,
271            SCRSDK::CrReconnecting_ON,
272            userId.c_str(), userPassword.c_str(), fingerprint.c_str(), (uint32_t)fingerprint.size());
273        if(err) GotoError("", err);
274
275    //  std::future_status status = eventFuture.wait_for(std::chrono::milliseconds(3000));
276    //  if(status != std::future_status::ready) GotoError("timeout",0);
277        try{
278            eventFuture.get();
279        } catch(const std::exception&) GotoError("", 0);
280    }
281
282    // set work directory
283    {
284        CrCout << "path=" << path.data() << "\n";
285        err = SCRSDK::SetSaveInfo(m_device_handle, const_cast<CrChar*>(path.data()), const_cast<CrChar*>(CRSTR("DSC")), -1/*startNo*/);
286        if(err) GotoError("", err);
287    }
288
289    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
290
291    std::cout << "usage:\n";
292    std::cout << "   lens\n";
293    std::cout << "   conv <distance[cm]>\n";
294    std::cout << "To exit, please enter 'q'.\n";
295
296    while(1) {
297        std::string inputLine;
298        std::getline(std::cin, inputLine);
299        std::vector<std::string> args = _split(inputLine, ' ');
300
301        if(args.size() == 0) {
302
303        } else if(args[0] == "lens") {
304            int i;
305            if(lensInfos) SCRSDK::ReleaseLensInformation(m_device_handle, lensInfos);
306
307            err = _getLensInformation(m_device_handle, &lensInfos, &numOfList);
308            if(err) goto Error;
309            std::cout << "OK\n";
310
311            //for(i = 0; i < numOfList; i++)
312            //  printf("%d, %d, %d, %d\n", lensInfos[i].dataVersion, lensInfos[i].type, lensInfos[i].normalizedValue, lensInfos[i].focusPosition);
313
314            // check "meter" tableRange
315            iMin = -1;
316            iMax = numOfList-1;
317            for(i = 0; i < (int)numOfList; i++) {
318                if(lensInfos[i].type == SCRSDK::CrLensInformationType_Meter) {
319                    if(iMin == -1) {
320                        iMin = i;
321                    }
322                } else if(lensInfos[i].type == SCRSDK::CrLensInformationType_Feet) {
323                    if(iMin != -1) {
324                        iMax = i-1;
325                        break;
326                    }
327                }
328            }
329            //printf("%d-%d(%d)\n", iMin, iMax, numOfList);
330        } else if(args[0] == "conv" && args.size() >= 2) {
331            uint32_t distance;
332            int i;
333            try { distance = stoi(args[1]); } catch(const std::exception&) { GotoError("", 0); }
334            if(!lensInfos) continue;
335
336            if(distance <= lensInfos[iMin].focusPosition) {
337                printf("%d\n", lensInfos[iMin].normalizedValue);
338
339            } else if(distance >= lensInfos[iMax].focusPosition) {
340                printf("%d\n", lensInfos[iMax].normalizedValue);
341
342            } else {
343                for(i = iMin; i <= iMax-1; i++) {
344                    if(distance <= lensInfos[i+1].focusPosition) {
345                        // log-log linear regression
346                        double lnx1 = std::log(lensInfos[i+0].focusPosition);
347                        double lnx2 = std::log(lensInfos[i+1].focusPosition);
348                        double lny1 = std::log(lensInfos[i+0].normalizedValue);
349                        double lny2 = std::log(lensInfos[i+1].normalizedValue);
350                        double k = (lny2 - lny1) / (lnx2 - lnx1);
351                        double lnx = std::log(distance);
352                        double lny = (lnx - lnx1) * k + lny1;
353                        int32_t y = (int32_t)std::round(std::exp(lny));
354                        printf("%d\n", y);
355                        break;
356                    }
357                }
358            }
359        } else if(args[0] == "q" || args[0] == "Q") {
360            break;
361        } else {
362            std::cout << "unknown command\n";
363        }
364    }
365
366    result = 0;
367Error:
368    if(lensInfos) SCRSDK::ReleaseLensInformation(m_device_handle, lensInfos);
369    if(enumCameraObjectInfo) enumCameraObjectInfo->Release();
370
371    if(m_connected) {
372        std::promise<void> eventPromise;
373        std::future<void> eventFuture = eventPromise.get_future();
374        setEventPromise(&eventPromise);
375        SCRSDK::Disconnect(m_device_handle);
376        eventFuture.wait_for(std::chrono::milliseconds(3000));
377    }
378    if(m_device_handle) SCRSDK::ReleaseDevice(m_device_handle);
379    SCRSDK::Release();
380
381    return result;
382}