Loading sdk/build/miphoto/miphoto-exec −4 KiB (9.38 MiB) File changed.No diff preview for this file type. View original file View changed file sdk/src/codes.cpp +1 −4 Original line number Diff line number Diff line #include "codes.h" using namespace std; using namespace std; int Codes::getSpeedMs(Speed speed) { Loading sdk/src/codes.h +1 −3 Original line number Diff line number Diff line Loading @@ -2,8 +2,6 @@ #define CODES_H #include <string> #include <algorithm> #include <vector> /** * Class containing various constant (and related functions) used for comunication with camera Loading Loading @@ -40,7 +38,7 @@ public: QuerySessionHolder = 1793, PowerOff = 6155, GetSetAutoPowerOff = 6151, //TODO GetSetAutoPowerOff = 6151, CameraOverheated = 6158 Loading sdk/src/commander.cpp +21 −23 Original line number Diff line number Diff line #include <cerrno> #include <climits> #include <cmath> #include <iostream> #include <vector> #include <thread> #include <iterator> #include <experimental/filesystem> #include "commander.h" #include "server.h" #include "exif.h" using namespace std; Commander::Commander() : _isReceiverRunning(false), _sock(TcpSocket(&_reader, this)), _isReceiverEnabled(false), _sock(TcpSocket(this)), _bracketingStep(0), _bracketingHalfCount(0), Loading Loading @@ -518,13 +516,13 @@ bool Commander::setPhotoWB(Codes::ParamWB wb) return true; } bool Commander::shootNormal() bool Commander::shootNormal(bool notify) { string path; return shootNormal(path); return shootNormal(notify, path); } bool Commander::shootNormal(string& imagePath, bool notify) bool Commander::shootNormal(bool notify, string& imagePath) { cout << "Taking picture" << endl; vector<shared_ptr<DynamicJsonDocument>> vectorJsonPtr; Loading Loading @@ -826,14 +824,14 @@ void Commander::runReceiver() { // wait until receiver should be running { unique_lock ulock(_isReceiverRunningMutex); _isReceiverRunningCV.wait(ulock, [this](){return _isReceiverRunning;}); unique_lock ulock(_isReceiverEnabledMutex); _isReceiverEnabledCV.wait(ulock, [this](){return _isReceiverEnabled;}); } // if cannot connect or _sock.runReceiver() exits correctly, stop receiver if (!connectSocket() || _sock.runReceiver()) { stopReceiver(); disableReceiver(); } else { Loading @@ -844,27 +842,27 @@ void Commander::runReceiver() } } void Commander::startReceiver() void Commander::enableReceiver() { cout << "Starting receiver" << endl; lock_guard lock(_isReceiverRunningMutex); _isReceiverRunning = true; _isReceiverRunningCV.notify_all(); lock_guard lock(_isReceiverEnabledMutex); _isReceiverEnabled = true; _isReceiverEnabledCV.notify_all(); } void Commander::stopReceiver() void Commander::disableReceiver() { cout << "Stopping receiver" << endl; lock_guard lock(_isReceiverRunningMutex); _isReceiverRunning = false; lock_guard lock(_isReceiverEnabledMutex); _isReceiverEnabled = false; _server->wsClose(); } bool Commander::isReceiverRunning() bool Commander::isReceiverEnabled() { lock_guard lock(_isReceiverRunningMutex); return _isReceiverRunning; lock_guard lock(_isReceiverEnabledMutex); return _isReceiverEnabled; } Loading Loading @@ -1057,7 +1055,7 @@ bool Commander::measureExposureExif(double& speed, double& iso) // Take one picture string path; if (!shootNormal(path, false)) if (!shootNormal(false, path)) { cerr << "Couldn't take photo." << endl; return false; Loading sdk/src/commander.h +151 −31 Original line number Diff line number Diff line #ifndef COMMANDER_H #define COMMANDER_H #include <map> #include <queue> #include <memory> #include <thread> Loading @@ -9,24 +8,51 @@ #include <ArduinoJson.h> #include "tcpSocket.h" #include "customReader.h" #include "codes.h" #include "server.h" class Server; /** * Class responsible for running commands received from user on the cammera. * Enqueues commands from user, send commands to cammera, checks responses * and stores information about camera state. * * To be able to run properly, one has to create also an instance of class Server and give it * a pointer to the Commander instance, then start both instances by running start() method on them */ class Commander { public: /** * Construct new Commander */ Commander(); /** * Start executing commands from user and reading response from camera. * An instance of Commander can do nothing until an instance of Server (with pointer to Commander) * has been created and started by running its start() method */ void start(); void startReceiver(); void stopReceiver(); /** * * Check whether commander is shooting * * @return true iff commander is currently executing a shooting command */ bool isShooting(); /** * Push a command in the queue. * * @param cmd String containing command in one of following formats: * @param cmd {"cmd": "APP_OFF"} - Disconnect the MiPhoto app from the camera. * @param cmd {"cmd": "POWER_OFF"} - Turn camera off. * @param cmd {"cmd": "WIFI_OFF"} - Turn off WiFi. * @param cmd {"cmd": "STOP"} - Stop shooting. * @param cmd {"cmd": "SHOOT", "speed":_, "iso":_, "bracketingHalf":_, "bracketingEV":_, "timelapseCount":_, "timelapseInterval":_, "photoWB":_} - Shoot. */ void enqueueCommand(const std::string& cmd); private: Loading @@ -34,19 +60,20 @@ private: friend class TcpSocket; std::thread _receiverThr; // thread for receiving messages from camera bool _isReceiverRunning; std::mutex _isReceiverRunningMutex; std::condition_variable _isReceiverRunningCV; std::thread _executorThr; // thread for executiong commands from user std::queue<std::shared_ptr<DynamicJsonDocument>> _executorQueue; bool _isReceiverEnabled; std::mutex _isReceiverEnabledMutex; std::condition_variable _isReceiverEnabledCV; std::thread _executorThr; // thread executiong commands from user std::queue<std::shared_ptr<DynamicJsonDocument>> _executorQueue; //Queue with commands std::mutex _executorQueueMutex; std::condition_variable _executorQueueCV; CustomReader _reader; TcpSocket _sock; int _token; int _autoPowerOff; TcpSocket _sock; // Scoket for comunication with the camera int _token; // Token used to identify connection with camera int _autoPowerOff; // Time in minutes before camera turns off when idle Codes::ISO _iso; Codes::Speed _speed; Loading @@ -54,9 +81,13 @@ private: Codes::ParamMode _mode; size_t _bracketingStep; size_t _bracketingHalfCount; bool _bracketingVectorInvalid;; std::vector<Codes::Speed> _bracketingVector; size_t _bracketingHalfCount; // number of pictures taken with bracketing is '2 * _bracketingHalfCount + 1' /** * Indicate that _bracketingVector has to be recomputed * (i.e. shutter speed or any parameter of bracketing changes, or shutter speed is auto) */ bool _bracketingVectorInvalid; std::vector<Codes::Speed> _bracketingVector; // vector containing shutter speeds used for bracketing Codes::ParamBracketingBuiltIn _bracketingBuiltIn; Loading @@ -66,6 +97,7 @@ private: bool _isShooting; std::mutex _isShootingMutex; // Flag telling commander to stop shooting bool _stopShooting; std::mutex _stopShootingMutex; std::condition_variable _stopShootingCV; Loading @@ -78,36 +110,82 @@ private: static std::vector<std::pair<Codes::ISO, double>> isoOrderedMapping; // Blocking function which starts executing commands from _executorQueue void runExecutor(); /** * Start shooting with parameters given by json * * @param json contains parameters for shooting * @return true iff shooting was successful */ bool executorShoot(std::shared_ptr<DynamicJsonDocument> json); // Blocking function which starts receiving messages from camera void runReceiver(); bool isReceiverEnabled(); // Enable receiving messages from camera via socket void enableReceiver(); // Disable receiving messages from camera via socket void disableReceiver(); /** * Create socket and connect to camera * * @return true iff connecting was successful */ bool connectSocket(); // Close socket used for communication with camera void disconnectSocket(); /** * Estabilish connection with commander by "handshaking" * (i.e. request a token from camera & get required settings) * * @return true iff connecting was successful */ bool connectCommander(); void disconnectCommander(); void invalidateCachedSettings(); void runExecutor(); bool executorShoot(std::shared_ptr<DynamicJsonDocument> json); void runReceiver(); bool isReceiverRunning(); // Invalidate camera settings that are stored locally void invalidateCachedSettings(); /** * Generate string with json in format: * {"token":_token, "msg_id": msg, "param":param} */ template <typename T> std::string generateJSON(Codes::MsgId msg, T param); std::string generateJSON(Codes::MsgId msg); /** * Generate string with json in format: * {"token":_token, "msg_id": msg} */ std::string generateJSON(Codes::MsgId msg); ////// Commands //////¨ ////////// Commands ////////// bool shoot(); // set the _stopShooting variable void stopShooting(bool stop = true); // turn off/on wifi bool wifiControl(bool on); bool powerOff(); bool setAutoPowerOff(size_t minutes); bool getAutoPowerOff(); bool shootNormal(); bool shootNormal(std::string& imagePath, bool notify = true); // take single picture bool shootNormal(bool notify = true); bool shootNormal(bool notify, std::string& imagePath); bool shootBracketing(); bool shootBracketing(const std::vector<Codes::Speed>& speeds); Loading @@ -128,13 +206,27 @@ private: bool setPhotoWB(Codes::ParamWB wb); bool setMode(Codes::ParamMode mode); /** * Request a token from camera and save it. * Token will then be used as identifiaction for every message between camera & commander * * @return true iff request was successful */ bool getToken(); /** * Request common settings from camera and save them. * Currently only ISO and shutter speed is being saved. * * @return true iff getting settings was successful */ bool getCameraSettings(); bool getMode(); bool getAutoTurnOff();//TODO bool getMode(); // Photo/video // send message that reassures the camera that we sill want to be connected bool holdSession(); ////////////////////////////// /** * Set commander's bracketing settings Loading Loading @@ -174,17 +266,45 @@ private: size_t halfCount, size_t evStep); /** * Take picture, read ISO & speed from exif data * * @param speed * @param iso * @return true iff measuring was successful */ bool measureExposureExif(double& speed, double& iso); /** * Find supported speed that is closest to the one passed as parameter. * Speed if first adjusted by 'inputError' exposure steps, then the closest supported one is found. * * @param speed Speed we want to find between the supported ones * @param inputError exposure steps to adjust the speed before search * @param outputError The difference [in exposure steps] between adjusted speed and the selected one * @return iterator to the speed found in speedOrderedMapping */ std::vector<std::pair<Codes::Speed, double>>::iterator findClosestSpeed( double speed, double inputError, double& outputError); /** * Find supported ISO that is closest to the one passed as parameter. * ISO if first adjusted by 'inputError' exposure steps, then closest supported one is found. * * @param iso ISO we want to find between the supported ones * @param inputError exposure steps to adjust the ISO before search * @param outputError The difference [in exposure steps] between adjusted ISO and the selected one * @return iterator to the speed found in isoOrderedMapping */ std::vector<std::pair<Codes::ISO, double>>::iterator findClosestISO( double iso, double inputError, double& outputError); // check if vector iterator is in valid range // check if vector iterator is in valid range [begin, end) template <typename T> inline static bool isValidIter(typename std::vector<T>::iterator it, const std::vector<T>& vector) { Loading Loading
sdk/build/miphoto/miphoto-exec −4 KiB (9.38 MiB) File changed.No diff preview for this file type. View original file View changed file
sdk/src/codes.cpp +1 −4 Original line number Diff line number Diff line #include "codes.h" using namespace std; using namespace std; int Codes::getSpeedMs(Speed speed) { Loading
sdk/src/codes.h +1 −3 Original line number Diff line number Diff line Loading @@ -2,8 +2,6 @@ #define CODES_H #include <string> #include <algorithm> #include <vector> /** * Class containing various constant (and related functions) used for comunication with camera Loading Loading @@ -40,7 +38,7 @@ public: QuerySessionHolder = 1793, PowerOff = 6155, GetSetAutoPowerOff = 6151, //TODO GetSetAutoPowerOff = 6151, CameraOverheated = 6158 Loading
sdk/src/commander.cpp +21 −23 Original line number Diff line number Diff line #include <cerrno> #include <climits> #include <cmath> #include <iostream> #include <vector> #include <thread> #include <iterator> #include <experimental/filesystem> #include "commander.h" #include "server.h" #include "exif.h" using namespace std; Commander::Commander() : _isReceiverRunning(false), _sock(TcpSocket(&_reader, this)), _isReceiverEnabled(false), _sock(TcpSocket(this)), _bracketingStep(0), _bracketingHalfCount(0), Loading Loading @@ -518,13 +516,13 @@ bool Commander::setPhotoWB(Codes::ParamWB wb) return true; } bool Commander::shootNormal() bool Commander::shootNormal(bool notify) { string path; return shootNormal(path); return shootNormal(notify, path); } bool Commander::shootNormal(string& imagePath, bool notify) bool Commander::shootNormal(bool notify, string& imagePath) { cout << "Taking picture" << endl; vector<shared_ptr<DynamicJsonDocument>> vectorJsonPtr; Loading Loading @@ -826,14 +824,14 @@ void Commander::runReceiver() { // wait until receiver should be running { unique_lock ulock(_isReceiverRunningMutex); _isReceiverRunningCV.wait(ulock, [this](){return _isReceiverRunning;}); unique_lock ulock(_isReceiverEnabledMutex); _isReceiverEnabledCV.wait(ulock, [this](){return _isReceiverEnabled;}); } // if cannot connect or _sock.runReceiver() exits correctly, stop receiver if (!connectSocket() || _sock.runReceiver()) { stopReceiver(); disableReceiver(); } else { Loading @@ -844,27 +842,27 @@ void Commander::runReceiver() } } void Commander::startReceiver() void Commander::enableReceiver() { cout << "Starting receiver" << endl; lock_guard lock(_isReceiverRunningMutex); _isReceiverRunning = true; _isReceiverRunningCV.notify_all(); lock_guard lock(_isReceiverEnabledMutex); _isReceiverEnabled = true; _isReceiverEnabledCV.notify_all(); } void Commander::stopReceiver() void Commander::disableReceiver() { cout << "Stopping receiver" << endl; lock_guard lock(_isReceiverRunningMutex); _isReceiverRunning = false; lock_guard lock(_isReceiverEnabledMutex); _isReceiverEnabled = false; _server->wsClose(); } bool Commander::isReceiverRunning() bool Commander::isReceiverEnabled() { lock_guard lock(_isReceiverRunningMutex); return _isReceiverRunning; lock_guard lock(_isReceiverEnabledMutex); return _isReceiverEnabled; } Loading Loading @@ -1057,7 +1055,7 @@ bool Commander::measureExposureExif(double& speed, double& iso) // Take one picture string path; if (!shootNormal(path, false)) if (!shootNormal(false, path)) { cerr << "Couldn't take photo." << endl; return false; Loading
sdk/src/commander.h +151 −31 Original line number Diff line number Diff line #ifndef COMMANDER_H #define COMMANDER_H #include <map> #include <queue> #include <memory> #include <thread> Loading @@ -9,24 +8,51 @@ #include <ArduinoJson.h> #include "tcpSocket.h" #include "customReader.h" #include "codes.h" #include "server.h" class Server; /** * Class responsible for running commands received from user on the cammera. * Enqueues commands from user, send commands to cammera, checks responses * and stores information about camera state. * * To be able to run properly, one has to create also an instance of class Server and give it * a pointer to the Commander instance, then start both instances by running start() method on them */ class Commander { public: /** * Construct new Commander */ Commander(); /** * Start executing commands from user and reading response from camera. * An instance of Commander can do nothing until an instance of Server (with pointer to Commander) * has been created and started by running its start() method */ void start(); void startReceiver(); void stopReceiver(); /** * * Check whether commander is shooting * * @return true iff commander is currently executing a shooting command */ bool isShooting(); /** * Push a command in the queue. * * @param cmd String containing command in one of following formats: * @param cmd {"cmd": "APP_OFF"} - Disconnect the MiPhoto app from the camera. * @param cmd {"cmd": "POWER_OFF"} - Turn camera off. * @param cmd {"cmd": "WIFI_OFF"} - Turn off WiFi. * @param cmd {"cmd": "STOP"} - Stop shooting. * @param cmd {"cmd": "SHOOT", "speed":_, "iso":_, "bracketingHalf":_, "bracketingEV":_, "timelapseCount":_, "timelapseInterval":_, "photoWB":_} - Shoot. */ void enqueueCommand(const std::string& cmd); private: Loading @@ -34,19 +60,20 @@ private: friend class TcpSocket; std::thread _receiverThr; // thread for receiving messages from camera bool _isReceiverRunning; std::mutex _isReceiverRunningMutex; std::condition_variable _isReceiverRunningCV; std::thread _executorThr; // thread for executiong commands from user std::queue<std::shared_ptr<DynamicJsonDocument>> _executorQueue; bool _isReceiverEnabled; std::mutex _isReceiverEnabledMutex; std::condition_variable _isReceiverEnabledCV; std::thread _executorThr; // thread executiong commands from user std::queue<std::shared_ptr<DynamicJsonDocument>> _executorQueue; //Queue with commands std::mutex _executorQueueMutex; std::condition_variable _executorQueueCV; CustomReader _reader; TcpSocket _sock; int _token; int _autoPowerOff; TcpSocket _sock; // Scoket for comunication with the camera int _token; // Token used to identify connection with camera int _autoPowerOff; // Time in minutes before camera turns off when idle Codes::ISO _iso; Codes::Speed _speed; Loading @@ -54,9 +81,13 @@ private: Codes::ParamMode _mode; size_t _bracketingStep; size_t _bracketingHalfCount; bool _bracketingVectorInvalid;; std::vector<Codes::Speed> _bracketingVector; size_t _bracketingHalfCount; // number of pictures taken with bracketing is '2 * _bracketingHalfCount + 1' /** * Indicate that _bracketingVector has to be recomputed * (i.e. shutter speed or any parameter of bracketing changes, or shutter speed is auto) */ bool _bracketingVectorInvalid; std::vector<Codes::Speed> _bracketingVector; // vector containing shutter speeds used for bracketing Codes::ParamBracketingBuiltIn _bracketingBuiltIn; Loading @@ -66,6 +97,7 @@ private: bool _isShooting; std::mutex _isShootingMutex; // Flag telling commander to stop shooting bool _stopShooting; std::mutex _stopShootingMutex; std::condition_variable _stopShootingCV; Loading @@ -78,36 +110,82 @@ private: static std::vector<std::pair<Codes::ISO, double>> isoOrderedMapping; // Blocking function which starts executing commands from _executorQueue void runExecutor(); /** * Start shooting with parameters given by json * * @param json contains parameters for shooting * @return true iff shooting was successful */ bool executorShoot(std::shared_ptr<DynamicJsonDocument> json); // Blocking function which starts receiving messages from camera void runReceiver(); bool isReceiverEnabled(); // Enable receiving messages from camera via socket void enableReceiver(); // Disable receiving messages from camera via socket void disableReceiver(); /** * Create socket and connect to camera * * @return true iff connecting was successful */ bool connectSocket(); // Close socket used for communication with camera void disconnectSocket(); /** * Estabilish connection with commander by "handshaking" * (i.e. request a token from camera & get required settings) * * @return true iff connecting was successful */ bool connectCommander(); void disconnectCommander(); void invalidateCachedSettings(); void runExecutor(); bool executorShoot(std::shared_ptr<DynamicJsonDocument> json); void runReceiver(); bool isReceiverRunning(); // Invalidate camera settings that are stored locally void invalidateCachedSettings(); /** * Generate string with json in format: * {"token":_token, "msg_id": msg, "param":param} */ template <typename T> std::string generateJSON(Codes::MsgId msg, T param); std::string generateJSON(Codes::MsgId msg); /** * Generate string with json in format: * {"token":_token, "msg_id": msg} */ std::string generateJSON(Codes::MsgId msg); ////// Commands //////¨ ////////// Commands ////////// bool shoot(); // set the _stopShooting variable void stopShooting(bool stop = true); // turn off/on wifi bool wifiControl(bool on); bool powerOff(); bool setAutoPowerOff(size_t minutes); bool getAutoPowerOff(); bool shootNormal(); bool shootNormal(std::string& imagePath, bool notify = true); // take single picture bool shootNormal(bool notify = true); bool shootNormal(bool notify, std::string& imagePath); bool shootBracketing(); bool shootBracketing(const std::vector<Codes::Speed>& speeds); Loading @@ -128,13 +206,27 @@ private: bool setPhotoWB(Codes::ParamWB wb); bool setMode(Codes::ParamMode mode); /** * Request a token from camera and save it. * Token will then be used as identifiaction for every message between camera & commander * * @return true iff request was successful */ bool getToken(); /** * Request common settings from camera and save them. * Currently only ISO and shutter speed is being saved. * * @return true iff getting settings was successful */ bool getCameraSettings(); bool getMode(); bool getAutoTurnOff();//TODO bool getMode(); // Photo/video // send message that reassures the camera that we sill want to be connected bool holdSession(); ////////////////////////////// /** * Set commander's bracketing settings Loading Loading @@ -174,17 +266,45 @@ private: size_t halfCount, size_t evStep); /** * Take picture, read ISO & speed from exif data * * @param speed * @param iso * @return true iff measuring was successful */ bool measureExposureExif(double& speed, double& iso); /** * Find supported speed that is closest to the one passed as parameter. * Speed if first adjusted by 'inputError' exposure steps, then the closest supported one is found. * * @param speed Speed we want to find between the supported ones * @param inputError exposure steps to adjust the speed before search * @param outputError The difference [in exposure steps] between adjusted speed and the selected one * @return iterator to the speed found in speedOrderedMapping */ std::vector<std::pair<Codes::Speed, double>>::iterator findClosestSpeed( double speed, double inputError, double& outputError); /** * Find supported ISO that is closest to the one passed as parameter. * ISO if first adjusted by 'inputError' exposure steps, then closest supported one is found. * * @param iso ISO we want to find between the supported ones * @param inputError exposure steps to adjust the ISO before search * @param outputError The difference [in exposure steps] between adjusted ISO and the selected one * @return iterator to the speed found in isoOrderedMapping */ std::vector<std::pair<Codes::ISO, double>>::iterator findClosestISO( double iso, double inputError, double& outputError); // check if vector iterator is in valid range // check if vector iterator is in valid range [begin, end) template <typename T> inline static bool isValidIter(typename std::vector<T>::iterator it, const std::vector<T>& vector) { Loading