Please note that active projects have migrated to https://github.com/fawkesrobotics.

ffc217a6e42f86a514c8c0f28880cf87abb7c99d
[fawkes.git] / src / plugins / robot-memory / robot_memory.h
1 /***************************************************************************
2  *  robot_memory.h - Class for storing and querying information in the RobotMemory
3  *    
4  *  Created: Aug 23, 2016 1:34:32 PM 2016
5  *  Copyright  2016  Frederik Zwilling
6  *             2017 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8
9 /*  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU Library General Public License for more details.
18  *
19  *  Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 #ifndef __PLUGINS_ROBOT_MEMORY_ROBOT_MEMORY_H_
22 #define __PLUGINS_ROBOT_MEMORY_ROBOT_MEMORY_H_
23
24 #include <aspect/clock.h>
25 #include <aspect/configurable.h>
26 #include <aspect/logging.h>
27 #include <aspect/blackboard.h>
28 #include <plugins/mongodb/aspect/mongodb_conncreator.h>
29 #include <memory>
30 #include <vector>
31
32 #include <mongo/client/dbclient.h>
33 #include "interfaces/RobotMemoryInterface.h"
34 #include "event_trigger_manager.h"
35 #include "computables/computables_manager.h"
36
37 namespace fawkes {
38   class Mutex;
39   class RobotMemoryInterface;
40 }
41
42 ///typedef for shorter type description
43 typedef std::unique_ptr<mongo::DBClientCursor> QResCursor;
44
45 class RobotMemory
46 {
47   /// Friend the RobotMemoryThread so that only it can access the loop and init functions
48   friend class RobotMemoryThread;
49
50   public:
51     RobotMemory(fawkes::Configuration* config, fawkes::Logger* logger,
52                 fawkes::Clock* clock, fawkes::MongoDBConnCreator* mongo_connection_manager,
53                 fawkes::BlackBoard* blackboard);
54     virtual ~RobotMemory();
55
56     //robot memory functions
57     QResCursor query(mongo::Query query, std::string collection = "");
58     mongo::BSONObj aggregate(std::vector<mongo::BSONObj> pipeline, std::string collection = "");
59     int insert(mongo::BSONObj obj, std::string collection = "");
60     int insert(std::vector<mongo::BSONObj> v_obj, std::string collection = "");
61     int insert(std::string obj_str, std::string collection = "");
62     int update(mongo::Query query, mongo::BSONObj update, std::string collection = "", bool upsert = false);
63     int update(mongo::Query query, std::string update_str, std::string collection = "", bool upsert = false);
64     mongo::BSONObj find_one_and_update(const mongo::BSONObj& filter, const mongo::BSONObj& update,
65                                        std::string collection, bool upsert = false, bool return_new = true);
66     int remove(mongo::Query query, std::string collection = "");
67     mongo::BSONObj mapreduce(mongo::Query query, std::string collection,
68                              std::string js_map_fun, std::string js_reduce_fun);
69     QResCursor aggregate(mongo::BSONObj pipeline, std::string collection = "");
70     int drop_collection(std::string collection);
71     int clear_memory();
72     int restore_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
73     int dump_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
74     int create_index(mongo::BSONObj keys, std::string collection = "", bool unique = false);
75
76     //bool semaphore_create(const std::string& name, unsigned int value);
77     //bool semaphore_acquire(const std::string& name, unsigned int v = 1);
78     //bool semaphore_release(const std::string& name, unsigned int v = 1);
79     bool mutex_setup_ttl(float max_age_sec);
80     bool mutex_create(const std::string& name);
81     bool mutex_destroy(const std::string& name);
82     bool mutex_try_lock(const std::string& name, bool force = false);
83     bool mutex_try_lock(const std::string& name, std::string identity, bool force = false);
84     bool mutex_unlock(const std::string& name, std::string identity);
85     bool mutex_renew_lock(const std::string& name, std::string identity);
86     bool mutex_expire_locks(float max_age_sec);
87
88     /**
89      * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
90      * @param query Query the updated document has to match
91      * @param collection db.collection to use
92      * @param callback Callback function (e.g. &Class::callback)
93      * @param _obj Pointer to class the callback is a function of (usaually this)
94      * @return Trigger object pointer, save it to remove the trigger later
95      */
96     template<typename T>
97     EventTrigger* register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
98     {
99       check_collection_name(collection);
100       return trigger_manager_->register_trigger(query, collection, callback, _obj);
101     }
102     /**
103      * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
104      * @param query_str Query as JSON string
105      * @param collection db.collection to use
106      * @param callback Callback function (e.g. &Class::callback)
107      * @param _obj Pointer to class the callback is a function of (usaually this)
108      * @return Trigger object pointer, save it to remove the trigger later
109      */
110     template<typename T>
111     EventTrigger* register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
112     {
113       check_collection_name(collection);
114       return register_trigger(mongo::fromjson(query_str), collection, callback, _obj);
115     }
116     void remove_trigger(EventTrigger* trigger);
117
118     /**
119      * Registers a Computable which provides information in the robot memory that is computed on demand.
120      *
121      * @param query_to_compute Query describing what the function computes. Yor computable is called when an new query matches the key value fields in the identifiyer.
122      * @param collection db.collection to fill with computed information
123      * @param compute_func Callback function that computes the information and retruns a list of computed documents
124      * @param obj Pointer to class the callback is a function of (usaually this)
125      * @param caching_time How long should computed results for a query be cached and be used for identical queries in that time?
126      * @param priority Computable priority ordering the evaluation
127      * @return Computable Object pointer used for removing it
128      */
129     template<typename T>
130     Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj, std::string), T *obj, double caching_time = 0.0, int priority = 0)
131     {
132       check_collection_name(collection);
133       return computables_manager_->register_computable(query_to_compute, collection, compute_func, obj, caching_time, priority);
134     }
135     void remove_computable(Computable* computable);
136
137   private:
138     fawkes::MongoDBConnCreator* mongo_connection_manager_;
139     mongo::DBClientBase* mongodb_client_local_;
140     mongo::DBClientBase* mongodb_client_distributed_;
141     bool distributed_;
142     fawkes::Configuration* config_;
143     fawkes::Logger* logger_;
144     fawkes::Clock* clock_;
145     fawkes::BlackBoard* blackboard_;
146
147     const char* name_ = "RobotMemory";
148     std::string database_name_;
149     std::string default_collection_;
150     bool debug_;
151     fawkes::Mutex *mutex_;
152     fawkes::RobotMemoryInterface* rm_if_;
153     EventTriggerManager* trigger_manager_;
154     ComputablesManager* computables_manager_;
155     std::vector<std::string> distributed_dbs_;
156
157     unsigned int cfg_startup_grace_period_;
158     std::string  cfg_coord_database_;
159     std::string  cfg_coord_mutex_collection_;
160
161     void init();
162     void loop();
163
164     void log(std::string what, std::string level = "info");
165     void log_deb(std::string what, std::string level = "info");
166     void log(mongo::Query query, std::string what, std::string level = "info");
167     void log(mongo::BSONObj obj, std::string what, std::string level = "info");
168     void log_deb(mongo::Query query, std::string what, std::string level = "info");
169     void log_deb(mongo::BSONObj obj, std::string what, std::string level = "info");
170
171     void set_fields(mongo::BSONObj &obj, std::string what);
172     void set_fields(mongo::Query &q, std::string what);
173     void remove_field(mongo::Query &q, std::string what);
174
175     void check_collection_name(std::string &collection);
176     mongo::DBClientBase* get_mongodb_client(std::string &collection);
177 };
178
179 #endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_ROBOT_MEMORY_H_ */