[Fawkes Git] branch/bschaepers/asp-aspect-rm: 226 revs updated. (0.5.0-3593-g2b98b38)

Bjoern Schaepers bjoern.schaepers at rwth-aachen.de
Wed Dec 28 13:56:46 CET 2016


Changes have been pushed for the project "Fawkes Robotics Software Framework".

Gitweb: http://git.fawkesrobotics.org/fawkes.git
Trac:   http://trac.fawkesrobotics.org

The branch, bschaepers/asp-aspect-rm has been updated
  discards  3fc89ba82c9a543417444f793c4645bf71fb9f54 (commit)
  discards  c00d1a0d0b4fdbabffb45f2869d0ab084fa58740 (commit)
  discards  b0b74134926a54b701967433ff9fbd85fe652a37 (commit)
  discards  19c1f2b9a32b65e40597128c8c187fc3754b65fc (commit)
  discards  824f59d5605820d04a9c94899d88afa8204f49b1 (commit)
  discards  45015c481ebbb6951499ccc3708a12738da550eb (commit)
  discards  0bc2d4f079241cf59964d32e914a0507c5b1cf24 (commit)
  discards  19db51858a49193f016cda7965decafff476d44e (commit)
  discards  4ce5e0fad19278618a9999332a2a89953dfe4a89 (commit)
  discards  1079d7b9e88a63b01b23384de0dd46bbcf5f6e57 (commit)
  discards  4512d97664d3528a686db9200455a5efc59757b9 (commit)
  discards  a0d8985550c8ab0fd1d7601e37a98b127b768fdd (commit)
  discards  0d313da6eb1e98340392de6ae0e415807c95290a (commit)
  discards  f9bfe876daf6b5cf562da31b7b3c950fda6fbee1 (commit)
  discards  f768e7ddba929cf354c7e71f646c17233f5344fc (commit)
  discards  0c578f53763afea4bf9ef222b054f1b5cfa0a8e3 (commit)
  discards  559b56aa233d8a8480f0736fa3eab9f39727c203 (commit)
  discards  2cf4dc4bb25b6779444375df78550ed4b6e90e67 (commit)
  discards  d87b61b714a9c77eea8697d053b42fd9b14c25c2 (commit)
  discards  ac7cf879b77533cdc706afe79a17496a169c9694 (commit)
  discards  7dc316b0a922ca18e24d632b834cc1060fa45546 (commit)
  discards  dce07be9146ffbc0d9e88e5a438462decd7fd5c1 (commit)
  discards  dacfdf2dd3beb9b45fc52638f5d612eabd8f5220 (commit)
  discards  07374426b1c53acc9510a7375fbcc54646810c33 (commit)
  discards  0bd5b96d1753dbf5b8414ceac7422ed4eda6ba2b (commit)
  discards  7041c4e002a9b2adc3c97e813124e3edfc4f980f (commit)
  discards  273fb8a22e4405802e7eebb1e34d140e40260e1c (commit)
  discards  2d9deb88f21c8aa27c2b8d9f10b74d6617e46816 (commit)
  discards  903a772eb9e57c66896d10b79d77348702884a71 (commit)
  discards  e570dcea0de2b155604638f626ff724d523a58a4 (commit)
  discards  2a80e6e1514bb310afc31fdaf2a6c8fc90b07042 (commit)
  discards  bcd6c4b6a05df9e137db5647d413ddb8d5a75b79 (commit)
  discards  7eb017e889f811111fb497084f62486be07b8081 (commit)
  discards  2d2427904bcf3ce87ee43a25405e178704dd3683 (commit)
  discards  3457738aea5417e69eae233c75936e1b5322bfcb (commit)
  discards  78dcd9dcc6ae8ef57e0b68585584b24297aeadb1 (commit)
  discards  c909ed2f6a3ada8913d2b8eba7359de2b97ab122 (commit)
  discards  56f59c110451cefa6fe710c81fdd70c21be2ae98 (commit)
  discards  e8cf33dae85c18bc0355e526c62801f76799ec25 (commit)
  discards  e13a374860b10df30609adae6bf45a233f7f1925 (commit)
  discards  245423ecb8eb908f6586ff3a5658b7df08beaaa5 (commit)
  discards  1e06162eb22da1b7715c7684968c8ff0a77b3237 (commit)
  discards  07f7e5cf910ae74eddc6ff63be9ce99d19c56a09 (commit)
  discards  ccb31729db73b7f7b75ab477466e35760d92c02b (commit)
  discards  899cf264ac4bfcc5125896d26ef30150de1822e9 (commit)
  discards  633dee11eaa1fa70cbecb793b4bd7cb9cb73949e (commit)
  discards  c4f28dd825f3c9ed9110f854e0b9468f27aeb591 (commit)
  discards  9526d2bf3d6c60ef7c791e27d458e73553bf1333 (commit)
  discards  16df52d8b40c32073247705bea0b3a7ff972b933 (commit)
  discards  bcf93253cf185c93bd9f61e475c2749f89fb6102 (commit)
  discards  4ac324755ab2aef922b89b03278843d0ccb4f3e7 (commit)
  discards  8eda35d1cd8ccd8dde515a7e37f765ff0c026b96 (commit)
  discards  2e1d72279762dd8adc3dd8e5a4f4582e46243232 (commit)
  discards  6d021fd5821e24db0ad2275ff8464305a1a1452a (commit)
  discards  583c341762b9e98a25764873082d0b9c43231653 (commit)
  discards  365d0c71d2ac103e951240990c17e24c88426c67 (commit)
  discards  1890c4853eaa26a06f320e1bd430cdb97afeedae (commit)
  discards  92acf8c0da8944bc25b56048c85968a8ee3102b9 (commit)
  discards  7814803c8ce13e0666c543396995a231d17c0445 (commit)
  discards  f64cfa12b704ecc677ce5b96a190c52e69669f72 (commit)
  discards  a0cafa1d28dabf7f1bf3971c23d33f8bd4265c5a (commit)
  discards  d7a9d81267efdd9de03b433771d9b6c406f80d7b (commit)
  discards  57d984fa1b912f98e5c9fd89d626a7f9e99ad93c (commit)
  discards  4c48028893519f687c05948383ab0f4ed9092f8d (commit)
  discards  60b435c6524e8d4411feca88d83007991ec2784e (commit)
  discards  be4214aee6d19210d3449972c9b04f4f2f94d465 (commit)
  discards  5c9f7492f882f64585825845aecd4adef3ec0f15 (commit)
  discards  158cbdefb42524f5a575b1797f96e5478fb345fd (commit)
  discards  d08ddcdd5271f7ea692462522711841cf6ca256f (commit)
  discards  55bcabed2dec2c073f34f7eb445e05a2c00d1742 (commit)
  discards  c7528c3032adb961f2714b0df4298a5bc3258189 (commit)
  discards  8d18688c45ea10aa3338cafa6d4227c11b5b9d0d (commit)
  discards  6eafa9c64e30efac5b8cfdf40f2ddc8bb583c548 (commit)
  discards  9f9428d0400c6adfb685415af6ac8e0bf6bd26be (commit)
  discards  4c3a6a6b87d41755bb9d383afae20b24dac70224 (commit)
  discards  5387a75bae1e0ce106f8c9e21a6226411d845621 (commit)
  discards  7c6cda7df994d2355c46debc88d29b906cf3f99d (commit)
  discards  b5129ebacf6dce2c52b1e6483a8e55648f76fb1c (commit)
  discards  e1e2264aa7bfe8ac10bf83dfc7e6eacd9bdd3431 (commit)
  discards  d3cafa435a8a919c85c087a0eed1dd79228d0146 (commit)
  discards  22e48fb6e702b0210210ed6032be870178eb64fe (commit)
  discards  ebb35b54b721f0e6479a2e600e8a89cb7d269560 (commit)
  discards  53d178b07bfcf2d3ebbfe7032c12cddb92c05439 (commit)
  discards  325821df6a31cb7702cf5a330e4910b1748921e0 (commit)
  discards  ef3d9a20b40ecd024a8143b6f603ac620ec70e43 (commit)
  discards  4270c488e8edeb250df1258dfd6a915e836174b3 (commit)
  discards  386a339d826b1bf9d0947d5f0879f8e53438c95c (commit)
  discards  eda2a2b2116e9d1baf13c8364ef2d703d7911f26 (commit)
  discards  5729d6f402028c886397bce50000dd9d44fd9d18 (commit)
  discards  c28d7b925e67ec47329d510df1d4896727053c6c (commit)
  discards  5173577ed6812e699e22143881e221a09629e707 (commit)
  discards  19d0fbfafa5901603ac07a8dd13cc6021f0350a0 (commit)
  discards  d5cc3a8454a34cb3661f409dcfd67262fb5f5b0d (commit)
  discards  365c95966cad4aac69ea73323cec4f2098ab1531 (commit)
  discards  0ba989a955956994feb728db46859943183c089f (commit)
  discards  291d8475b466d01f1be661bcc8a5b1a96f923ef4 (commit)
  discards  a03d31e17ffb0d8a1d5ddb1a791c5d5f4dddab8b (commit)
  discards  67666871ebc5ba66f3b874a6448dfdac84d52435 (commit)
  discards  ae75a1bf012916533f7c608c5d61ed8b53e706c0 (commit)
  discards  553e17b178e18bd0dc814b99ed22a28331e248cd (commit)
  discards  04a3c63656cd488bbd7b3f06f976333f9db6e5d2 (commit)
  discards  69195c38a75ac601772b9cabd4dad09040d421eb (commit)
  discards  54478d8068bd92d09e339929974a5ce260b54089 (commit)
  discards  c0357cb0cb7d0e11834b83ccdd3edfb6f1f3ac5a (commit)
  discards  de73a7db12983440d1d4de7f5103f13660f4b24f (commit)
  discards  3af7d94677205381ecd336b048dc8c33c7dcf9a5 (commit)
  discards  b9f7287e9839760b67c07f4365d0034c34276a5c (commit)
  discards  9cf08148999af9ae0f74eb3a719fa56d1e4c7864 (commit)
  discards  cdecfb075141a21d62f4ef1ac0590403fd5c34fc (commit)
  discards  e47565a0598910e69d3e397856afd2c91d0270bc (commit)
  discards  5bf7f961a90888869504f86b926602ad9ac2e766 (commit)
  discards  d8a0684480e717cd1b12178067cbe4a1e1b10806 (commit)
  discards  6b6a1772bf007d4b0be9e9d75f8870c16bd4fa04 (commit)
  discards  a184dc8ad586101023be35bca4c8cb577ba45e42 (commit)
  discards  aedae1b4e6c33806c65789fe094d22c5c5e528ea (commit)
  discards  0121b82476f370d33e5cd1c58cc5a55d2aa083a1 (commit)
  discards  fd1d110a8cb83eb931efce4056f47e1ca531cc26 (commit)
  discards  43c0ff74262a4175f7ef4311440e09b2d3fb979f (commit)
  discards  24573f491e916ea4fe2dd1948c4f091566401c6a (commit)
  discards  7d86c6fc167acc2d6ff0f95fc7692dee31d2c463 (commit)
  discards  b2a5231a1ba736c9114a903556300e3c61da6fcb (commit)
  discards  4bb5f4709e414612659dbedeb42384d5661b6530 (commit)
  discards  63d7186f6cdd37d715aeb7b57c953049f2e33673 (commit)
  discards  15fad015e6794700d1da6ebd09cbb1ddee61efb4 (commit)
  discards  6bbf4ea6838a733dcf3f8e8c9603f0a9bbf265d6 (commit)
  discards  caec699dd3e4fdc46781bc6104c4ca052f688009 (commit)
  discards  7138569cfccbbf9efc8ee18131cdf03c21f410da (commit)
  discards  8806eb005879a2e879217f00cad88fb8f7cdaa15 (commit)
  discards  9bbb7d0fb36d3656705cd8a3585fd5c189fad419 (commit)
  discards  c48b00b4b60d243ac6b337c5e9f717624776ae98 (commit)
  discards  c0e0eb609971d97d877d7b830ac29950d1da0174 (commit)
  discards  b55e7a4b2dd2d6c314af32a01262a3198592dd8e (commit)
  discards  2aaa72883c92b3546832be60e12273b229cd5676 (commit)
  discards  535c50e06d3b76bca66b069f3591cb21cd4f4795 (commit)
        to  2b98b38794db6a0ad71e8e0f210a8f588acf3b3b (commit)
       via  b30af5c2df61f2e288f8f094be0110b55b01a604 (commit)
       via  583d1f64d327d2f3a01f0d68de7083f4bbbae1c7 (commit)
       via  2826e879bdaa81efe345489518360bafda28895e (commit)
       via  5545f7e590a413cb24f63c7af58081fb645a8806 (commit)
       via  fa3aa7b81289c559be300f67fcc1f02a88f2eb42 (commit)
       via  151f6f8779ac6d49df82a8c5df5ee25e01c25a6a (commit)
       via  003ef75ab2670d818db02a96300dfb3483e67bcf (commit)
       via  b78e868f28631d75614a767d2d653d2b6eba2f8d (commit)
       via  b97f940169eb4854be8789c89e108f589aba49b1 (commit)
       via  11aae2c10db961e9f326f13504fa67897f764495 (commit)
       via  a16ff219d8d12d36f252ecd7e45b0b0b742ea92b (commit)
       via  eddbbf495bad39a4dca4a26046317f3efaa59aba (commit)
       via  15acf2aa495aa39b5e2d92f238aafea573d3d9c1 (commit)
       via  535e28fbbebf1b712d723acd165a90281266ccc7 (commit)
       via  efda932a96201b57fffa44997c4a91ace64b0d25 (commit)
       via  a8073ccbe9d74344e773731dfc70b3b6df19ef94 (commit)
       via  e1b93bbc9a8d16145e710fae998e679c4e3c0080 (commit)
       via  1436050dd696c7a29d8e3c8f074451df170f7f5e (commit)
       via  f5b1cd3a31fd73da7c0d2444aa7b44743e512326 (commit)
       via  a5c59ecf418edefed8f5368b865f7ec327e8a9d7 (commit)
       via  5677b7279aa5b1565f496a93ec2d4a740fd7809b (commit)
       via  f54e58ef881f99db9b95336f74159937af315136 (commit)
       via  588035ab1f72c72d0aef77fe536f53d77fdd7635 (commit)
       via  69b423a6c6f85f9448658d4643eaa855c96f2fe9 (commit)
       via  c81310b8157eb0226bec32a96d82789d152f7c47 (commit)
       via  55ccedd5c700cfd6aa1c8bbb6f92459770eeb954 (commit)
       via  b62ac089bc9b1e4776d5c2ef72c56cb92d826cb3 (commit)
       via  b51bde4fa296db3f89748792b68d9a8a7538d606 (commit)
       via  739faeb8bfd503319df9a84a0958a7b4ad989e89 (commit)
       via  0392e9ea56be48a5376b8803d27ff778d362ca36 (commit)
       via  a187e9436902f4615b86c80e6b0bda1be6069732 (commit)
       via  2c98f1d7156bf1b584978ca8a0a6b449efd5741c (commit)
       via  954978e4960c16dbb36a79afe4af5e85a150e6a6 (commit)
       via  d6fb4e58fcb897edf2feff3f1791a900d676061c (commit)
       via  3c154a899de821498c9be1e49378bb7523060e37 (commit)
       via  2533050b3314ceb8788771ce3a250cf1851f224e (commit)
       via  5faa7384cd612f2dd8a3f5cad24c3d4aa916f073 (commit)
       via  5373f4a6e235b04143cc6baaae409eb45c0cd2e4 (commit)
       via  8fa54256f2154ce789fdd13616182c53fb769380 (commit)
       via  f9e5dcdf867c842195802934c391159306c4f7b6 (commit)
       via  ccf97d831f7af2c5483a8e632cb9d9472695dee8 (commit)
       via  541da32fde934b81b326295b2c04ecb24dae8476 (commit)
       via  93b17b985c3a73ade24c8a5fa3fe2af9194824f8 (commit)
       via  dd13c1c7e28c8808e6c672b0423d67af512cba03 (commit)
       via  bbac921ebf1d0c78d00ffcc0a20528b254eaff3a (commit)
       via  abffeeff1f677d731905824320d475e87a6b20a1 (commit)
       via  22cd83f26224a039f9dda901e46a7e986333f582 (commit)
       via  1c6c8442522bc5702596ed309333eff17011ae2e (commit)
       via  5a3683b3ec6b083c43c06b057cfdceb5b9be8bd2 (commit)
       via  8bfca895b1f774152fc9e46461cfa4ed3b728642 (commit)
       via  d04d59de3cfa0439cc5fd9159f1e5a83e3420ee3 (commit)
       via  e2d046ba7e35f92777df7f30135fb3b96f93dd1a (commit)
       via  3d0bc35f212aa0515350fa242d92efa64cb310c4 (commit)
       via  d70a2682b9905c89500abcd65b1df2dc30382138 (commit)
       via  b21f756c17b4cf0cc488f91faf48390f56c31d46 (commit)
       via  985a882afcf73c6caa52bbda741d7d8ec2367d03 (commit)
       via  39a0f2cdb2c94402d19972396dd734104374538b (commit)
       via  003b16f4f89d974735dac0ce80be9a5514cad249 (commit)
       via  65bf4bca135a067270031d4a3a598524101f1f18 (commit)
       via  3cc3e1026428906366e8411ddc00ed93751f904d (commit)
       via  99337cec1665536e44167905c12bf272669c51d1 (commit)
       via  333d69f01bb2f061e0b82b2e5a2b2708e8d48ffd (commit)
       via  5193fd949c8c8720b2cf4a5c2e0eefb78b871508 (commit)
       via  5a1175768a048035d1d0355b4c5a9a2645dc86d9 (commit)
       via  ef0eff479b0e62e8bc94143fc6595379219182db (commit)
       via  b7a6f91e0a8f140aa4e12cc43fbbbbcda6d8e838 (commit)
       via  8929eccd8ab91547209b76ea04c112754cc13c6b (commit)
       via  c41c56ebd56c74bbf5bd0d6f1ead50452145981c (commit)
       via  f4bea46649b239b2a8136450c17d23b1e6512525 (commit)
       via  15377b6de9b612f129dbe66070150dbe943122c7 (commit)
       via  29d5784df30b6183ad80cbfb791a47c9c46b4612 (commit)
       via  baaf892b850c27b9227332829fd9f168dd89cd87 (commit)
       via  b1c8159e2ce98f11e5a72c63706d70f6cdc0ef88 (commit)
       via  5fea1376c1ed9550d6d55aa68a6fd695682f63d9 (commit)
       via  aa2664284f4c42c1fae3b46b742985fa73e72617 (commit)
       via  d76752247ccedde69803f4f4e0fabf873706e343 (commit)
       via  9ff67ed4211180fac4acca32ef8075ef89e24eb1 (commit)
       via  16bcecd4422de9d7b18dd4ded96a6ba21cccecb2 (commit)
       via  c1ede99dd233168736a13bbe2187472feb11fadd (commit)
       via  71f2b98bb78fffd9ae2c53c35a025969d658b390 (commit)
       via  64fb85117583821d69860d2869069125aa5d9fda (commit)
       via  e75f3c1aaf1b6d38a1ff413dba71a13e1a942226 (commit)
       via  9a34c0e6a9fc873633df2945cdc36941adb4b9bb (commit)
       via  bb299bbf60d195569597b6ee3f9e8d6b37838eb7 (commit)
       via  c1151b06fd8a608b1c982e22d1853dd3b9aebc4a (commit)
       via  32b8ee08f85b64127c1ef189b96715df6364d262 (commit)
       via  1623fdd0d5c4e211211f357747c6cad60c979277 (commit)
       via  598ba98d3a52fd78ed3b68c6070b2e19ee0b3940 (commit)
       via  016379fe9320b6c0ce981af3265b0c6ebc1d110f (commit)
       via  98619545a806b6ccd04669badcea4571b002702a (commit)
       via  c08bd4f70216f2e4d1b6ed47a88104dd5ec055a2 (commit)
       via  f55876bedc97abb8f10b05867c3f037c00f7c56f (commit)
       via  a9eafa99fdaedd49aea281f9b6bb497a982cbe23 (commit)
       via  2c155dd1a7976f7b16852716a96091db597761e5 (commit)
       via  00e1c00e03d36baf806b567d2b720ba505b32794 (commit)
       via  1e9867a4667edf32f6bd7b60f5a1bf13306f408a (commit)
       via  09a8a56439b703120c1f249a2d124e1288e1abcf (commit)
       via  97da60efd6cb31b76f803c971f8bfc3eb0808116 (commit)
       via  0c5c8cb60965b58a9665a737454b8312d9c3f51e (commit)
       via  a9272928e209badaa923fc0ed343fa74f2c9dfd4 (commit)
       via  a84d8384cfa05700d6f8a98753d438fcb2f3bd8b (commit)
       via  f40bc3c05497e876101d1045026db99edbdb6d9f (commit)
       via  5dfdf5f58a77917dd1b9bd034aba9d1a98cca30a (commit)
       via  c1159aa7c1c577f71354c24ba2ce172af4fea847 (commit)
       via  3a0ac1253e62188171e13bf76d52bda1a9c50bed (commit)
       via  965fbcd95677be6c0cef2775aba39e0465e4ae09 (commit)
       via  511331a4c4315c542312f22966b712e9ea5172a7 (commit)
       via  c4fb764e4bbf39565b8e744b176db295290f209b (commit)
       via  9ecf2b6af4ed5985b618ea410ca2d73325906023 (commit)
       via  a913b632d6a92c77357a58ae0487d510c39fc995 (commit)
       via  e4da9cb5372ed196bbb877b122b1fe89e90b4f49 (commit)
       via  e406474465f791d5d6aee18cfb32c66b86cd1b1e (commit)
       via  d57be03a290b9b49e8822f0b123d9118e8b8d3e1 (commit)
       via  79e7dfeb3f3d0af5b7363f3d9efccd84f4d20c80 (commit)
       via  2c51f5a1c07b898933b6d4ff60bb3c6c0b0b68f0 (commit)
       via  6a7944859b683762cc200df28a3b3fddfd6b02e8 (commit)
       via  2f3821952b6b451e209551e9ddadf20dd756cf45 (commit)
       via  699024211bf6c107e146a4924caa402ba93aa743 (commit)
       via  ca8dc55aec6eca6b0a853a0d223bf72e80a9b31d (commit)
       via  761b2d52f71745cda9e9d3fd58b8a4518777d113 (commit)
       via  fde289414f01229b9e7664877635eaf68033be2e (commit)
       via  1b8b0f6b9917b4260b5589107125db4da863389d (commit)
       via  23539c9b9542350295b632f00e443dbf1b9bc653 (commit)
       via  c7feeea0f362a62e1c451c572fe35acfe0a96636 (commit)
       via  b65ca961155cc343af26c1fbc314ddbb28e8361a (commit)
       via  f44b816f35b6f625d6d8245a724bc60c72e866d1 (commit)
       via  fde8bce5d0d9861019e7b0b8c124e54f577718e8 (commit)
       via  cbb7cab6b52a72714367563523c33f9404ed2448 (commit)
       via  0eb1ca81c32819ae3bc34cc070e9220916cf040f (commit)
       via  899063bcfcabc034b1e7bbfb30fc69d74eb9fced (commit)
       via  6879c08932bdd9a356dac6a6f6d95953f6f0d2bf (commit)
       via  623b36ecd777d80b8ec5e7be2b0c6822cf4a1d7e (commit)
       via  568fc54c8e517441be455935230fd1c0177a46dc (commit)
       via  ccf6e3ba82ddbab199a0cbf75136795fd8e27397 (commit)
       via  2fafe28ec8e65813efd86c0f0186149df84bceb8 (commit)
       via  9ea4aea38cff30c76dc687c94f79a14e95fb4f6f (commit)
       via  3fe27c43812c7723c2eaf9f76dae37bae800888c (commit)
       via  144f69dfb3398a080bc5dd6fb4b1ec97fadfe1fb (commit)
       via  419a6564acb457e4d46f4dda8bdd93a430a8f74f (commit)
       via  5f8ddfc21b51aa33cbb0b37a1e5e975be9102711 (commit)
       via  f19eb689c97faabb047a3f4ec7a35843506f3786 (commit)
       via  b6353097e2719a8775dc2bfc80ded5fd9f06ded8 (commit)
       via  2850bb45c31ba7be8b9a7ab36b923dfaeca3a179 (commit)
       via  b5889979bf53f1bbb0cc764b572a9f3d725962a5 (commit)
       via  77c7c16c0b518d30b625af64ecd209d01fb55d7a (commit)
       via  48aa61fab8cd12373b8e238c736e56a1433c1c7f (commit)
       via  7f2544a683b32cffb55cf216ddbd6bbb6919518e (commit)
       via  83492aab00f622918377cb680fbaaeb95d4534d3 (commit)
       via  90371400ab29e4959ef6208905232f1341c04f29 (commit)
       via  d77c995d77b7c1f5f3529c81ffef957b451f7f2e (commit)
       via  a4d5227b50f85e6645b2f2229a9ae31ea20366fc (commit)
       via  b2111390918c2428543f9380f233177c4873e94d (commit)
       via  049113ba3df12dafbe46718b9230d3bb3a93cbc3 (commit)
       via  ea417f2f5fff72ca707e11f0d18d89bedc2c7c9b (commit)
       via  bee476873ffadb7485fec26af8363267a2dc0707 (commit)
       via  699529c5fa32345e89f45d66fe7f1eb946dbf390 (commit)
       via  c175651ea123c577bedd3e35bb2dc360de7f4466 (commit)
       via  31b65ac1e4bfb2ead38398d0876448abf9cf6822 (commit)
       via  5be4f629d160831d5c191a0fc6ac5a2e28c1779f (commit)
       via  cbb1725f3ae546e8b20e92ba666d32133ba5301e (commit)
       via  34cd20dc741f50d180637ac3fa9e9bf824b4a847 (commit)
       via  d9a15ff0314d6e855243b2ef0b301260e7f9a289 (commit)
       via  c8db401bc6c20e07eccb2c776e00d65aa61acbcf (commit)
       via  7ac1a5f73d4036aba0c54a8fc832314ff0614a64 (commit)
       via  3aa208b7bdf2415269872ed9107843bc2c90106b (commit)
       via  c8ea4744359fe726ad3ef5d6e9a38d84b9c9b1ad (commit)
       via  40b2e90d23d459a92fc670ef70692bd014218a1f (commit)
       via  21907b1259e6497b57df8a858817aceba2f4965e (commit)
       via  71ba39c1157515785b28a618544afa647243ec47 (commit)
       via  6ee025107fa9e3bc813db5388f20e0e2c9e9e507 (commit)
       via  4de7cf7155a311aab7ad73b575422a23a029926a (commit)
       via  05ed774ea40e6b1db7630a5959f429851858c085 (commit)
       via  993f1e4bc92b6487cde1647b2af9fbab1d6a3c06 (commit)
       via  c0078babe157fa105328a0cda3e226c88ead2a0f (commit)
       via  be2af409be1f0a093008c9982136078f2ef83e56 (commit)
       via  a021c3a96854b92a53e1301a7e50676dab9c4082 (commit)
       via  ef50309622fdb59ff93e74a3133491e06a9c862f (commit)
       via  23df43bc2532b5881ea0feebe310c33517001c19 (commit)
       via  90053507c52485ba66d72ec219c8005f05568e72 (commit)
       via  6dbdcd62c21667a6cd65aad0354878379e42a739 (commit)
       via  02a92760f1a714d80f8c3e57f1310c69504ce6cc (commit)
       via  97ef4170bddcec9a9d58a33d37deb5017039c794 (commit)
       via  5e91a4aca55e081d5134d09fb9fb7dae587b40f7 (commit)
       via  0eade76a552045c9becda1f1c3d4b3fcedd180cc (commit)
       via  78447f12861948ad0fff5ef9c31344e1917c06b9 (commit)
       via  a2dc8899fbc5d4dbc114a3811057d661b896497c (commit)
       via  43a0a89ddd7dfbff81f6599efeb118a14f7ecbf9 (commit)
       via  dda02509a742c7bb8c37ac89116668f49fe02029 (commit)
       via  1206fb5cc1e6d27151d05b163a73ceaa9b5fce0e (commit)
       via  ec6d5428a4ed91dea2d5f1b8bf8cad83875a737a (commit)
       via  ad4ccda804139b913dda9cb981bf1013c372ec9e (commit)
       via  2ebef0258d26485f943597f77a183b396c4e347c (commit)
       via  90fe9e077fe80a0c9c96d015005aefa7f92965e1 (commit)
       via  084abb59f3c1c9398d20e2a99243aeb5ebbf9848 (commit)
       via  32e8cabb3d79baebec942e6fd6ff43be3fe04383 (commit)
       via  a5c08125501ca1e10a68643a1785aaf94373c24b (commit)
       via  e4836d89926974d8d4b7159745781ba6196e18d1 (commit)
       via  b62bc0d3c98028c2a5b5b9427b35b9c8e47e5c2e (commit)
       via  cf9f6e3b2c6d541fcb94eba2b914899b2ac8e555 (commit)
       via  8dd0c67a1e7d323ac9dd1466f1ad2d0602192cd1 (commit)
       via  03ed1a8a8097857aaba1dd6a4edf8beaead5a9a0 (commit)
       via  9bad06818f45732777822bbf545ea2ac6959e147 (commit)
       via  a1d300072d62a60b124db799b72f0c4bd9db1484 (commit)
       via  20eff8ca60075b389c3b35df91c8fcd6285961a2 (commit)
       via  26c8e9bd4c8b50dbbe195df8c4164cb50ea98600 (commit)
       via  cad79d2dbca77b8d6a0dc9639d8db7a1a030f083 (commit)
       via  816bac4b2315ceb101a8ddedab25cc13efb37b68 (commit)
       via  c49c7b2a0a9f54e16daaba0329cc054bba5ebb9f (commit)
       via  b2740fcfdb02b619f4678e35163860e1f04dc0ec (commit)
       via  92270599bca0244281edf063641bc6ace35ba130 (commit)
       via  60be8b94573fbf91d85c7a477b464064cf587203 (commit)
       via  ee5efaf6d48a85bb68317dc86b307b01343eed4d (commit)
       via  9e53cb09e72060fa65101dd21ef9d365fa02bf3e (commit)
       via  9f59070bb5285dbfa8a16d297cd22da62feda623 (commit)
       via  f94a1fe6e5f4fd422d83d274d0ee668fa140d398 (commit)
       via  17470e03e4d3d48abbe4bfce68bc1bc81a888a6e (commit)
       via  3b4f8439887946a3e0c524748e7d11a029ac88a1 (commit)
       via  5d0e24992b2db43b70dcfe932207e4fe443bd003 (commit)
       via  28217e5dde6d32fa740e3ab353d70e260c20d334 (commit)
       via  da3881959aa7fcb876ea9b8170742d51b2f99f8c (commit)
       via  46f1e250c8f6b5938a05a1ad4a347f13285519cb (commit)
       via  ae6f9ea96ce59d35a9f9a601df34121e0b45b65c (commit)
       via  c8b8b0a2c37477a4af802e2907b87b23c6be44a5 (commit)
       via  fdb1ccb7df2f4aa63938de94b42201f910fe29c3 (commit)
       via  24d10876dbfeed1981db01b7e0f3235cf2a045e9 (commit)

This update added new revisions after undoing existing revisions.  That is
to say, the old revision is not a strict subset of the new revision.  This
situation occurs when you --force push a change and generate a repository
containing something like this:

 * -- * -- B -- O -- O -- O (3fc89ba82c9a543417444f793c4645bf71fb9f54)
            \
             N -- N -- N (2b98b38794db6a0ad71e8e0f210a8f588acf3b3b)

When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.

http://git.fawkesrobotics.org/fawkes.git/bschaepers/asp-aspect-rm

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- *Log* ---------------------------------------------------------------
commit a9eafa99fdaedd49aea281f9b6bb497a982cbe23
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Sep 20 17:57:53 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:51 2016 +0100

    utils: moved string utils for command argv and envs into utils/misc

http://git.fawkesrobotics.org/fawkes.git/commit/a9eafa9
http://trac.fawkesrobotics.org/changeset/a9eafa9

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit f55876bedc97abb8f10b05867c3f037c00f7c56f
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Sep 20 18:32:33 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:51 2016 +0100

    utils: require cpp11
    
    For example this is needed in the new utils classes for string
    conversions to use tuples and nicer for loops.

http://git.fawkesrobotics.org/fawkes.git/commit/f55876b
http://trac.fawkesrobotics.org/changeset/f55876b

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit c08bd4f70216f2e4d1b6ed47a88104dd5ec055a2
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Sep 20 18:34:36 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:51 2016 +0100

    openprs: properly use moved string utils

http://git.fawkesrobotics.org/fawkes.git/commit/c08bd4f
http://trac.fawkesrobotics.org/changeset/c08bd4f

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 98619545a806b6ccd04669badcea4571b002702a
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Sep 20 18:37:40 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:51 2016 +0100

    sub_process: moved utils to create sub processes into utils

http://git.fawkesrobotics.org/fawkes.git/commit/9861954
http://trac.fawkesrobotics.org/changeset/9861954

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 016379fe9320b6c0ce981af3265b0c6ebc1d110f
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Sep 20 19:26:05 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:52 2016 +0100

    utils: require boost asio and system for sb_process utils

http://git.fawkesrobotics.org/fawkes.git/commit/016379f
http://trac.fawkesrobotics.org/changeset/016379f

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 598ba98d3a52fd78ed3b68c6070b2e19ee0b3940
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Sep 20 19:30:53 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:52 2016 +0100

    openprs: properly use moved sub_process utils

http://git.fawkesrobotics.org/fawkes.git/commit/598ba98
http://trac.fawkesrobotics.org/changeset/598ba98

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 1623fdd0d5c4e211211f357747c6cad60c979277
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Sun May 1 20:14:11 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:52 2016 +0100

    robot-memory: skeleton for experimental plugin

http://git.fawkesrobotics.org/fawkes.git/commit/1623fdd
http://trac.fawkesrobotics.org/changeset/1623fdd

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 32b8ee08f85b64127c1ef189b96715df6364d262
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Sun May 1 22:33:08 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:52 2016 +0100

    robot-memory: execute queries from interface msg

http://git.fawkesrobotics.org/fawkes.git/commit/32b8ee0
http://trac.fawkesrobotics.org/changeset/32b8ee0

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit c1151b06fd8a608b1c982e22d1853dd3b9aebc4a
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Sun May 1 23:38:09 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:52 2016 +0100

    robot-memory: get info about parsed query

http://git.fawkesrobotics.org/fawkes.git/commit/c1151b0
http://trac.fawkesrobotics.org/changeset/c1151b0

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit bb299bbf60d195569597b6ee3f9e8d6b37838eb7
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Mon May 9 17:50:45 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:52 2016 +0100

    robot-memory: added insert, update, remove messages

http://git.fawkesrobotics.org/fawkes.git/commit/bb299bb
http://trac.fawkesrobotics.org/changeset/bb299bb

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 9a34c0e6a9fc873633df2945cdc36941adb4b9bb
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Mon May 9 18:59:23 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:52 2016 +0100

    robot-memory: virtual knowledge base experiments

http://git.fawkesrobotics.org/fawkes.git/commit/9a34c0e
http://trac.fawkesrobotics.org/changeset/9a34c0e

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit e75f3c1aaf1b6d38a1ff413dba71a13e1a942226
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed May 11 14:52:21 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: added missing config file

http://git.fawkesrobotics.org/fawkes.git/commit/e75f3c1
http://trac.fawkesrobotics.org/changeset/e75f3c1

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 64fb85117583821d69860d2869069125aa5d9fda
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Aug 18 12:59:31 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: added gtest skeleton for unit testing

http://git.fawkesrobotics.org/fawkes.git/commit/64fb851
http://trac.fawkesrobotics.org/changeset/64fb851

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 71f2b98bb78fffd9ae2c53c35a025969d658b390
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Aug 23 18:51:52 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    mongodb: hint in exception to start the mongod service

http://git.fawkesrobotics.org/fawkes.git/commit/71f2b98
http://trac.fawkesrobotics.org/changeset/71f2b98

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit c1ede99dd233168736a13bbe2187472feb11fadd
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Aug 23 18:55:19 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: provide aspect for using the RobotMemory

http://git.fawkesrobotics.org/fawkes.git/commit/c1ede99
http://trac.fawkesrobotics.org/changeset/c1ede99

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 16bcecd4422de9d7b18dd4ded96a6ba21cccecb2
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Aug 24 11:36:35 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: clearer api functions

http://git.fawkesrobotics.org/fawkes.git/commit/16bcecd
http://trac.fawkesrobotics.org/changeset/16bcecd

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 9ff67ed4211180fac4acca32ef8075ef89e24eb1
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Aug 24 14:03:51 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    gtest: tool for unit testing in a running fawkes environment
    
    This tool allows gtest unit tests depending on a running fawkes
    environmnet with aspects, plugins, blackboard, etc.
    You can execute tests with "make test" in src/tools/gtest. It then
    starts fawkes similar to the mainapp's main function with a set of
    plugins containing a test-plugin. This test plugin implements unit tests
    and calls the RUN_ALL_TESTS makro. Afterwards the plugins ends fawkes.

http://git.fawkesrobotics.org/fawkes.git/commit/9ff67ed
http://trac.fawkesrobotics.org/changeset/9ff67ed

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit d76752247ccedde69803f4f4e0fabf873706e343
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Aug 24 14:59:22 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: created gtest plugin to run tests in fawkes

http://git.fawkesrobotics.org/fawkes.git/commit/d767522
http://trac.fawkesrobotics.org/changeset/d767522

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit aa2664284f4c42c1fae3b46b742985fa73e72617
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Aug 24 17:40:48 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory-test: provide environment with access to the RobotMemory

http://git.fawkesrobotics.org/fawkes.git/commit/aa26642
http://trac.fawkesrobotics.org/changeset/aa26642

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 5fea1376c1ed9550d6d55aa68a6fd695682f63d9
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Aug 25 02:16:47 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: appropriate return values for query,insert,update,remove
    
    Added proper return values. 1/0 for successful/failed
    insert,update,remove. Cursor for query or NULL for invalid query.

http://git.fawkesrobotics.org/fawkes.git/commit/5fea137
http://trac.fawkesrobotics.org/changeset/5fea137

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit b1c8159e2ce98f11e5a72c63706d70f6cdc0ef88
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Aug 25 02:19:47 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory-tests: added tests for query,insert,update,remove

http://git.fawkesrobotics.org/fawkes.git/commit/b1c8159
http://trac.fawkesrobotics.org/changeset/b1c8159

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit baaf892b850c27b9227332829fd9f168dd89cd87
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Aug 25 21:57:23 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: configurable debug output

http://git.fawkesrobotics.org/fawkes.git/commit/baaf892
http://trac.fawkesrobotics.org/changeset/baaf892

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 29d5784df30b6183ad80cbfb791a47c9c46b4612
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Aug 25 21:57:57 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory-test: properly quit fawkes when tests finished

http://git.fawkesrobotics.org/fawkes.git/commit/29d5784
http://trac.fawkesrobotics.org/changeset/29d5784

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 15377b6de9b612f129dbe66070150dbe943122c7
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Aug 26 19:05:37 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: better logging functions

http://git.fawkesrobotics.org/fawkes.git/commit/15377b6
http://trac.fawkesrobotics.org/changeset/15377b6

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit f4bea46649b239b2a8136450c17d23b1e6512525
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Mon Aug 29 19:02:53 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: dump and restore collections
    
    You can now dump and restore collections. This allows setting the robot
    memory to an initial state or storing memory states (e.g. to repeat
    experiments on the same data).
    The implementation uses mongorestore and mongodump.

http://git.fawkesrobotics.org/fawkes.git/commit/f4bea46
http://trac.fawkesrobotics.org/changeset/f4bea46

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit c41c56ebd56c74bbf5bd0d6f1ead50452145981c
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Mon Aug 29 19:44:31 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: use BSONObj and Query in API
    
    This allows giving BSONObj and Queries to the robot memory's function as
    well as simple strings in the JSON format.

http://git.fawkesrobotics.org/fawkes.git/commit/c41c56e
http://trac.fawkesrobotics.org/changeset/c41c56e

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 8929eccd8ab91547209b76ea04c112754cc13c6b
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Mon Aug 29 20:27:26 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    clips-robot-memory: start for CLIPS feature from refbox clips-mongodb

http://git.fawkesrobotics.org/fawkes.git/commit/8929ecc
http://trac.fawkesrobotics.org/changeset/8929ecc

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit b7a6f91e0a8f140aa4e12cc43fbbbbcda6d8e838
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Sep 1 15:00:10 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: add upsert option in update function
    
    When executing an update, the upsert option defines if the document
    should be inserted if it is not already in the database.

http://git.fawkesrobotics.org/fawkes.git/commit/b7a6f91
http://trac.fawkesrobotics.org/changeset/b7a6f91

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit ef0eff479b0e62e8bc94143fc6595379219182db
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Sep 1 16:25:04 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: removed setting type in document for testing

http://git.fawkesrobotics.org/fawkes.git/commit/ef0eff4
http://trac.fawkesrobotics.org/changeset/ef0eff4

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 5a1175768a048035d1d0355b4c5a9a2645dc86d9
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Sep 1 17:42:09 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    clips-robot-memory: adjusted plugin to use the robot memory

http://git.fawkesrobotics.org/fawkes.git/commit/5a11757
http://trac.fawkesrobotics.org/changeset/5a11757

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 5193fd949c8c8720b2cf4a5c2e0eefb78b871508
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Sep 13 18:01:15 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    clips-robot-memory: function to create BSON doc from structured fact

http://git.fawkesrobotics.org/fawkes.git/commit/5193fd9
http://trac.fawkesrobotics.org/changeset/5193fd9

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 333d69f01bb2f061e0b82b2e5a2b2708e8d48ffd
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Sep 13 18:19:27 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    clips-robot-memory: create BSON document from ordered fact

http://git.fawkesrobotics.org/fawkes.git/commit/333d69f
http://trac.fawkesrobotics.org/changeset/333d69f

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 99337cec1665536e44167905c12bf272669c51d1
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Sep 13 19:15:24 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    clips-robot-memory: assert facts from bson document

http://git.fawkesrobotics.org/fawkes.git/commit/99337ce
http://trac.fawkesrobotics.org/changeset/99337ce

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 3cc3e1026428906366e8411ddc00ed93751f904d
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Sep 21 17:55:02 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: startup local mongod processes
    
    Startup a local mongod process when it is not already running.
    Requires the fzwilling/sub_process branch.

http://git.fawkesrobotics.org/fawkes.git/commit/3cc3e10
http://trac.fawkesrobotics.org/changeset/3cc3e10

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 65bf4bca135a067270031d4a3a598524101f1f18
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Sep 21 19:48:29 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    utils: string_conversions: resolve ~ in path

http://git.fawkesrobotics.org/fawkes.git/commit/65bf4bc
http://trac.fawkesrobotics.org/changeset/65bf4bc

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 003b16f4f89d974735dac0ce80be9a5514cad249
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Sep 21 19:48:59 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: setup config server for distributed robot memory

http://git.fawkesrobotics.org/fawkes.git/commit/003b16f
http://trac.fawkesrobotics.org/changeset/003b16f

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 39a0f2cdb2c94402d19972396dd734104374538b
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Sep 22 20:01:32 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: setup replicaset and mongos process

http://git.fawkesrobotics.org/fawkes.git/commit/39a0f2c
http://trac.fawkesrobotics.org/changeset/39a0f2c

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 985a882afcf73c6caa52bbda741d7d8ec2367d03
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Sep 23 19:16:30 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    clips-robot-memory: add remove function

http://git.fawkesrobotics.org/fawkes.git/commit/985a882
http://trac.fawkesrobotics.org/changeset/985a882

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit b21f756c17b4cf0cc488f91faf48390f56c31d46
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Sep 28 13:06:57 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: config sharded cluster automatically

http://git.fawkesrobotics.org/fawkes.git/commit/b21f756
http://trac.fawkesrobotics.org/changeset/b21f756

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit d70a2682b9905c89500abcd65b1df2dc30382138
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Sep 28 14:51:15 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory: set read preference 'nearest' to read locally

http://git.fawkesrobotics.org/fawkes.git/commit/d70a268
http://trac.fawkesrobotics.org/changeset/d70a268

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 3d0bc35f212aa0515350fa242d92efa64cb310c4
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Sep 28 14:53:39 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:53 2016 +0100

    robot-memory-test: use simulated replica set in tests

http://git.fawkesrobotics.org/fawkes.git/commit/3d0bc35
http://trac.fawkesrobotics.org/changeset/3d0bc35

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit e2d046ba7e35f92777df7f30135fb3b96f93dd1a
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Sep 28 15:47:38 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: made setup robust against missing db+shards already added

http://git.fawkesrobotics.org/fawkes.git/commit/e2d046b
http://trac.fawkesrobotics.org/changeset/e2d046b

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit d04d59de3cfa0439cc5fd9159f1e5a83e3420ee3
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Sep 28 16:18:59 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: use default db name when modified for simulation

http://git.fawkesrobotics.org/fawkes.git/commit/d04d59d
http://trac.fawkesrobotics.org/changeset/d04d59d

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 8bfca895b1f774152fc9e46461cfa4ed3b728642
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Sep 28 18:35:30 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: added dependencies in plugins/Makefile

http://git.fawkesrobotics.org/fawkes.git/commit/8bfca89
http://trac.fawkesrobotics.org/changeset/8bfca89

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 5a3683b3ec6b083c43c06b057cfdceb5b9be8bd2
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Sep 29 16:23:16 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    utils: fixed makefile to create lua/fawkesutils after new requirements

http://git.fawkesrobotics.org/fawkes.git/commit/5a3683b
http://trac.fawkesrobotics.org/changeset/5a3683b

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 1c6c8442522bc5702596ed309333eff17011ae2e
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Sep 29 20:22:42 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: create dbs and assing them to shards

http://git.fawkesrobotics.org/fawkes.git/commit/1c6c844
http://trac.fawkesrobotics.org/changeset/1c6c844

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 22cd83f26224a039f9dda901e46a7e986333f582
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 6 18:00:00 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    utils: added libdeamon to makefile to close sockets in SubProcess

http://git.fawkesrobotics.org/fawkes.git/commit/22cd83f
http://trac.fawkesrobotics.org/changeset/22cd83f

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit abffeeff1f677d731905824320d475e87a6b20a1
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Mon Oct 3 17:20:38 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: first prototype for event triggers using the oplog

http://git.fawkesrobotics.org/fawkes.git/commit/abffeef
http://trac.fawkesrobotics.org/changeset/abffeef

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit bbac921ebf1d0c78d00ffcc0a20528b254eaff3a
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 6 11:44:14 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: handling trigger callback functions

http://git.fawkesrobotics.org/fawkes.git/commit/bbac921
http://trac.fawkesrobotics.org/changeset/bbac921

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit dd13c1c7e28c8808e6c672b0423d67af512cba03
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 6 18:36:45 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: enable oplog on local mongodb with single replSet
    
    To enable the oplog we have to make the database to a replica set with a
    single member. This is necessary for triggers.

http://git.fawkesrobotics.org/fawkes.git/commit/dd13c1c
http://trac.fawkesrobotics.org/changeset/dd13c1c

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 93b17b985c3a73ade24c8a5fa3fe2af9194824f8
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 6 18:46:06 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: tests and fixes for event triggers

http://git.fawkesrobotics.org/fawkes.git/commit/93b17b9
http://trac.fawkesrobotics.org/changeset/93b17b9

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 541da32fde934b81b326295b2c04ecb24dae8476
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 6 19:01:30 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: fixed DumpRestore test

http://git.fawkesrobotics.org/fawkes.git/commit/541da32
http://trac.fawkesrobotics.org/changeset/541da32

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit ccf97d831f7af2c5483a8e632cb9d9472695dee8
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Mon Oct 10 14:27:53 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    clips-robot-memory: first steps of trigger integration

http://git.fawkesrobotics.org/fawkes.git/commit/ccf97d8
http://trac.fawkesrobotics.org/changeset/ccf97d8

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit f9e5dcdf867c842195802934c391159306c4f7b6
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Oct 11 16:20:28 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    clips-robot-memory: fixed getting sub-documents

http://git.fawkesrobotics.org/fawkes.git/commit/f9e5dcd
http://trac.fawkesrobotics.org/changeset/f9e5dcd

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 8fa54256f2154ce789fdd13616182c53fb769380
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Oct 11 17:51:43 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    clips-robot-memroy: fixed assert-from-bson

http://git.fawkesrobotics.org/fawkes.git/commit/8fa5425
http://trac.fawkesrobotics.org/changeset/8fa5425

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 5373f4a6e235b04143cc6baaae409eb45c0cd2e4
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Oct 11 22:00:57 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    clips-robot-memory: assert trigger facts for db updates

http://git.fawkesrobotics.org/fawkes.git/commit/5373f4a
http://trac.fawkesrobotics.org/changeset/5373f4a

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 5faa7384cd612f2dd8a3f5cad24c3d4aa916f073
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Oct 11 21:51:46 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    colli: renamed AStar class to avoid conflict with utils/search/astar
    
    Since we compiled the utils with C++11, the linker mixes up the colli
    astar and utils astar classes. They are implemented differently, but
    have the same name and namespace. This lead to a segfault when suddenly
    the search function of the utils was executed in a colli astar instance.
    This is a fist hotfix that just renames the colli astar class.

http://git.fawkesrobotics.org/fawkes.git/commit/5faa738
http://trac.fawkesrobotics.org/changeset/5faa738

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 2533050b3314ceb8788771ce3a250cf1851f224e
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 13 13:21:38 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: proper first setup of local mongod with oplog

http://git.fawkesrobotics.org/fawkes.git/commit/2533050
http://trac.fawkesrobotics.org/changeset/2533050

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 3c154a899de821498c9be1e49378bb7523060e37
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 13 13:42:00 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    pddl-robot-memory: plugin skeleton for generating pddl from the robot memory

http://git.fawkesrobotics.org/fawkes.git/commit/3c154a8
http://trac.fawkesrobotics.org/changeset/3c154a8

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit d6fb4e58fcb897edf2feff3f1791a900d676061c
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 13 15:31:14 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    pddl-robot-memory: reading template and writing output file

http://git.fawkesrobotics.org/fawkes.git/commit/d6fb4e5
http://trac.fawkesrobotics.org/changeset/d6fb4e5

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 954978e4960c16dbb36a79afe4af5e85a150e6a6
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 13 19:39:36 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    pddl-robot-memory: use ctemplate as template engine for generating .pddl

http://git.fawkesrobotics.org/fawkes.git/commit/954978e
http://trac.fawkesrobotics.org/changeset/954978e

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 2c98f1d7156bf1b584978ca8a0a6b449efd5741c
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Oct 14 00:16:52 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    pddl-robot-memory: generic templates to query robot memory and fill
    
    Uses the template engine ctemplate to generate pddl from a template
    file and the robot memory.
    
    The template file can use the following templates to generate some
    output for each document returned by a query:
    
    Example: <<#ONTABLE|{relation:'on-table'}>> (on-table <<object>>)
      <</ONTABLE>>
    Yields: (on-table a) (on-table b)
    When these documents are in the database:
     {relation:'on-table', object:'a'}, {relation:'on-table', object:'b'}
    
    The selection template <<#UNIQUENAME|query>> something
     <</UNIQUENAME>>
     queries the robot memory and inserts 'something' for each returned
     document.
    
    Variable templates <<key>> inside the selection are substituted by
     the values
     of that key in the document returned by the query. You can also
     access subdocuments
     (e.g. <<position.orientation.yaw>> )

http://git.fawkesrobotics.org/fawkes.git/commit/2c98f1d
http://trac.fawkesrobotics.org/changeset/2c98f1d

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit a187e9436902f4615b86c80e6b0bda1be6069732
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Oct 14 13:12:41 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    pddl-robot-memory: changed delimiter to access subdocuments to '_'
    
    The previous '.' as well as other intuitive delimiters are not usable in
    ctemplate names.

http://git.fawkesrobotics.org/fawkes.git/commit/a187e94
http://trac.fawkesrobotics.org/changeset/a187e94

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 0392e9ea56be48a5376b8803d27ff778d362ca36
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Oct 14 13:40:23 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    pddl-robot-memory: allow accessing arrays in templates

http://git.fawkesrobotics.org/fawkes.git/commit/0392e9e
http://trac.fawkesrobotics.org/changeset/0392e9e

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 739faeb8bfd503319df9a84a0958a7b4ad989e89
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Oct 14 16:26:49 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    pddl-robot-memory: generate pddl on interface message

http://git.fawkesrobotics.org/fawkes.git/commit/739faeb
http://trac.fawkesrobotics.org/changeset/739faeb

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit b51bde4fa296db3f89748792b68d9a8a7538d606
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Oct 14 16:33:58 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    pddl-robot-memory: config to generate pddl on init

http://git.fawkesrobotics.org/fawkes.git/commit/b51bde4
http://trac.fawkesrobotics.org/changeset/b51bde4

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit b62ac089bc9b1e4776d5c2ef72c56cb92d826cb3
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Oct 18 18:25:35 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: improved documentation

http://git.fawkesrobotics.org/fawkes.git/commit/b62ac08
http://trac.fawkesrobotics.org/changeset/b62ac08

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 55ccedd5c700cfd6aa1c8bbb6f92459770eeb954
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Oct 21 21:37:29 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: class and api skeleton for computables

http://git.fawkesrobotics.org/fawkes.git/commit/55ccedd
http://trac.fawkesrobotics.org/changeset/55ccedd

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit c81310b8157eb0226bec32a96d82789d152f7c47
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 27 19:39:23 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: registering, checking, and executing computables
    
    Computables provide information computation on demand when querying
    (e.g. for interfacing perception, and geting complex information that
    would be inpractical to store permanently in the robot memory such as
    object distances). You can register a computable in the robot memory
    by giving a function that returns a list of computed documents. The
    function receives the query that should be executed at the moment and
    which usually contains more information about what should be computed.
    When registering a computable, you also need to give an identifyer
    query that defines when to call the computable by checking if the
    current query is matched by the identifyer query.

http://git.fawkesrobotics.org/fawkes.git/commit/c81310b
http://trac.fawkesrobotics.org/changeset/c81310b

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 69b423a6c6f85f9448658d4643eaa855c96f2fe9
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 27 20:05:54 2016 +0200
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: computable unit test: addition and adding multiple docs

http://git.fawkesrobotics.org/fawkes.git/commit/69b423a
http://trac.fawkesrobotics.org/changeset/69b423a

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 588035ab1f72c72d0aef77fe536f53d77fdd7635
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Nov 1 13:21:29 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: moved computables in subfolder

http://git.fawkesrobotics.org/fawkes.git/commit/588035a
http://trac.fawkesrobotics.org/changeset/588035a

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit f54e58ef881f99db9b95336f74159937af315136
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Nov 1 18:12:02 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: added computable for blackboard interfaces

http://git.fawkesrobotics.org/fawkes.git/commit/f54e58e
http://trac.fawkesrobotics.org/changeset/f54e58e

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 5677b7279aa5b1565f496a93ec2d4a740fd7809b
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Tue Nov 1 18:31:11 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: fixed syntax in aspect Makefile

http://git.fawkesrobotics.org/fawkes.git/commit/5677b72
http://trac.fawkesrobotics.org/changeset/5677b72

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit a5c59ecf418edefed8f5368b865f7ec327e8a9d7
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Nov 3 11:14:24 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: error hint if mongod is running with wrong parameters

http://git.fawkesrobotics.org/fawkes.git/commit/a5c59ec
http://trac.fawkesrobotics.org/changeset/a5c59ec

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit f5b1cd3a31fd73da7c0d2444aa7b44743e512326
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Nov 3 11:51:17 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: compute all bb-interfaces when no id is given

http://git.fawkesrobotics.org/fawkes.git/commit/f5b1cd3
http://trac.fawkesrobotics.org/changeset/f5b1cd3

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 1436050dd696c7a29d8e3c8f074451df170f7f5e
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Nov 3 13:00:06 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: require collection in interface msgs for testing

http://git.fawkesrobotics.org/fawkes.git/commit/1436050
http://trac.fawkesrobotics.org/changeset/1436050

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit e1b93bbc9a8d16145e710fae998e679c4e3c0080
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Nov 9 18:20:05 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: use config of  local database path
    
    This avoids problems with systems where /data/db is not prepared for the
    use by mongodb.

http://git.fawkesrobotics.org/fawkes.git/commit/e1b93bb
http://trac.fawkesrobotics.org/changeset/e1b93bb

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit a8073ccbe9d74344e773731dfc70b3b6df19ef94
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Nov 10 18:09:10 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: fixed initial creation of dbs to be able to move them
    
    DBs have to be created before they can be moved to a primary. To be
    created they have to be not empty. The previous initialization created
    the db in the local mongod but the mongos pointed to an empty  db
    with the same name in another mongod. Thus it produced the error
    'can't find db'. Now the db is created using the mongos and afterwards
    moved to the local mongod.

http://git.fawkesrobotics.org/fawkes.git/commit/a8073cc
http://trac.fawkesrobotics.org/changeset/a8073cc

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit efda932a96201b57fffa44997c4a91ace64b0d25
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Nov 11 16:23:33 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    clips-robot-memory: fixed getting symbol multifields from documents

http://git.fawkesrobotics.org/fawkes.git/commit/efda932
http://trac.fawkesrobotics.org/changeset/efda932

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 535e28fbbebf1b712d723acd165a90281266ccc7
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Nov 11 17:25:30 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    clips-robot-memory: better distinction of string and symbol values

http://git.fawkesrobotics.org/fawkes.git/commit/535e28f
http://trac.fawkesrobotics.org/changeset/535e28f

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 15acf2aa495aa39b5e2d92f238aafea573d3d9c1
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Fri Nov 18 16:30:19 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: fixed trigger-manager in non-replicated case

http://git.fawkesrobotics.org/fawkes.git/commit/15acf2a
http://trac.fawkesrobotics.org/changeset/15acf2a

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit eddbbf495bad39a4dca4a26046317f3efaa59aba
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Mon Nov 21 18:07:35 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: give collection in computable function
    
    This allows registering a computable for multiple collections.

http://git.fawkesrobotics.org/fawkes.git/commit/eddbbf4
http://trac.fawkesrobotics.org/changeset/eddbbf4

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit a16ff219d8d12d36f252ecd7e45b0b0b742ea92b
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Nov 23 13:39:53 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: added transform computable
    
    This computable provides geometric positions already present in the
    robot memory in other frames. To use it you have to add the used
    collection in the config of the transform computable and query the
    wanted position with the target frame and 'allow_tf':true .

http://git.fawkesrobotics.org/fawkes.git/commit/a16ff21
http://trac.fawkesrobotics.org/changeset/a16ff21

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 11aae2c10db961e9f326f13504fa67897f764495
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Nov 23 13:42:02 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: fixed template function for trigger registration

http://git.fawkesrobotics.org/fawkes.git/commit/11aae2c
http://trac.fawkesrobotics.org/changeset/11aae2c

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit b97f940169eb4854be8789c89e108f589aba49b1
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Nov 23 15:26:25 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: function to insert vector of documents

http://git.fawkesrobotics.org/fawkes.git/commit/b97f940
http://trac.fawkesrobotics.org/changeset/b97f940

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit b78e868f28631d75614a767d2d653d2b6eba2f8d
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Nov 23 15:27:15 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:54 2016 +0100

    robot-memory: Use RM instead of mongo client in computable_manager
    
    The DBClientConnection is not thread safe. Thus we now use the robot
    memory functions to access the database in the computable manager,
    because they already include mutex locks.

http://git.fawkesrobotics.org/fawkes.git/commit/b78e868
http://trac.fawkesrobotics.org/changeset/b78e868

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 003ef75ab2670d818db02a96300dfb3483e67bcf
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Nov 23 21:20:50 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:55 2016 +0100

    robot-memory: caching computables
    
    A computable now can cache computed documents. During the caching time
    these documents stay in the robot memory and the same query given a
    second time does not invoke the computation again. After the caching
    time, computed documents are removed.

http://git.fawkesrobotics.org/fawkes.git/commit/003ef75
http://trac.fawkesrobotics.org/changeset/003ef75

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 151f6f8779ac6d49df82a8c5df5ee25e01c25a6a
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Nov 24 14:38:14 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:55 2016 +0100

    openrave-robot-memory: constructing motion planner scenes from robot memory
    
    This new plugin connects the robot memory to the motion planner
    openrave. It should construct the scene in which opnrave plans robot arm
    motion. To do this it querries a collection of the robot memory for
    objects in the scene. This is only the plugin skeleton.

http://git.fawkesrobotics.org/fawkes.git/commit/151f6f8
http://trac.fawkesrobotics.org/changeset/151f6f8

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit fa3aa7b81289c559be300f67fcc1f02a88f2eb42
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Nov 24 18:11:13 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:55 2016 +0100

    robot-memory: fixed transform computable not keeping fields

http://git.fawkesrobotics.org/fawkes.git/commit/fa3aa7b
http://trac.fawkesrobotics.org/changeset/fa3aa7b

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 5545f7e590a413cb24f63c7af58081fb645a8806
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Nov 24 18:12:04 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:55 2016 +0100

    robot-memory: multithreading robust checking if query mathes a computable

http://git.fawkesrobotics.org/fawkes.git/commit/5545f7e
http://trac.fawkesrobotics.org/changeset/5545f7e

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 2826e879bdaa81efe345489518360bafda28895e
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Nov 24 18:13:16 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:55 2016 +0100

    openrave-robot-memory: add and place block objects in openrave

http://git.fawkesrobotics.org/fawkes.git/commit/2826e87
http://trac.fawkesrobotics.org/changeset/2826e87

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 583d1f64d327d2f3a01f0d68de7083f4bbbae1c7
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Nov 30 15:02:17 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:55 2016 +0100

    clips-robot-memory: added function (bson-has-hield ?obj "field")

http://git.fawkesrobotics.org/fawkes.git/commit/583d1f6
http://trac.fawkesrobotics.org/changeset/583d1f6

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit b30af5c2df61f2e288f8f094be0110b55b01a604
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Nov 30 15:03:09 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:55 2016 +0100

    robot-memory: fixed trigger on local replica set

http://git.fawkesrobotics.org/fawkes.git/commit/b30af5c
http://trac.fawkesrobotics.org/changeset/b30af5c

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 2b98b38794db6a0ad71e8e0f210a8f588acf3b3b
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Wed Nov 30 16:51:06 2016 +0100
Commit:     Bjoern Schaepers <bjoern.schaepers at rwth-aachen.de>
CommitDate: Wed Dec 28 13:55:55 2016 +0100

    pddl-robot-memory: added interface files

http://git.fawkesrobotics.org/fawkes.git/commit/2b98b38
http://trac.fawkesrobotics.org/changeset/2b98b38

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


- *Summary* -----------------------------------------------------------
 AUTHORS                                            |   15 +
 cfg/conf.d/network.yaml                            |   29 +
 cfg/config.yaml                                    |    9 +-
 etc/buildsys/boost.mk                              |   11 +-
 etc/buildsys/cgal.mk                               |    8 +-
 etc/buildsys/gtest.mk                              |   16 +-
 etc/buildsys/rules.mk                              |    2 +-
 res/guis/skillgui/skillgui.ui                      |    3 +-
 src/libs/Makefile                                  |    2 +-
 src/libs/baseapp/Makefile                          |    2 +-
 src/libs/baseapp/run.cpp                           |   43 +-
 src/libs/config/yaml.cpp                           |   51 +-
 src/libs/core/threading/thread.cpp                 |    2 +-
 src/libs/core/version.h                            |    4 +-
 .../fvutils/colormap/bayes/bayes_histos_to_lut.cpp |    9 +-
 src/libs/fvutils/compression/jpeg_compressor.h     |    2 +-
 src/libs/fvutils/readers/png.cpp                   |    8 +-
 src/libs/fvutils/statistical/imagediff.cpp         |    2 +-
 src/libs/gui_utils/Makefile                        |    2 +-
 src/libs/gui_utils/avahi_dispatcher.cpp            |    1 +
 src/libs/gui_utils/avahi_dispatcher.h              |    1 +
 src/libs/gui_utils/service_chooser_dialog.cpp      |  103 +-
 src/libs/gui_utils/service_chooser_dialog.h        |    4 +-
 src/libs/gui_utils/service_model.cpp               |   64 +-
 src/libs/gui_utils/service_model.h                 |   32 +-
 src/libs/interfaces/BatteryInterface.h             |   12 +-
 src/libs/interfaces/CameraControlInterface.h       |   16 +-
 src/libs/interfaces/EclipseDebuggerInterface.h     |    8 +-
 src/libs/interfaces/FacerInterface.h               |   32 +-
 src/libs/interfaces/FacialExpressionInterface.h    |   20 +-
 src/libs/interfaces/GameStateInterface.h           |   16 +-
 src/libs/interfaces/GripperInterface.h             |   12 +-
 src/libs/interfaces/HumanSkeletonInterface.h       |    4 +-
 src/libs/interfaces/HumanoidMotionInterface.h      |   48 +-
 src/libs/interfaces/IMUInterface.h                 |    4 +-
 src/libs/interfaces/JointInterface.h               |    4 +-
 src/libs/interfaces/JoystickInterface.h            |   16 +-
 src/libs/interfaces/KeyValueInterface.h            |    4 +-
 src/libs/interfaces/KickerInterface.h              |   16 +-
 src/libs/interfaces/Laser1080Interface.h           |    4 +-
 src/libs/interfaces/Laser360Interface.h            |    4 +-
 src/libs/interfaces/Laser720Interface.h            |    4 +-
 src/libs/interfaces/LedInterface.h                 |   16 +-
 src/libs/interfaces/LocalizationInterface.h        |    8 +-
 src/libs/interfaces/MotorInterface.h               |   48 +-
 src/libs/interfaces/NavPathInterface.h             |    4 +-
 src/libs/interfaces/NavigatorInterface.h           |   68 +-
 src/libs/interfaces/ObjectPositionInterface.h      |    4 +-
 src/libs/interfaces/Position2DTrackInterface.h     |    4 +-
 src/libs/interfaces/Position3DInterface.h          |    4 +-
 src/libs/interfaces/SkillerInterface.h             |   24 +-
 src/libs/interfaces/SoccerPenaltyInterface.h       |    8 +-
 src/libs/interfaces/SpeechRecognitionInterface.h   |   12 +-
 src/libs/interfaces/SpeechSynthInterface.h         |    8 +-
 src/libs/interfaces/SwitchInterface.h              |   20 +-
 src/libs/interfaces/TestInterface.h                |   16 +-
 src/libs/interfaces/TransformInterface.h           |    4 +-
 src/libs/interfaces/VisualDisplay2DInterface.h     |   28 +-
 src/libs/interfaces/generator/cpp_generator.cpp    |    6 +-
 src/libs/interfaces/generator/digest.cpp           |   15 +-
 src/libs/netcomm/crypto/decrypt.cpp                |   12 +-
 src/libs/netcomm/crypto/encrypt.cpp                |   20 +-
 src/libs/netcomm/dns-sd/avahi_resolver_handler.cpp |    4 +-
 src/libs/netcomm/dns-sd/avahi_resolver_handler.h   |   10 +-
 src/libs/netcomm/dns-sd/avahi_thread.cpp           |  236 +++-
 src/libs/netcomm/dns-sd/avahi_thread.h             |   23 +-
 src/libs/netcomm/fawkes/client.cpp                 |  112 +-
 src/libs/netcomm/fawkes/client.h                   |   19 +-
 src/libs/netcomm/fawkes/network_manager.cpp        |   20 +-
 src/libs/netcomm/fawkes/network_manager.h          |   10 +-
 src/libs/netcomm/fawkes/server_thread.cpp          |   48 +-
 src/libs/netcomm/fawkes/server_thread.h            |   11 +-
 .../netcomm/service_discovery/browse_handler.h     |    2 +
 src/libs/netcomm/service_discovery/service.cpp     |   53 +-
 src/libs/netcomm/service_discovery/service.h       |    3 +-
 src/libs/netcomm/socket/datagram.cpp               |    5 +-
 src/libs/netcomm/socket/datagram.h                 |    2 +-
 src/libs/netcomm/socket/datagram_broadcast.cpp     |   10 +-
 src/libs/netcomm/socket/datagram_broadcast.h       |    2 +-
 src/libs/netcomm/socket/datagram_multicast.cpp     |   16 +-
 src/libs/netcomm/socket/datagram_multicast.h       |    5 +-
 src/libs/netcomm/socket/socket.cpp                 |  452 ++++++--
 src/libs/netcomm/socket/socket.h                   |   49 +-
 src/libs/netcomm/socket/stream.cpp                 |   25 +-
 src/libs/netcomm/socket/stream.h                   |    3 +-
 src/libs/netcomm/utils/acceptor_thread.cpp         |   34 +
 src/libs/netcomm/utils/acceptor_thread.h           |   16 +-
 src/libs/netcomm/utils/addr_comp.h                 |   74 ++
 .../pointcloud.h => netcomm/utils/addr_size.h}     |   46 +-
 src/libs/netcomm/utils/resolver.cpp                |   43 +-
 src/libs/netcomm/utils/resolver.h                  |   33 +-
 src/libs/netcomm/utils/resolver_thread.cpp         |  114 +--
 src/libs/netcomm/utils/resolver_thread.h           |   31 +-
 src/libs/netcomm/worldinfo/defs.h                  |   34 -
 src/libs/netcomm/worldinfo/handler.cpp             |  153 ---
 src/libs/netcomm/worldinfo/handler.h               |   84 --
 src/libs/netcomm/worldinfo/messages.h              |  256 ----
 src/libs/netcomm/worldinfo/transceiver.cpp         | 1239 --------------------
 src/libs/netcomm/worldinfo/transceiver.h           |  220 ----
 src/libs/protobuf_clips/communicator.cpp           |    6 +-
 src/libs/protobuf_clips/communicator.h             |    3 -
 src/libs/protobuf_comm/crypto.cpp                  |   24 +-
 src/libs/utils/system/argparser.cpp                |  138 ++-
 src/libs/utils/system/argparser.h                  |    4 +
 src/libs/webview/access_log.cpp                    |    2 +-
 src/libs/webview/server.cpp                        |   38 +-
 src/libs/webview/server.h                          |    7 +-
 src/lua/skills/generic/goto.lua                    |  169 ++--
 src/lua/skills/generic/relgoto.lua                 |  184 +--
 src/plugins/Makefile                               |    2 +-
 src/plugins/amcl/amcl_thread.cpp                   |    2 +-
 .../interfaces/OpenCVStereoParamsInterface.h_ext   |   48 +-
 src/plugins/clips-protobuf/clips/protobuf.clp      |    3 +-
 .../interfaces/DynamixelServoInterface.h_ext       |   80 +-
 .../gazsim_vis_localization_thread.cpp             |   10 +-
 src/plugins/gazebo/msgs/Float.proto                |    1 +
 src/plugins/gazebo/msgs/LightSignalDetection.proto |    4 +-
 src/plugins/gazebo/msgs/SimTime.proto              |    4 +-
 src/plugins/gossip/aspect/Makefile                 |    2 +-
 src/plugins/jaco/arm_kindrv.cpp                    |    7 +-
 .../jaco/interfaces/JacoBimanualInterface.h_ext    |   20 +-
 src/plugins/jaco/interfaces/JacoInterface.h_ext    |   40 +-
 src/plugins/jaco/openrave_thread.cpp               |    2 +-
 .../katana/interfaces/KatanaInterface.h_ext        |   68 +-
 .../interfaces/LaserClusterInterface.h_ext         |   12 +-
 .../interfaces/LaserLineInterface.h_ext            |    4 +-
 .../nao/interfaces/NaoJointPositionInterface.h_ext |   20 +-
 .../interfaces/NaoJointStiffnessInterface.h_ext    |   16 +-
 .../nao/interfaces/NaoSensorInterface.h_ext        |   16 +-
 .../interfaces/NavGraphGeneratorInterface.h_ext    |   64 +-
 .../HumanSkeletonProjectionInterface.h_ext         |    4 +-
 .../openrave/interfaces/OpenRaveInterface.h_ext    |   48 +-
 .../pantilt/interfaces/PanTiltInterface.h_ext      |   40 +-
 .../interfaces/PclDatabaseMergeInterface.h_ext     |    8 +-
 .../interfaces/PclDatabaseRetrieveInterface.h_ext  |    8 +-
 .../interfaces/PclDatabaseStoreInterface.h_ext     |    8 +-
 .../refboxcomm/processor}/enums.cpp                |    2 +-
 .../refboxcomm/processor}/enums.h                  |    4 +-
 src/plugins/refboxcomm/processor/msl2010.cpp       |    2 +-
 src/plugins/refboxcomm/processor/spl.cpp           |    2 +-
 src/plugins/refboxcomm/processor/spl.h             |    2 +-
 src/plugins/refboxcomm/processor/state_handler.h   |    2 +-
 .../interfaces/RobotinoSensorInterface.h_ext       |   12 +-
 src/plugins/roomba/Roomba500Interface.h_ext        |   28 +-
 src/plugins/skiller/SkillerDebugInterface.h_ext    |   16 +-
 src/plugins/ttmainloop/thread.cpp                  |    2 +-
 src/plugins/webview/service_browse_handler.cpp     |    1 +
 src/plugins/webview/service_browse_handler.h       |    1 +
 src/plugins/webview/webview_thread.cpp             |   23 +-
 src/plugins/webview/webview_thread.h               |    2 +
 src/plugins/worldmodel/Makefile                    |   46 -
 src/plugins/worldmodel/fusers/fuser.cpp            |   47 -
 src/plugins/worldmodel/fusers/fuser.h              |   35 -
 src/plugins/worldmodel/fusers/multi_copy.cpp       |  165 ---
 src/plugins/worldmodel/fusers/multi_copy.h         |   63 -
 src/plugins/worldmodel/fusers/objpos_average.cpp   |  293 -----
 src/plugins/worldmodel/fusers/objpos_average.h     |   67 --
 src/plugins/worldmodel/fusers/objpos_majority.cpp  |  534 ---------
 src/plugins/worldmodel/fusers/objpos_majority.h    |  128 --
 src/plugins/worldmodel/fusers/qa/Makefile          |   29 -
 .../worldmodel/fusers/qa/qa_objpos_majority.cpp    |  330 ------
 src/plugins/worldmodel/fusers/single_copy.cpp      |   74 --
 src/plugins/worldmodel/fusers/single_copy.h        |   49 -
 src/plugins/worldmodel/net_thread.cpp              |  491 --------
 src/plugins/worldmodel/net_thread.h                |  134 ---
 src/plugins/worldmodel/wm_thread.cpp               |  285 -----
 src/plugins/worldmodel/wm_thread.h                 |   82 --
 src/plugins/worldmodel/worldmodel_plugin.cpp       |   50 -
 src/plugins/worldmodel/worldmodel_plugin.h         |   34 -
 src/tools/Makefile                                 |    2 +-
 src/tools/battery_monitor/battery_monitor.cpp      |    1 +
 src/tools/battery_monitor/battery_monitor.h        |    1 +
 src/tools/netloggui/netloggui.cpp                  |    6 +-
 src/tools/plugin/main.cpp                          |    2 +-
 src/tools/refboxrep/Makefile                       |   35 -
 src/tools/refboxrep/ffrefboxrep.txt                |   93 --
 src/tools/refboxrep/main.cpp                       |  184 ---
 src/tools/refboxrep/msl2007.cpp                    |  257 ----
 src/tools/refboxrep/msl2007.h                      |   59 -
 src/tools/refboxrep/msl2008.cpp                    |  361 ------
 src/tools/refboxrep/msl2008.h                      |   72 --
 src/tools/refboxrep/msl2010.cpp                    |  401 -------
 src/tools/refboxrep/msl2010.h                      |   78 --
 src/tools/refboxrep/refbox_state_sender.cpp        |  257 ----
 src/tools/refboxrep/refbox_state_sender.h          |   94 --
 src/tools/refboxrep/refbox_state_writer.cpp        |  322 -----
 src/tools/refboxrep/refbox_state_writer.h          |   69 --
 src/tools/refboxrep/spl.cpp                        |  173 ---
 src/tools/refboxrep/spl.h                          |   95 --
 src/tools/vision/net.cpp                           |    1 +
 190 files changed, 1957 insertions(+), 9232 deletions(-)
 create mode 100644 cfg/conf.d/network.yaml
 create mode 100644 src/libs/netcomm/utils/addr_comp.h
 copy src/libs/{aspect/pointcloud.h => netcomm/utils/addr_size.h} (61%)
 delete mode 100644 src/libs/netcomm/worldinfo/defs.h
 delete mode 100644 src/libs/netcomm/worldinfo/handler.cpp
 delete mode 100644 src/libs/netcomm/worldinfo/handler.h
 delete mode 100644 src/libs/netcomm/worldinfo/messages.h
 delete mode 100644 src/libs/netcomm/worldinfo/transceiver.cpp
 delete mode 100644 src/libs/netcomm/worldinfo/transceiver.h
 rename src/{libs/netcomm/worldinfo => plugins/refboxcomm/processor}/enums.cpp (99%)
 rename src/{libs/netcomm/worldinfo => plugins/refboxcomm/processor}/enums.h (98%)
 delete mode 100644 src/plugins/worldmodel/Makefile
 delete mode 100644 src/plugins/worldmodel/fusers/fuser.cpp
 delete mode 100644 src/plugins/worldmodel/fusers/fuser.h
 delete mode 100644 src/plugins/worldmodel/fusers/multi_copy.cpp
 delete mode 100644 src/plugins/worldmodel/fusers/multi_copy.h
 delete mode 100644 src/plugins/worldmodel/fusers/objpos_average.cpp
 delete mode 100644 src/plugins/worldmodel/fusers/objpos_average.h
 delete mode 100644 src/plugins/worldmodel/fusers/objpos_majority.cpp
 delete mode 100644 src/plugins/worldmodel/fusers/objpos_majority.h
 delete mode 100644 src/plugins/worldmodel/fusers/qa/Makefile
 delete mode 100644 src/plugins/worldmodel/fusers/qa/qa_objpos_majority.cpp
 delete mode 100644 src/plugins/worldmodel/fusers/single_copy.cpp
 delete mode 100644 src/plugins/worldmodel/fusers/single_copy.h
 delete mode 100644 src/plugins/worldmodel/net_thread.cpp
 delete mode 100644 src/plugins/worldmodel/net_thread.h
 delete mode 100644 src/plugins/worldmodel/wm_thread.cpp
 delete mode 100644 src/plugins/worldmodel/wm_thread.h
 delete mode 100644 src/plugins/worldmodel/worldmodel_plugin.cpp
 delete mode 100644 src/plugins/worldmodel/worldmodel_plugin.h
 delete mode 100644 src/tools/refboxrep/Makefile
 delete mode 100644 src/tools/refboxrep/ffrefboxrep.txt
 delete mode 100644 src/tools/refboxrep/main.cpp
 delete mode 100644 src/tools/refboxrep/msl2007.cpp
 delete mode 100644 src/tools/refboxrep/msl2007.h
 delete mode 100644 src/tools/refboxrep/msl2008.cpp
 delete mode 100644 src/tools/refboxrep/msl2008.h
 delete mode 100644 src/tools/refboxrep/msl2010.cpp
 delete mode 100644 src/tools/refboxrep/msl2010.h
 delete mode 100644 src/tools/refboxrep/refbox_state_sender.cpp
 delete mode 100644 src/tools/refboxrep/refbox_state_sender.h
 delete mode 100644 src/tools/refboxrep/refbox_state_writer.cpp
 delete mode 100644 src/tools/refboxrep/refbox_state_writer.h
 delete mode 100644 src/tools/refboxrep/spl.cpp
 delete mode 100644 src/tools/refboxrep/spl.h


- *Diffs* -------------------------------------------------------------

- *commit* a9eafa99fdaedd49aea281f9b6bb497a982cbe23 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Sep 20 17:57:53 2016 +0200
Subject: utils: moved string utils for command argv and envs into utils/misc

 .../utils/misc/string_commands.cpp}                |    0
 .../string.h => libs/utils/misc/string_commands.h} |    0
 2 files changed, 0 insertions(+), 0 deletions(-)


- *commit* f55876bedc97abb8f10b05867c3f037c00f7c56f - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Sep 20 18:32:33 2016 +0200
Subject: utils: require cpp11

 src/libs/utils/Makefile |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

_Diff for modified files_:
diff --git a/src/libs/utils/Makefile b/src/libs/utils/Makefile
index 5f8c937..d84e9b3 100644
--- a/src/libs/utils/Makefile
+++ b/src/libs/utils/Makefile
@@ -43,11 +43,17 @@ LDFLAGS += $(LDFLAGS_LIBMAGIC)
 
 OBJS_all = $(OBJS_libfawkesutils) $(OBJS_lua_fawkesutils)
 LIBS_all  = $(LIBDIR)/libfawkesutils.so
-ifeq ($(HAVE_TOLUA),1)
+ifeq ($(HAVE_TOLUA)$(HAVE_CPP11),11)
+  CFLAGS += $(CFLAGS_CPP11)
   LIBS_all += $(LUALIBDIR)/fawkesutils.so
   TARGETS_all += $(SRCDIR)/fawkesutils_tolua.cpp
 else
-  WARN_TARGETS += warning_tolua_wrapper
+  ifneq ($(HAVE_CPP11),1)
+    WARN_TARGETS += warning_cpp11
+  endif
+  ifneq ($(HAVE_TOLUA),1)
+    WARN_TARGETS += warning_tolua_wrapper
+  endif
 endif
 
 ifneq ($(HAVE_INOTIFY),1)
@@ -60,6 +66,9 @@ all: $(WARN_TARGETS)
 warning_libmagic:
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TYELLOW)Restricted file type detection support$(TNORMAL) (file[-devel] (libmagic) not installed)"
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TYELLOW)File monitoring utils cannot be built$(TNORMAL) (inotify headers not found)"
+warning_cpp11:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting utils$(TNORMAL) " \
+		"(CPP11 not available)"
 endif
 
 $(LUALIBDIR)/fawkesutils.$(SOEXT): | $(LIBDIR)/libfawkesutils.$(SOEXT)

- *commit* c08bd4f70216f2e4d1b6ed47a88104dd5ec055a2 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Sep 20 18:34:36 2016 +0200
Subject: openprs: properly use moved string utils

 src/libs/utils/misc/string_commands.cpp            |    3 ++-
 src/libs/utils/misc/string_commands.h              |    6 +++---
 .../openprs/aspect/openprs_kernel_manager.cpp      |    2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

_Diff for modified files_:
diff --git a/src/libs/utils/misc/string_commands.cpp b/src/libs/utils/misc/string_commands.cpp
index 80a4122..960ae90 100644
--- a/src/libs/utils/misc/string_commands.cpp
+++ b/src/libs/utils/misc/string_commands.cpp
@@ -1,6 +1,6 @@
 
 /***************************************************************************
- *  string.cpp - string utilities
+ *  string.cpp - string utilities for command argv and envs
  *
  *  Created: Fri Aug 22 15:32:47 2014
  *  Copyright  2014  Tim Niemueller [www.niemueller.de]
@@ -26,6 +26,7 @@
 #include <tuple>
 #include <string>
 #include <cstring>
+#include <vector>
 
 namespace fawkes {
 #if 0 /* just to make Emacs auto-indent happy */
diff --git a/src/libs/utils/misc/string_commands.h b/src/libs/utils/misc/string_commands.h
index 74745e6..ab864b4 100644
--- a/src/libs/utils/misc/string_commands.h
+++ b/src/libs/utils/misc/string_commands.h
@@ -1,6 +1,6 @@
 
 /***************************************************************************
- *  string.h - string utilities
+ *  string.h - string utilities for command argv and envs
  *
  *  Created: Fri Aug 22 14:49:05 2014
  *  Copyright  2014  Tim Niemueller [www.niemueller.de]
@@ -20,8 +20,8 @@
  *  Read the full text in the LICENSE.GPL file in the doc directory.
  */
 
-#ifndef __PLUGINS_OPENPRS_UTILS_STRING_H_
-#define __PLUGINS_OPENPRS_UTILS_STRING_H_
+#ifndef __PLUGINS_UTILS_STRING_H_
+#define __PLUGINS_UTILS_STRING_H_
 
 #include <string>
 #include <vector>
diff --git a/src/plugins/openprs/aspect/openprs_kernel_manager.cpp b/src/plugins/openprs/aspect/openprs_kernel_manager.cpp
index 3ff143a..79320c9 100644
--- a/src/plugins/openprs/aspect/openprs_kernel_manager.cpp
+++ b/src/plugins/openprs/aspect/openprs_kernel_manager.cpp
@@ -22,7 +22,7 @@
 
 #include <plugins/openprs/aspect/openprs_kernel_manager.h>
 #include <plugins/openprs/utils/proc.h>
-#include <plugins/openprs/utils/string.h>
+#include <utils/misc/string_commands.h>
 #include <logging/logger.h>
 #include <config/config.h>
 #include <utils/time/time.h>

- *commit* 98619545a806b6ccd04669badcea4571b002702a - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Sep 20 18:37:40 2016 +0200
Subject: sub_process: moved utils to create sub processes into utils

 .../utils => libs/utils/sub_process}/proc.cpp      |    0
 .../utils => libs/utils/sub_process}/proc.h        |    0
 2 files changed, 0 insertions(+), 0 deletions(-)


- *commit* 016379fe9320b6c0ce981af3265b0c6ebc1d110f - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Sep 20 19:26:05 2016 +0200
Subject: utils: require boost asio and system for sb_process utils

 src/libs/utils/Makefile |   21 +++++++++++++++++----
 1 files changed, 17 insertions(+), 4 deletions(-)

_Diff for modified files_:
diff --git a/src/libs/utils/Makefile b/src/libs/utils/Makefile
index d84e9b3..12da36a 100644
--- a/src/libs/utils/Makefile
+++ b/src/libs/utils/Makefile
@@ -16,9 +16,13 @@
 BASEDIR = ../../..
 include $(BASEDIR)/etc/buildsys/config.mk
 include $(BUILDSYSDIR)/lua.mk
+include $(BASEDIR)/etc/buildsys/boost.mk
 
 FILTER_OUT=%_tolua.o
 
+REQ_BOOST_LIBS = asio system
+HAVE_BOOST_LIBS = $(call boost-have-libs,$(REQ_BOOST_LIBS))
+
 ifneq ($(wildcard $(SYSROOT)/usr/include/magic.h $(SYSROOT)/opt/local/include/magic.h),)
   HAVE_LIBMAGIC = 1
   LIBS_LIBMAGIC = magic
@@ -42,10 +46,13 @@ CFLAGS  += $(CFLAGS_LIBMAGIC)
 LDFLAGS += $(LDFLAGS_LIBMAGIC)
 
 OBJS_all = $(OBJS_libfawkesutils) $(OBJS_lua_fawkesutils)
-LIBS_all  = $(LIBDIR)/libfawkesutils.so
-ifeq ($(HAVE_TOLUA)$(HAVE_CPP11),11)
-  CFLAGS += $(CFLAGS_CPP11)
+
+ifeq ($(HAVE_TOLUA)$(HAVE_CPP11)$(HAVE_BOOST_LIBS),111)
+  CFLAGS += $(CFLAGS_CPP11) $(call boost-libs-cflags,$(REQ_BOOST_LIBS))
   LIBS_all += $(LUALIBDIR)/fawkesutils.so
+  LDFLAGS += $(call boost-libs-ldflags,$(REQ_BOOST_LIBS))
+
+  LIBS_all  = $(LIBDIR)/libfawkesutils.so
   TARGETS_all += $(SRCDIR)/fawkesutils_tolua.cpp
 else
   ifneq ($(HAVE_CPP11),1)
@@ -54,6 +61,9 @@ else
   ifneq ($(HAVE_TOLUA),1)
     WARN_TARGETS += warning_tolua_wrapper
   endif
+  ifneq ($(HAVE_BOOST_LIBS),1)
+    WARN_TARGETS_BOOST = $(foreach l,$(REQ_BOOST_LIBS),$(if $(call boost-have-lib,$l),, warning_boost_$l))
+  endif
 endif
 
 ifneq ($(HAVE_INOTIFY),1)
@@ -61,7 +71,7 @@ ifneq ($(HAVE_INOTIFY),1)
 endif
 
 ifeq ($(OBJSSUBMAKE),1)
-all: $(WARN_TARGETS)
+all: $(WARN_TARGETS) $(WARN_TARGETS_BOOST)
 .PHONY: warning_libmagic warning_inotify
 warning_libmagic:
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TYELLOW)Restricted file type detection support$(TNORMAL) (file[-devel] (libmagic) not installed)"
@@ -69,6 +79,9 @@ warning_libmagic:
 warning_cpp11:
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting utils$(TNORMAL) " \
 		"(CPP11 not available)"
+$(WARN_TARGETS_BOOST): warning_boost_%:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Cannot build utils library$(TNORMAL) (Boost library $* not found)"endif
+
 endif
 
 $(LUALIBDIR)/fawkesutils.$(SOEXT): | $(LIBDIR)/libfawkesutils.$(SOEXT)

- *commit* 598ba98d3a52fd78ed3b68c6070b2e19ee0b3940 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Sep 20 19:30:53 2016 +0200
Subject: openprs: properly use moved sub_process utils

 .../openprs/aspect/openprs_kernel_manager.cpp      |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/openprs/aspect/openprs_kernel_manager.cpp b/src/plugins/openprs/aspect/openprs_kernel_manager.cpp
index 79320c9..38fb262 100644
--- a/src/plugins/openprs/aspect/openprs_kernel_manager.cpp
+++ b/src/plugins/openprs/aspect/openprs_kernel_manager.cpp
@@ -21,7 +21,7 @@
  */
 
 #include <plugins/openprs/aspect/openprs_kernel_manager.h>
-#include <plugins/openprs/utils/proc.h>
+#include <utils/sub_process/proc.h>
 #include <utils/misc/string_commands.h>
 #include <logging/logger.h>
 #include <config/config.h>

- *commit* 1623fdd0d5c4e211211f357747c6cad60c979277 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Sun May 1 20:14:11 2016 +0200
Subject: robot-memory: skeleton for experimental plugin

 src/plugins/Makefile                               |    2 +-
 src/plugins/{mongodb_log => robot-memory}/Makefile |   32 +++----
 .../robot_memory_plugin.cpp}                       |   33 ++++---
 src/plugins/robot-memory/robot_memory_thread.cpp   |  105 ++++++++++++++++++++
 .../robot_memory_thread.h}                         |   32 +++---
 5 files changed, 152 insertions(+), 52 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/Makefile b/src/plugins/Makefile
index 16778fd..499bb73 100644
--- a/src/plugins/Makefile
+++ b/src/plugins/Makefile
@@ -26,7 +26,7 @@ SUBDIRS	= bbsync bblogger webview ttmainloop rrd rrdweb \
 	  static_transforms navgraph navgraph-clusters navgraph-generator colli \
 	  clips clips-agent clips-protobuf clips-webview clips-navgraph clips-ros \
 	  clips-tf openprs openprs-agent eclipse-clp \
-	  mongodb mongodb_log \
+	  mongodb mongodb_log robot-memory\
 	  openni refboxcomm ros player xmlrpc gossip \
 	  robot_state_publisher gazebo dynamixel navgraph-interactive \
 	  asp

- *commit* 32b8ee08f85b64127c1ef189b96715df6364d262 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Sun May 1 22:33:08 2016 +0200
Subject: robot-memory: execute queries from interface msg

 src/plugins/robot-memory/Makefile                  |    4 +-
 .../{pantilt => robot-memory}/interfaces/Makefile  |    6 +-
 .../interfaces/RobotMemoryInterface.cpp            |  271 ++++++++++++++++++++
 .../interfaces/RobotMemoryInterface.h_ext}         |   61 +++--
 .../interfaces/RobotMemoryInterface.tolua}         |   32 ++-
 .../interfaces/RobotMemoryInterface.xml            |   20 ++
 src/plugins/robot-memory/robot_memory_thread.cpp   |   60 +++++-
 src/plugins/robot-memory/robot_memory_thread.h     |    7 +
 8 files changed, 416 insertions(+), 45 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/Makefile b/src/plugins/robot-memory/Makefile
index d24702f..78fe64a 100644
--- a/src/plugins/robot-memory/Makefile
+++ b/src/plugins/robot-memory/Makefile
@@ -19,9 +19,11 @@ include $(BASEDIR)/etc/buildsys/config.mk
 include $(BUILDCONFDIR)/tf/tf.mk
 include $(BASEDIR)/src/plugins/mongodb/mongodb.mk
 
+PRESUBDIRS = interfaces
+
 LIBS_robot_memory = fawkescore fawkesaspects fawkesblackboard fawkesinterface \
 		fawkesutils fawkeslogging fawkesmongodbaspect fvutils \
-		fawkestf
+		fawkestf RobotMemoryInterface
 OBJS_robot_memory = $(patsubst %.cpp,%.o,$(patsubst qa/%,,$(subst $(SRCDIR)/,,$(realpath $(wildcard $(SRCDIR)/*.cpp)))))
 
 CFLAGS  += $(CFLAGS_MONGODB)
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index be08e53..2c35769 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -21,6 +21,10 @@
  */
 
 #include "robot_memory_thread.h"
+#include "interfaces/RobotMemoryInterface.h"
+#include <core/threading/mutex.h>
+#include <core/threading/mutex_locker.h>
+#include <memory>
 
 // from MongoDB
 #include <mongo/client/dbclient.h>
@@ -35,24 +39,34 @@ using namespace fawkes;
 
 /** Constructor. */
 RobotMemoryThread::RobotMemoryThread()
-  : Thread("RobotMemoryThread", Thread::OPMODE_WAITFORWAKEUP)
+	: Thread("RobotMemoryThread", Thread::OPMODE_WAITFORWAKEUP),
+	  BlockedTimingAspect(BlockedTimingAspect::WAKEUP_HOOK_WORLDSTATE)
 {
+  __mutex = new Mutex();
 }
 
 
 /** Destructor. */
 RobotMemoryThread::~RobotMemoryThread()
 {
+  delete __mutex;
 }
 
 
 void
 RobotMemoryThread::init()
 {
+	logger->log_info(name(), "Started RobotMemory");
 	__collection = "fawkes.msglog";
   try {
     __collection = config->get_string("/plugins/mongodb/logger_collection");
   } catch (Exception &e) {}
+
+  __rm_if = blackboard->open_for_writing<RobotMemoryInterface>(config->get_string("/plugins/robot-memory/interface-name").c_str());
+  __rm_if->set_error("");
+  __rm_if->set_result("");
+  
+  __rm_if->write();
 }
 
 
@@ -65,8 +79,52 @@ RobotMemoryThread::finalize()
 void
 RobotMemoryThread::loop()
 {
+	// process interface messages
+  while (! __rm_if->msgq_empty() ) {
+    if (__rm_if->msgq_first_is<RobotMemoryInterface::QueryMessage>()) {
+	    RobotMemoryInterface::QueryMessage* query = (RobotMemoryInterface::QueryMessage*) __rm_if->msgq_first();
+	    exec_query(query->query());
+    } else {
+      logger->log_warn(name(), "Unknown message received");
+    }
+
+    __rm_if->msgq_pop();
+  }
 }
 
+void RobotMemoryThread::exec_query(std::string query_string)
+{
+	logger->log_info(name(), "Executing Query: %s", query_string.c_str());
+
+	//only one query at a time
+	MutexLocker lock(__mutex);
+
+	//get query from string
+	Query query;
+	try{
+	  query = Query(query_string);
+	} catch (DBException &e) {
+		logger->log_error(name(), "Can't parse query_string '%s'\n Exception: %s",
+		                  query_string.c_str(), e.toString().c_str());
+		__rm_if->set_error((std::string("Can't parse query_string ") +  query_string
+		                    + "\nException: " + e.toString()).c_str());
+		return;
+	}
+
+	//actually execute query
+	std::unique_ptr<DBClientCursor> cursor;
+	try{
+	  cursor = mongodb_client->query(__collection, query);
+	} catch (DBException &e) {
+		logger->log_error(name(), "Error for query %s\n Exception: %s",
+		                  query_string.c_str(), e.toString().c_str());
+		__rm_if->set_error((std::string("Query error for ") +  query_string
+		                    + "\nException: " + e.toString()).c_str());
+		return;
+	}
+
+	logger->log_info(name(), "Query One result:\n%s", cursor->next().toString().c_str());
+}
 
 // void
 // RobotMemoryThread::insert_message(LogLevel ll, const char *component,
diff --git a/src/plugins/robot-memory/robot_memory_thread.h b/src/plugins/robot-memory/robot_memory_thread.h
index ca3ee06..004a454 100644
--- a/src/plugins/robot-memory/robot_memory_thread.h
+++ b/src/plugins/robot-memory/robot_memory_thread.h
@@ -29,11 +29,13 @@
 #include <aspect/clock.h>
 #include <plugins/mongodb/aspect/mongodb.h>
 #include <aspect/blackboard.h>
+#include <aspect/blocked_timing.h>
 
 #include <string>
 
 namespace fawkes {
   class Mutex;
+  class RobotMemoryInterface;
 }
 
 class RobotMemoryThread
@@ -42,6 +44,7 @@ class RobotMemoryThread
   public fawkes::ConfigurableAspect,
   public fawkes::ClockAspect,
   public fawkes::MongoDBAspect,
+	public fawkes::BlockedTimingAspect,
   public fawkes::BlackBoardAspect
 {
  public:
@@ -57,6 +60,10 @@ class RobotMemoryThread
 
  private:
   std::string    __collection;
+  fawkes::Mutex *__mutex;
+  fawkes::RobotMemoryInterface *__rm_if;
+
+  void exec_query(std::string query);
 };
 
 #endif

- *commit* c1151b06fd8a608b1c982e22d1853dd3b9aebc4a - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Sun May 1 23:38:09 2016 +0200
Subject: robot-memory: get info about parsed query

 src/plugins/robot-memory/robot_memory_thread.cpp |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 2c35769..32facf8 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -108,9 +108,18 @@ void RobotMemoryThread::exec_query(std::string query_string)
 		                  query_string.c_str(), e.toString().c_str());
 		__rm_if->set_error((std::string("Can't parse query_string ") +  query_string
 		                    + "\nException: " + e.toString()).c_str());
+		__rm_if->write();
 		return;
 	}
 
+	//introspect query
+	logger->log_info(name(), "Filter: %s", query.getFilter().toString().c_str());
+	logger->log_info(name(), "Modifiers: %s", query.getModifiers().toString().c_str());
+	logger->log_info(name(), "Sort: %s", query.getSort().toString().c_str());
+	logger->log_info(name(), "Hint: %s", query.getHint().toString().c_str());
+	logger->log_info(name(), "ReadPref: %s", query.getReadPref().toString().c_str());
+
+	
 	//actually execute query
 	std::unique_ptr<DBClientCursor> cursor;
 	try{
@@ -120,10 +129,13 @@ void RobotMemoryThread::exec_query(std::string query_string)
 		                  query_string.c_str(), e.toString().c_str());
 		__rm_if->set_error((std::string("Query error for ") +  query_string
 		                    + "\nException: " + e.toString()).c_str());
+		__rm_if->write();
 		return;
 	}
 
 	logger->log_info(name(), "Query One result:\n%s", cursor->next().toString().c_str());
+	__rm_if->set_result(cursor->next().toString().c_str());
+	__rm_if->write();
 }
 
 // void

- *commit* bb299bbf60d195569597b6ee3f9e8d6b37838eb7 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Mon May 9 17:50:45 2016 +0200
Subject: robot-memory: added insert, update, remove messages

 .../interfaces/RobotMemoryInterface.cpp            |  327 +++++++++++++++++++-
 .../interfaces/RobotMemoryInterface.h_ext          |   85 +++++
 .../interfaces/RobotMemoryInterface.tolua          |   87 ++++++
 .../interfaces/RobotMemoryInterface.xml            |   19 ++
 src/plugins/robot-memory/robot_memory_thread.cpp   |  219 ++++++++++---
 src/plugins/robot-memory/robot_memory_thread.h     |    7 +
 6 files changed, 696 insertions(+), 48 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp
index 40250f8..54650b9 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp
@@ -53,7 +53,10 @@ RobotMemoryInterface::RobotMemoryInterface() : Interface()
   add_fieldinfo(IFT_STRING, "error", 1024, data->error);
   add_fieldinfo(IFT_STRING, "result", 1024, data->result);
   add_messageinfo("QueryMessage");
-  unsigned char tmp_hash[] = {0xb5, 0xf6, 0xa0, 0x13, 0xd1, 0x30, 0x84, 0x19, 0xb6, 0x98, 0x2c, 0x3d, 0x92, 0xa4, 0x7a, 0xf};
+  add_messageinfo("InsertMessage");
+  add_messageinfo("UpdateMessage");
+  add_messageinfo("RemoveMessage");
+  unsigned char tmp_hash[] = {0x61, 0x88, 0x21, 0xcd, 0x5a, 0x65, 0x18, 0x8d, 0x60, 0xaf, 0xf5, 0x57, 0x30, 0x4c, 0x6b, 0xd8};
   set_hash(tmp_hash);
 }
 
@@ -131,6 +134,12 @@ RobotMemoryInterface::create_message(const char *type) const
 {
   if ( strncmp("QueryMessage", type, __INTERFACE_MESSAGE_TYPE_SIZE) == 0 ) {
     return new QueryMessage();
+  } else if ( strncmp("InsertMessage", type, __INTERFACE_MESSAGE_TYPE_SIZE) == 0 ) {
+    return new InsertMessage();
+  } else if ( strncmp("UpdateMessage", type, __INTERFACE_MESSAGE_TYPE_SIZE) == 0 ) {
+    return new UpdateMessage();
+  } else if ( strncmp("RemoveMessage", type, __INTERFACE_MESSAGE_TYPE_SIZE) == 0 ) {
+    return new RemoveMessage();
   } else {
     throw UnknownTypeException("The given type '%s' does not match any known "
                                "message type for this interface type.", type);
@@ -249,6 +258,310 @@ RobotMemoryInterface::QueryMessage::clone() const
 {
   return new RobotMemoryInterface::QueryMessage(this);
 }
+/** @class RobotMemoryInterface::InsertMessage <interfaces/RobotMemoryInterface.h>
+ * InsertMessage Fawkes BlackBoard Interface Message.
+ * 
+    
+ */
+
+
+/** Constructor with initial values.
+ * @param ini_insert initial value for insert
+ */
+RobotMemoryInterface::InsertMessage::InsertMessage(const char * ini_insert) : Message("InsertMessage")
+{
+  data_size = sizeof(InsertMessage_data_t);
+  data_ptr  = malloc(data_size);
+  memset(data_ptr, 0, data_size);
+  data      = (InsertMessage_data_t *)data_ptr;
+  data_ts   = (message_data_ts_t *)data_ptr;
+  strncpy(data->insert, ini_insert, 1024);
+  add_fieldinfo(IFT_STRING, "insert", 1024, data->insert);
+}
+/** Constructor */
+RobotMemoryInterface::InsertMessage::InsertMessage() : Message("InsertMessage")
+{
+  data_size = sizeof(InsertMessage_data_t);
+  data_ptr  = malloc(data_size);
+  memset(data_ptr, 0, data_size);
+  data      = (InsertMessage_data_t *)data_ptr;
+  data_ts   = (message_data_ts_t *)data_ptr;
+  add_fieldinfo(IFT_STRING, "insert", 1024, data->insert);
+}
+
+/** Destructor */
+RobotMemoryInterface::InsertMessage::~InsertMessage()
+{
+  free(data_ptr);
+}
+
+/** Copy constructor.
+ * @param m message to copy from
+ */
+RobotMemoryInterface::InsertMessage::InsertMessage(const InsertMessage *m) : Message("InsertMessage")
+{
+  data_size = m->data_size;
+  data_ptr  = malloc(data_size);
+  memcpy(data_ptr, m->data_ptr, data_size);
+  data      = (InsertMessage_data_t *)data_ptr;
+  data_ts   = (message_data_ts_t *)data_ptr;
+}
+
+/* Methods */
+/** Get insert value.
+ * Document to insert as JSON string
+ * @return insert value
+ */
+char *
+RobotMemoryInterface::InsertMessage::insert() const
+{
+  return data->insert;
+}
+
+/** Get maximum length of insert value.
+ * @return length of insert value, can be length of the array or number of 
+ * maximum number of characters for a string
+ */
+size_t
+RobotMemoryInterface::InsertMessage::maxlenof_insert() const
+{
+  return 1024;
+}
+
+/** Set insert value.
+ * Document to insert as JSON string
+ * @param new_insert new insert value
+ */
+void
+RobotMemoryInterface::InsertMessage::set_insert(const char * new_insert)
+{
+  strncpy(data->insert, new_insert, sizeof(data->insert));
+}
+
+/** Clone this message.
+ * Produces a message of the same type as this message and copies the
+ * data to the new message.
+ * @return clone of this message
+ */
+Message *
+RobotMemoryInterface::InsertMessage::clone() const
+{
+  return new RobotMemoryInterface::InsertMessage(this);
+}
+/** @class RobotMemoryInterface::UpdateMessage <interfaces/RobotMemoryInterface.h>
+ * UpdateMessage Fawkes BlackBoard Interface Message.
+ * 
+    
+ */
+
+
+/** Constructor with initial values.
+ * @param ini_query initial value for query
+ * @param ini_update initial value for update
+ */
+RobotMemoryInterface::UpdateMessage::UpdateMessage(const char * ini_query, const char * ini_update) : Message("UpdateMessage")
+{
+  data_size = sizeof(UpdateMessage_data_t);
+  data_ptr  = malloc(data_size);
+  memset(data_ptr, 0, data_size);
+  data      = (UpdateMessage_data_t *)data_ptr;
+  data_ts   = (message_data_ts_t *)data_ptr;
+  strncpy(data->query, ini_query, 1024);
+  strncpy(data->update, ini_update, 1024);
+  add_fieldinfo(IFT_STRING, "query", 1024, data->query);
+  add_fieldinfo(IFT_STRING, "update", 1024, data->update);
+}
+/** Constructor */
+RobotMemoryInterface::UpdateMessage::UpdateMessage() : Message("UpdateMessage")
+{
+  data_size = sizeof(UpdateMessage_data_t);
+  data_ptr  = malloc(data_size);
+  memset(data_ptr, 0, data_size);
+  data      = (UpdateMessage_data_t *)data_ptr;
+  data_ts   = (message_data_ts_t *)data_ptr;
+  add_fieldinfo(IFT_STRING, "query", 1024, data->query);
+  add_fieldinfo(IFT_STRING, "update", 1024, data->update);
+}
+
+/** Destructor */
+RobotMemoryInterface::UpdateMessage::~UpdateMessage()
+{
+  free(data_ptr);
+}
+
+/** Copy constructor.
+ * @param m message to copy from
+ */
+RobotMemoryInterface::UpdateMessage::UpdateMessage(const UpdateMessage *m) : Message("UpdateMessage")
+{
+  data_size = m->data_size;
+  data_ptr  = malloc(data_size);
+  memcpy(data_ptr, m->data_ptr, data_size);
+  data      = (UpdateMessage_data_t *)data_ptr;
+  data_ts   = (message_data_ts_t *)data_ptr;
+}
+
+/* Methods */
+/** Get query value.
+ * Query as JSON string
+ * @return query value
+ */
+char *
+RobotMemoryInterface::UpdateMessage::query() const
+{
+  return data->query;
+}
+
+/** Get maximum length of query value.
+ * @return length of query value, can be length of the array or number of 
+ * maximum number of characters for a string
+ */
+size_t
+RobotMemoryInterface::UpdateMessage::maxlenof_query() const
+{
+  return 1024;
+}
+
+/** Set query value.
+ * Query as JSON string
+ * @param new_query new query value
+ */
+void
+RobotMemoryInterface::UpdateMessage::set_query(const char * new_query)
+{
+  strncpy(data->query, new_query, sizeof(data->query));
+}
+
+/** Get update value.
+ * Update as JSON string
+ * @return update value
+ */
+char *
+RobotMemoryInterface::UpdateMessage::update() const
+{
+  return data->update;
+}
+
+/** Get maximum length of update value.
+ * @return length of update value, can be length of the array or number of 
+ * maximum number of characters for a string
+ */
+size_t
+RobotMemoryInterface::UpdateMessage::maxlenof_update() const
+{
+  return 1024;
+}
+
+/** Set update value.
+ * Update as JSON string
+ * @param new_update new update value
+ */
+void
+RobotMemoryInterface::UpdateMessage::set_update(const char * new_update)
+{
+  strncpy(data->update, new_update, sizeof(data->update));
+}
+
+/** Clone this message.
+ * Produces a message of the same type as this message and copies the
+ * data to the new message.
+ * @return clone of this message
+ */
+Message *
+RobotMemoryInterface::UpdateMessage::clone() const
+{
+  return new RobotMemoryInterface::UpdateMessage(this);
+}
+/** @class RobotMemoryInterface::RemoveMessage <interfaces/RobotMemoryInterface.h>
+ * RemoveMessage Fawkes BlackBoard Interface Message.
+ * 
+    
+ */
+
+
+/** Constructor with initial values.
+ * @param ini_query initial value for query
+ */
+RobotMemoryInterface::RemoveMessage::RemoveMessage(const char * ini_query) : Message("RemoveMessage")
+{
+  data_size = sizeof(RemoveMessage_data_t);
+  data_ptr  = malloc(data_size);
+  memset(data_ptr, 0, data_size);
+  data      = (RemoveMessage_data_t *)data_ptr;
+  data_ts   = (message_data_ts_t *)data_ptr;
+  strncpy(data->query, ini_query, 1024);
+  add_fieldinfo(IFT_STRING, "query", 1024, data->query);
+}
+/** Constructor */
+RobotMemoryInterface::RemoveMessage::RemoveMessage() : Message("RemoveMessage")
+{
+  data_size = sizeof(RemoveMessage_data_t);
+  data_ptr  = malloc(data_size);
+  memset(data_ptr, 0, data_size);
+  data      = (RemoveMessage_data_t *)data_ptr;
+  data_ts   = (message_data_ts_t *)data_ptr;
+  add_fieldinfo(IFT_STRING, "query", 1024, data->query);
+}
+
+/** Destructor */
+RobotMemoryInterface::RemoveMessage::~RemoveMessage()
+{
+  free(data_ptr);
+}
+
+/** Copy constructor.
+ * @param m message to copy from
+ */
+RobotMemoryInterface::RemoveMessage::RemoveMessage(const RemoveMessage *m) : Message("RemoveMessage")
+{
+  data_size = m->data_size;
+  data_ptr  = malloc(data_size);
+  memcpy(data_ptr, m->data_ptr, data_size);
+  data      = (RemoveMessage_data_t *)data_ptr;
+  data_ts   = (message_data_ts_t *)data_ptr;
+}
+
+/* Methods */
+/** Get query value.
+ * Query as JSON string
+ * @return query value
+ */
+char *
+RobotMemoryInterface::RemoveMessage::query() const
+{
+  return data->query;
+}
+
+/** Get maximum length of query value.
+ * @return length of query value, can be length of the array or number of 
+ * maximum number of characters for a string
+ */
+size_t
+RobotMemoryInterface::RemoveMessage::maxlenof_query() const
+{
+  return 1024;
+}
+
+/** Set query value.
+ * Query as JSON string
+ * @param new_query new query value
+ */
+void
+RobotMemoryInterface::RemoveMessage::set_query(const char * new_query)
+{
+  strncpy(data->query, new_query, sizeof(data->query));
+}
+
+/** Clone this message.
+ * Produces a message of the same type as this message and copies the
+ * data to the new message.
+ * @return clone of this message
+ */
+Message *
+RobotMemoryInterface::RemoveMessage::clone() const
+{
+  return new RobotMemoryInterface::RemoveMessage(this);
+}
 /** Check if message is valid and can be enqueued.
  * @param message Message to check
  * @return true if the message is valid, false otherwise.
@@ -260,6 +573,18 @@ RobotMemoryInterface::message_valid(const Message *message) const
   if ( m0 != NULL ) {
     return true;
   }
+  const InsertMessage *m1 = dynamic_cast<const InsertMessage *>(message);
+  if ( m1 != NULL ) {
+    return true;
+  }
+  const UpdateMessage *m2 = dynamic_cast<const UpdateMessage *>(message);
+  if ( m2 != NULL ) {
+    return true;
+  }
+  const RemoveMessage *m3 = dynamic_cast<const RemoveMessage *>(message);
+  if ( m3 != NULL ) {
+    return true;
+  }
   return false;
 }
 
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.h_ext b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.h_ext
index e0abd1a..ddd2d0b 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.h_ext
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.h_ext
@@ -80,6 +80,91 @@ class RobotMemoryInterface : public Interface
     virtual Message * clone() const;
   };
 
+  class InsertMessage : public Message
+  {
+   private:
+#pragma pack(push,4)
+    /** Internal data storage, do NOT modify! */
+    typedef struct {
+      int64_t timestamp_sec;  /**< Interface Unix timestamp, seconds */
+      int64_t timestamp_usec; /**< Interface Unix timestamp, micro-seconds */
+      char insert[1024]; /**< Document to insert as JSON string */
+    } InsertMessage_data_t;
+#pragma pack(pop)
+
+    InsertMessage_data_t *data;
+
+   public:
+    InsertMessage(const char * ini_insert);
+    InsertMessage();
+    ~InsertMessage();
+
+    InsertMessage(const InsertMessage *m);
+    /* Methods */
+    char * insert() const;
+    void set_insert(const char * new_insert);
+    size_t maxlenof_insert() const;
+    virtual Message * clone() const;
+  };
+
+  class UpdateMessage : public Message
+  {
+   private:
+#pragma pack(push,4)
+    /** Internal data storage, do NOT modify! */
+    typedef struct {
+      int64_t timestamp_sec;  /**< Interface Unix timestamp, seconds */
+      int64_t timestamp_usec; /**< Interface Unix timestamp, micro-seconds */
+      char query[1024]; /**< Query as JSON string */
+      char update[1024]; /**< Update as JSON string */
+    } UpdateMessage_data_t;
+#pragma pack(pop)
+
+    UpdateMessage_data_t *data;
+
+   public:
+    UpdateMessage(const char * ini_query, const char * ini_update);
+    UpdateMessage();
+    ~UpdateMessage();
+
+    UpdateMessage(const UpdateMessage *m);
+    /* Methods */
+    char * query() const;
+    void set_query(const char * new_query);
+    size_t maxlenof_query() const;
+    char * update() const;
+    void set_update(const char * new_update);
+    size_t maxlenof_update() const;
+    virtual Message * clone() const;
+  };
+
+  class RemoveMessage : public Message
+  {
+   private:
+#pragma pack(push,4)
+    /** Internal data storage, do NOT modify! */
+    typedef struct {
+      int64_t timestamp_sec;  /**< Interface Unix timestamp, seconds */
+      int64_t timestamp_usec; /**< Interface Unix timestamp, micro-seconds */
+      char query[1024]; /**< Query as JSON string */
+    } RemoveMessage_data_t;
+#pragma pack(pop)
+
+    RemoveMessage_data_t *data;
+
+   public:
+    RemoveMessage(const char * ini_query);
+    RemoveMessage();
+    ~RemoveMessage();
+
+    RemoveMessage(const RemoveMessage *m);
+    /* Methods */
+    char * query() const;
+    void set_query(const char * new_query);
+    size_t maxlenof_query() const;
+    virtual Message * clone() const;
+  };
+
   virtual bool message_valid(const Message *message) const;
  private:
   RobotMemoryInterface();
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.tolua b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.tolua
index 1b06b6b..67095b2 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.tolua
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.tolua
@@ -34,6 +34,93 @@ class RobotMemoryInterface : public Interface
     int maxlenof_query() const;
   };
 
+  class InsertMessage : public Message
+  {
+    InsertMessage(char * ini_insert);
+    InsertMessage();
+    ~InsertMessage();
+
+    unsigned int      id() const;
+
+    unsigned int      sender_id() const;
+    const char *      sender_thread_name() const;
+    Interface *       interface() const;
+    const char *      type() const;
+
+    const void *      datachunk() const;
+    unsigned int      datasize() const;
+
+    void              set_from_chunk(const void *chunk);
+
+    /* from RefCount */
+    void              ref();
+    void              unref();
+    unsigned int      refcount();
+
+    char * insert();
+    void set_insert(const char * new_insert);
+    int maxlenof_insert() const;
+  };
+
+  class UpdateMessage : public Message
+  {
+    UpdateMessage(char * ini_query, char * ini_update);
+    UpdateMessage();
+    ~UpdateMessage();
+
+    unsigned int      id() const;
+
+    unsigned int      sender_id() const;
+    const char *      sender_thread_name() const;
+    Interface *       interface() const;
+    const char *      type() const;
+
+    const void *      datachunk() const;
+    unsigned int      datasize() const;
+
+    void              set_from_chunk(const void *chunk);
+
+    /* from RefCount */
+    void              ref();
+    void              unref();
+    unsigned int      refcount();
+
+    char * query();
+    void set_query(const char * new_query);
+    int maxlenof_query() const;
+    char * update();
+    void set_update(const char * new_update);
+    int maxlenof_update() const;
+  };
+
+  class RemoveMessage : public Message
+  {
+    RemoveMessage(char * ini_query);
+    RemoveMessage();
+    ~RemoveMessage();
+
+    unsigned int      id() const;
+
+    unsigned int      sender_id() const;
+    const char *      sender_thread_name() const;
+    Interface *       interface() const;
+    const char *      type() const;
+
+    const void *      datachunk() const;
+    unsigned int      datasize() const;
+
+    void              set_from_chunk(const void *chunk);
+
+    /* from RefCount */
+    void              ref();
+    void              unref();
+    unsigned int      refcount();
+
+    char * query();
+    void set_query(const char * new_query);
+    int maxlenof_query() const;
+  };
+
   char * error();
   void set_error(const char * new_error);
   int maxlenof_error() const;
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml
index ae43d12..56dcfe7 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml
@@ -16,5 +16,24 @@
     </comment>
     <field type="string"  length="1024" name="query">Query as JSON string</field>
   </message>
+  <message name="Insert">
+    <comment>
+      Message to insert a document into the database.
+    </comment>
+    <field type="string"  length="1024" name="insert">Document to insert as JSON string</field>
+  </message>
+  <message name="Update">
+    <comment>
+      Message to update documents mathing a query.
+    </comment>
+    <field type="string"  length="1024" name="query">Query as JSON string</field>
+    <field type="string"  length="1024" name="update">Update as JSON string</field>
+  </message>
+  <message name="Remove">
+    <comment>
+      Message to remove documents matching the query.
+    </comment>
+    <field type="string"  length="1024" name="query">Query as JSON string</field>
+  </message>
 
 </interface>
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 32facf8..1821a83 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -59,7 +59,7 @@ RobotMemoryThread::init()
 	logger->log_info(name(), "Started RobotMemory");
 	__collection = "fawkes.msglog";
   try {
-    __collection = config->get_string("/plugins/mongodb/logger_collection");
+    __collection = config->get_string("/plugins/mongodb/test-collection");
   } catch (Exception &e) {}
 
   __rm_if = blackboard->open_for_writing<RobotMemoryInterface>(config->get_string("/plugins/robot-memory/interface-name").c_str());
@@ -82,8 +82,17 @@ RobotMemoryThread::loop()
 	// process interface messages
   while (! __rm_if->msgq_empty() ) {
     if (__rm_if->msgq_first_is<RobotMemoryInterface::QueryMessage>()) {
-	    RobotMemoryInterface::QueryMessage* query = (RobotMemoryInterface::QueryMessage*) __rm_if->msgq_first();
-	    exec_query(query->query());
+	    RobotMemoryInterface::QueryMessage* msg = (RobotMemoryInterface::QueryMessage*) __rm_if->msgq_first();
+	    exec_query(msg->query());
+    } else if (__rm_if->msgq_first_is<RobotMemoryInterface::InsertMessage>()) {
+	    RobotMemoryInterface::InsertMessage* msg = (RobotMemoryInterface::InsertMessage*) __rm_if->msgq_first();
+	    exec_insert(msg->insert());
+    } else if (__rm_if->msgq_first_is<RobotMemoryInterface::UpdateMessage>()) {
+	    RobotMemoryInterface::UpdateMessage* msg = (RobotMemoryInterface::UpdateMessage*) __rm_if->msgq_first();
+	    exec_update(msg->query(), msg->update());
+    } else if (__rm_if->msgq_first_is<RobotMemoryInterface::RemoveMessage>()) {
+	    RobotMemoryInterface::RemoveMessage* msg = (RobotMemoryInterface::RemoveMessage*) __rm_if->msgq_first();
+	    exec_remove(msg->query());
     } else {
       logger->log_warn(name(), "Unknown message received");
     }
@@ -113,17 +122,12 @@ void RobotMemoryThread::exec_query(std::string query_string)
 	}
 
 	//introspect query
-	logger->log_info(name(), "Filter: %s", query.getFilter().toString().c_str());
-	logger->log_info(name(), "Modifiers: %s", query.getModifiers().toString().c_str());
-	logger->log_info(name(), "Sort: %s", query.getSort().toString().c_str());
-	logger->log_info(name(), "Hint: %s", query.getHint().toString().c_str());
-	logger->log_info(name(), "ReadPref: %s", query.getReadPref().toString().c_str());
-
+	log(query, "executing query:");
 	
 	//actually execute query
 	std::unique_ptr<DBClientCursor> cursor;
 	try{
-	  cursor = mongodb_client->query(__collection, query);
+	  cursor = mongodb_client->query(dyn_collection, query);
 	} catch (DBException &e) {
 		logger->log_error(name(), "Error for query %s\n Exception: %s",
 		                  query_string.c_str(), e.toString().c_str());
@@ -133,43 +137,164 @@ void RobotMemoryThread::exec_query(std::string query_string)
 		return;
 	}
 
-	logger->log_info(name(), "Query One result:\n%s", cursor->next().toString().c_str());
-	__rm_if->set_result(cursor->next().toString().c_str());
+	if(cursor->more()){
+		BSONObj res = cursor->next();
+		logger->log_info(name(), "Query One result:\n%s", res.toString().c_str());
+		__rm_if->set_result(res.toString().c_str());
+		__rm_if->write();
+	}
+	else {
+		logger->log_info(name(), "Query result empty");
+	}
+}
+
+void RobotMemoryThread::exec_insert(std::string insert_string)
+{
+	logger->log_info(name(), "Executing Query: %s", insert_string.c_str());
+
+	//only one query at a time
+	MutexLocker lock(__mutex);
+
+	//get query from string
+  BSONObj obj;
+	try{
+		obj = fromjson(insert_string);
+	} catch (DBException &e) {
+		logger->log_error(name(), "Can't parse insert_string '%s'\n Exception: %s",
+		                  insert_string.c_str(), e.toString().c_str());
+		__rm_if->set_error((std::string("Can't parse insert_string ") +  insert_string
+		                    + "\nException: " + e.toString()).c_str());
+		__rm_if->write();
+		return;
+	}
+
+	log(obj, "Inserting:");
+	
+	//actually execute insert
+	try{
+	  mongodb_client->insert(__collection, obj);
+	} catch (DBException &e) {
+		logger->log_error(name(), "Error for insert %s\n Exception: %s",
+		                  insert_string.c_str(), e.toString().c_str());
+		__rm_if->set_error((std::string("Query error for ") +  insert_string
+		                    + "\nException: " + e.toString()).c_str());
+		__rm_if->write();
+		return;
+	}
+
+	__rm_if->set_result("insert successful");
 	__rm_if->write();
 }
 
-// void
-// RobotMemoryThread::insert_message(LogLevel ll, const char *component,
-// 				    const char *format, va_list va)
-// {
-//   if (log_level <= ll ) {
-//     MutexLocker lock(__mutex);
-//     struct timeval now;
-//     gettimeofday(&now, NULL);
-//     Date_t nowd = now.tv_sec * 1000 + now.tv_usec / 1000;
-
-//     char *msg;
-//     if (vasprintf(&msg, format, va) == -1) {
-//       // Cannot do anything useful, drop log message
-//       return;
-//     }
-
-//     BSONObjBuilder b;
-//     switch (ll) {
-//     case LL_DEBUG: b.append("level", "DEBUG"); break;
-//     case LL_INFO:  b.append("level", "INFO");  break;
-//     case LL_WARN:  b.append("level", "WARN");  break;
-//     case LL_ERROR: b.append("level", "ERROR"); break;
-//     default:       b.append("level", "UNKN");  break;
-//     }
-//     b.append("component", component);
-//     b.appendDate("time", nowd);
-//     b.append("message", msg);
-
-//     free(msg);
-
-//     try {
-//       mongodb_client->insert(__collection, b.obj());
-//     } catch (mongo::DBException &e) {} // ignored
-//   }
-// }
+void RobotMemoryThread::exec_update(std::string query_string, std::string update_string)
+{
+	logger->log_info(name(), "Executing Update %s for query %s",
+	                 update_string.c_str(), query_string.c_str());
+
+	//only one query at a time
+	MutexLocker lock(__mutex);
+
+	//get query from string
+	Query query;
+	try{
+	  query = Query(query_string);
+	} catch (DBException &e) {
+		logger->log_error(name(), "Can't parse query_string '%s'\n Exception: %s",
+		                  query_string.c_str(), e.toString().c_str());
+		__rm_if->set_error((std::string("Can't parse query_string ") +  query_string
+		                    + "\nException: " + e.toString()).c_str());
+		__rm_if->write();
+		return;
+	}
+	BSONObj update;
+	try{
+		update = fromjson(update_string);
+	} catch (DBException &e) {
+		logger->log_error(name(), "Can't parse update_string '%s'\n Exception: %s",
+		                  update_string.c_str(), e.toString().c_str());
+		__rm_if->set_error((std::string("Can't parse update_string ") +  update_string
+		                    + "\nException: " + e.toString()).c_str());
+		__rm_if->write();
+		return;
+	}
+
+	log(query, "Updating documents for query:");
+	log(update, "Updating with:");
+	
+	//actually execute update
+	try{
+		mongodb_client->update(__collection, query, update);
+	} catch (DBException &e) {
+		logger->log_error(name(), "Error for update %s for query %s\n Exception: %s",
+		                  update_string.c_str(), query_string.c_str(), e.toString().c_str());
+		__rm_if->set_error((std::string("Query error for ") +  query_string + " and update "
+		                    + update_string + "\nException: " + e.toString()).c_str());
+		__rm_if->write();
+		return;
+	}
+
+	__rm_if->set_result("update successful");
+	__rm_if->write();
+}
+
+void RobotMemoryThread::exec_remove(std::string query_string)
+{
+	logger->log_info(name(), "Executing Remove: %s", query_string.c_str());
+
+	//only one query at a time
+	MutexLocker lock(__mutex);
+
+	//get query from string
+	Query query;
+	try{
+	  query = Query(query_string);
+	} catch (DBException &e) {
+		logger->log_error(name(), "Can't parse query_string '%s'\n Exception: %s",
+		                  query_string.c_str(), e.toString().c_str());
+		__rm_if->set_error((std::string("Can't parse query_string ") +  query_string
+		                    + "\nException: " + e.toString()).c_str());
+		__rm_if->write();
+		return;
+	}
+
+	//introspect
+	log(query, "Removing documents for query:");
+	
+	//actually execute remove
+	try{
+	  mongodb_client->remove(__collection, query);
+	} catch (DBException &e) {
+		logger->log_error(name(), "Error for query %s\n Exception: %s",
+		                  query_string.c_str(), e.toString().c_str());
+		__rm_if->set_error((std::string("Query error for ") +  query_string
+		                    + "\nException: " + e.toString()).c_str());
+		__rm_if->write();
+		return;
+	}
+
+	__rm_if->set_result("remove successful");
+	__rm_if->write();
+}
+
+void
+RobotMemoryThread::log(Query query, std::string what)
+{
+	std::string output = what
+		+ "\nFilter: " + query.getFilter().toString()
+		+ "\nModifiers: " + query.getModifiers().toString()
+		+ "\nSort: " + query.getSort().toString()
+		+ "\nHint: " + query.getHint().toString()
+		+ "\nReadPref: " + query.getReadPref().toString();
+		
+	logger->log_info(name(), "%s", output.c_str());
+}
+
+void
+RobotMemoryThread::log(BSONObj obj, std::string what)
+{
+	std::string output = what
+		+ "\nObject: " + obj.toString();
+		
+	logger->log_info(name(), "%s", output.c_str());
+}
+
diff --git a/src/plugins/robot-memory/robot_memory_thread.h b/src/plugins/robot-memory/robot_memory_thread.h
index 004a454..ed32903 100644
--- a/src/plugins/robot-memory/robot_memory_thread.h
+++ b/src/plugins/robot-memory/robot_memory_thread.h
@@ -30,6 +30,7 @@
 #include <plugins/mongodb/aspect/mongodb.h>
 #include <aspect/blackboard.h>
 #include <aspect/blocked_timing.h>
+#include <mongo/client/dbclient.h>
 
 #include <string>
 
@@ -64,6 +65,12 @@ class RobotMemoryThread
   fawkes::RobotMemoryInterface *__rm_if;
 
   void exec_query(std::string query);
+  void exec_insert(std::string insert);
+  void exec_update(std::string query, std::string update);
+  void exec_remove(std::string query);
+
+  void log(mongo::Query query, std::string what);
+  void log(mongo::BSONObj obj, std::string what);
 };
 
 #endif

- *commit* 9a34c0e6a9fc873633df2945cdc36941adb4b9bb - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Mon May 9 18:59:23 2016 +0200
Subject: robot-memory: virtual knowledge base experiments

 src/plugins/robot-memory/robot_memory_thread.cpp |  108 +++++++++++++++++++++-
 src/plugins/robot-memory/robot_memory_thread.h   |   11 ++
 2 files changed, 115 insertions(+), 4 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 1821a83..7774ab7 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -103,6 +103,10 @@ RobotMemoryThread::loop()
 
 void RobotMemoryThread::exec_query(std::string query_string)
 {
+	exec_query(query_string, __collection);
+}
+void RobotMemoryThread::exec_query(std::string query_string, std::string collection)
+{
 	logger->log_info(name(), "Executing Query: %s", query_string.c_str());
 
 	//only one query at a time
@@ -123,11 +127,26 @@ void RobotMemoryThread::exec_query(std::string query_string)
 
 	//introspect query
 	log(query, "executing query:");
+
+	//check if virtual knowledge is queried
+	//rename field in query
+	if(query.getFilter().hasField("class")){
+		set_fields(query, std::string("{type:\"") +
+		           query.getFilter()["class"].String() + "\"}");
+		remove_field(query, "class");
+	}
+	log(query, "Virtual query:");
+	//computation on request
+	if(query.getFilter().hasField("bbinterface")){
+		collection = config->get_string("plugins/robot-memory/blackboard-collection");
+		gen_blackboard_data(query.getFilter()["bbinterface"].String());
+	}
+	log(query, "Virtual query:");
 	
 	//actually execute query
 	std::unique_ptr<DBClientCursor> cursor;
 	try{
-	  cursor = mongodb_client->query(dyn_collection, query);
+	  cursor = mongodb_client->query(collection, query);
 	} catch (DBException &e) {
 		logger->log_error(name(), "Error for query %s\n Exception: %s",
 		                  query_string.c_str(), e.toString().c_str());
@@ -150,6 +169,10 @@ void RobotMemoryThread::exec_query(std::string query_string)
 
 void RobotMemoryThread::exec_insert(std::string insert_string)
 {
+	exec_insert(insert_string, __collection);
+}
+void RobotMemoryThread::exec_insert(std::string insert_string, std::string collection)
+{
 	logger->log_info(name(), "Executing Query: %s", insert_string.c_str());
 
 	//only one query at a time
@@ -169,10 +192,12 @@ void RobotMemoryThread::exec_insert(std::string insert_string)
 	}
 
 	log(obj, "Inserting:");
+	set_fields(obj, "{type: \"test\"}");
+	log(obj, "Updated Inserting:");
 	
 	//actually execute insert
 	try{
-	  mongodb_client->insert(__collection, obj);
+	  mongodb_client->insert(collection, obj);
 	} catch (DBException &e) {
 		logger->log_error(name(), "Error for insert %s\n Exception: %s",
 		                  insert_string.c_str(), e.toString().c_str());
@@ -188,6 +213,11 @@ void RobotMemoryThread::exec_insert(std::string insert_string)
 
 void RobotMemoryThread::exec_update(std::string query_string, std::string update_string)
 {
+	exec_update(query_string, update_string, __collection);
+}
+void RobotMemoryThread::exec_update(std::string query_string, std::string update_string,
+                                    std::string collection)
+{
 	logger->log_info(name(), "Executing Update %s for query %s",
 	                 update_string.c_str(), query_string.c_str());
 
@@ -223,7 +253,7 @@ void RobotMemoryThread::exec_update(std::string query_string, std::string update
 	
 	//actually execute update
 	try{
-		mongodb_client->update(__collection, query, update);
+		mongodb_client->update(collection, query, update);
 	} catch (DBException &e) {
 		logger->log_error(name(), "Error for update %s for query %s\n Exception: %s",
 		                  update_string.c_str(), query_string.c_str(), e.toString().c_str());
@@ -239,6 +269,11 @@ void RobotMemoryThread::exec_update(std::string query_string, std::string update
 
 void RobotMemoryThread::exec_remove(std::string query_string)
 {
+	exec_remove(query_string, __collection);
+}
+
+void RobotMemoryThread::exec_remove(std::string query_string, std::string collection)
+{
 	logger->log_info(name(), "Executing Remove: %s", query_string.c_str());
 
 	//only one query at a time
@@ -262,7 +297,7 @@ void RobotMemoryThread::exec_remove(std::string query_string)
 	
 	//actually execute remove
 	try{
-	  mongodb_client->remove(__collection, query);
+	  mongodb_client->remove(collection, query);
 	} catch (DBException &e) {
 		logger->log_error(name(), "Error for query %s\n Exception: %s",
 		                  query_string.c_str(), e.toString().c_str());
@@ -298,3 +333,68 @@ RobotMemoryThread::log(BSONObj obj, std::string what)
 	logger->log_info(name(), "%s", output.c_str());
 }
 
+void
+RobotMemoryThread::set_fields(BSONObj &obj, std::string what)
+{
+	BSONObjBuilder b;
+	b.appendElements(obj);
+	b.appendElements(fromjson(what));
+	//override
+	obj = b.obj();
+}
+
+void
+RobotMemoryThread::set_fields(Query &q, std::string what)
+{
+	BSONObjBuilder b;
+	b.appendElements(q.getFilter());
+	b.appendElements(fromjson(what));
+
+	//TODO keep other stuff in query
+	// + "\nFilter: " + query.getFilter().toString()
+	// + "\nModifiers: " + query.getModifiers().toString()
+	// + "\nSort: " + query.getSort().toString()
+	// + "\nHint: " + query.getHint().toString()
+	// + "\nReadPref: " + query.getReadPref().toString();
+     
+	//override
+	q = Query(b.obj());
+}
+
+void
+RobotMemoryThread::remove_field(Query &q, std::string what)
+{
+	BSONObjBuilder b;
+	b.appendElements(q.getFilter().removeField(what));
+	
+	//TODO keep other stuff in query
+	// + "\nFilter: " + query.getFilter().toString()
+	// + "\nModifiers: " + query.getModifiers().toString()
+	// + "\nSort: " + query.getSort().toString()
+	// + "\nHint: " + query.getHint().toString()
+	// + "\nReadPref: " + query.getReadPref().toString();
+	
+	//override
+	q = Query(b.obj());
+}
+
+void
+RobotMemoryThread::gen_blackboard_data(std::string field)
+{
+	logger->log_info(name(), "Generating virtual kb for bb");
+
+	std::string collection = config->get_string("plugins/robot-memory/blackboard-collection");
+	
+	//remove old data first
+	mongodb_client->remove(collection, Query{"{}"});
+	
+	BSONObjBuilder b;
+	b.append("type", "bbinterface");
+	__rm_if->read();
+	b.append("bbinterface", __rm_if->uid());
+	b.append("error", __rm_if->error());
+	b.append("result", __rm_if->result());
+	
+	mongodb_client->insert(collection, b.obj());  
+}
+
diff --git a/src/plugins/robot-memory/robot_memory_thread.h b/src/plugins/robot-memory/robot_memory_thread.h
index ed32903..8a5013c 100644
--- a/src/plugins/robot-memory/robot_memory_thread.h
+++ b/src/plugins/robot-memory/robot_memory_thread.h
@@ -64,13 +64,24 @@ class RobotMemoryThread
   fawkes::Mutex *__mutex;
   fawkes::RobotMemoryInterface *__rm_if;
 
+  void exec_query(std::string query, std::string collection);
   void exec_query(std::string query);
+  void exec_insert(std::string insert, std::string collection);
   void exec_insert(std::string insert);
+  void exec_update(std::string query, std::string update, std::string collection);
   void exec_update(std::string query, std::string update);
+  void exec_remove(std::string query, std::string collection);
   void exec_remove(std::string query);
 
   void log(mongo::Query query, std::string what);
   void log(mongo::BSONObj obj, std::string what);
+
+  void set_fields(mongo::BSONObj &obj, std::string what);
+  void set_fields(mongo::Query &q, std::string what);
+  void remove_field(mongo::Query &q, std::string what);
+
+  //funtions to generate virtual knowledge
+  void gen_blackboard_data(std::string field);
 };
 
 #endif

- *commit* e75f3c1aaf1b6d38a1ff413dba71a13e1a942226 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed May 11 14:52:21 2016 +0200
Subject: robot-memory: added missing config file

 cfg/conf.d/robot-memory.yaml |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)


- *commit* 64fb85117583821d69860d2869069125aa5d9fda - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Aug 18 12:59:31 2016 +0200
Subject: robot-memory: added gtest skeleton for unit testing

 .../core => plugins/robot-memory}/tests/Makefile   |   26 ++++++++-----------
 .../robot-memory/tests/robot_memory_test.cpp}      |   22 +++++++++-------
 2 files changed, 23 insertions(+), 25 deletions(-)


- *commit* 71f2b98bb78fffd9ae2c53c35a025969d658b390 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Aug 23 18:51:52 2016 +0200
Subject: mongodb: hint in exception to start the mongod service

 src/plugins/mongodb/mongodb_thread.cpp |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/mongodb/mongodb_thread.cpp b/src/plugins/mongodb/mongodb_thread.cpp
index 081fd18..c2a7e5b 100644
--- a/src/plugins/mongodb/mongodb_thread.cpp
+++ b/src/plugins/mongodb/mongodb_thread.cpp
@@ -326,7 +326,7 @@ MongoDBThread::ClientConf::create_client()
       client = clconn;
       std::string errmsg;
       if (! clconn->connect(__conn_hostport, errmsg)) {
-	throw Exception("Could not connect to MongoDB at %s: %s",
+	throw Exception("Could not connect to MongoDB at %s: %s\nYou probably forgot to start/enable the mongod service",
 			__conn_hostport.toString().c_str(), errmsg.c_str());
       }
       std::list<AuthInfo>::iterator ai;

- *commit* c1ede99dd233168736a13bbe2187472feb11fadd - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Aug 23 18:55:19 2016 +0200
Subject: robot-memory: provide aspect for using the RobotMemory

 src/plugins/robot-memory/Makefile                  |    9 +-
 src/plugins/{nao => robot-memory}/aspect/Makefile  |   33 +-
 .../robot_memory_aspect.cpp}                       |   51 ++--
 .../robot_memory_aspect.h}                         |   47 ++--
 .../robot-memory/aspect/robot_memory_inifin.cpp    |   79 +++++
 .../robot_memory_inifin.h}                         |   35 ++-
 .../interfaces/RobotMemoryInterface.cpp            |    2 +-
 .../interfaces/RobotMemoryInterface.xml            |    2 +-
 src/plugins/robot-memory/robot_memory.cpp          |  305 +++++++++++++++++
 src/plugins/robot-memory/robot_memory.h            |   82 +++++
 src/plugins/robot-memory/robot_memory_thread.cpp   |  354 ++------------------
 src/plugins/robot-memory/robot_memory_thread.h     |   30 +--
 12 files changed, 594 insertions(+), 435 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/Makefile b/src/plugins/robot-memory/Makefile
index 78fe64a..6deb5cb 100644
--- a/src/plugins/robot-memory/Makefile
+++ b/src/plugins/robot-memory/Makefile
@@ -19,16 +19,13 @@ include $(BASEDIR)/etc/buildsys/config.mk
 include $(BUILDCONFDIR)/tf/tf.mk
 include $(BASEDIR)/src/plugins/mongodb/mongodb.mk
 
-PRESUBDIRS = interfaces
+PRESUBDIRS = interfaces aspect
 
 LIBS_robot_memory = fawkescore fawkesaspects fawkesblackboard fawkesinterface \
 		fawkesutils fawkeslogging fawkesmongodbaspect fvutils \
-		fawkestf RobotMemoryInterface
+		fawkestf RobotMemoryInterface fawkesrobotmemory
 OBJS_robot_memory = $(patsubst %.cpp,%.o,$(patsubst qa/%,,$(subst $(SRCDIR)/,,$(realpath $(wildcard $(SRCDIR)/*.cpp)))))
 
-CFLAGS  += $(CFLAGS_MONGODB)
-LDFLAGS += $(LDFLAGS_MONGODB)
-
 OBJS_all    = $(OBJS_robot_memory)
 
 ifeq ($(HAVE_MONGODB)$(HAVE_TF),11)
@@ -49,7 +46,7 @@ all: $(WARN_TARGETS)
 
 .PHONY: warning_mongodb warning_tf
 warning_mongodb:
-	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting MongoDB Logging Plugin$(TNORMAL) (mongodb[-devel] not installed)"
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting RobotMemory Plugin$(TNORMAL) (mongodb[-devel] not installed)"
 warning_tf:
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting PCL utility library$(TNORMAL) (tf framework not available)"
 endif
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp
index 54650b9..a60da8d 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp
@@ -56,7 +56,7 @@ RobotMemoryInterface::RobotMemoryInterface() : Interface()
   add_messageinfo("InsertMessage");
   add_messageinfo("UpdateMessage");
   add_messageinfo("RemoveMessage");
-  unsigned char tmp_hash[] = {0x61, 0x88, 0x21, 0xcd, 0x5a, 0x65, 0x18, 0x8d, 0x60, 0xaf, 0xf5, 0x57, 0x30, 0x4c, 0x6b, 0xd8};
+  unsigned char tmp_hash[] = {0x57, 0x8, 0x55, 0x6b, 0x61, 0x8, 0xc9, 0x16, 0xf7, 0x68, 0xcc, 0x7e, 0xae, 0xe2, 0x42, 0xe};
   set_hash(tmp_hash);
 }
 
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml
index 56dcfe7..498cda9 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml
@@ -24,7 +24,7 @@
   </message>
   <message name="Update">
     <comment>
-      Message to update documents mathing a query.
+      Message to update documents matching a query.
     </comment>
     <field type="string"  length="1024" name="query">Query as JSON string</field>
     <field type="string"  length="1024" name="update">Update as JSON string</field>
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 7774ab7..8bf74ec 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -26,10 +26,7 @@
 #include <core/threading/mutex_locker.h>
 #include <memory>
 
-// from MongoDB
-#include <mongo/client/dbclient.h>
 
-using namespace mongo;
 using namespace fawkes;
 
 /** @class RobotMemoryThread "robot_memory_thread.h"
@@ -40,39 +37,33 @@ using namespace fawkes;
 /** Constructor. */
 RobotMemoryThread::RobotMemoryThread()
 	: Thread("RobotMemoryThread", Thread::OPMODE_WAITFORWAKEUP),
-	  BlockedTimingAspect(BlockedTimingAspect::WAKEUP_HOOK_WORLDSTATE)
+	  BlockedTimingAspect(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PROCESS),
+    AspectProviderAspect(&robot_memory_inifin_)
 {
-  __mutex = new Mutex();
 }
 
 
 /** Destructor. */
 RobotMemoryThread::~RobotMemoryThread()
-{
-  delete __mutex;
-}
+{}
 
 
 void
 RobotMemoryThread::init()
 {
-	logger->log_info(name(), "Started RobotMemory");
-	__collection = "fawkes.msglog";
-  try {
-    __collection = config->get_string("/plugins/mongodb/test-collection");
-  } catch (Exception &e) {}
-
-  __rm_if = blackboard->open_for_writing<RobotMemoryInterface>(config->get_string("/plugins/robot-memory/interface-name").c_str());
-  __rm_if->set_error("");
-  __rm_if->set_result("");
-  
-  __rm_if->write();
+  //init RobotMemory itself
+  robot_memory = new RobotMemory(config, logger, clock, mongodb_client, blackboard);
+  robot_memory->init();
+  //prepare aspect initializer
+  robot_memory_inifin_.set_robot_memory(robot_memory);
 }
 
 
 void
 RobotMemoryThread::finalize()
 {
+  robot_memory_inifin_.set_robot_memory(NULL);
+  delete robot_memory;
 }
 
 
@@ -80,321 +71,24 @@ void
 RobotMemoryThread::loop()
 {
 	// process interface messages
-  while (! __rm_if->msgq_empty() ) {
-    if (__rm_if->msgq_first_is<RobotMemoryInterface::QueryMessage>()) {
-	    RobotMemoryInterface::QueryMessage* msg = (RobotMemoryInterface::QueryMessage*) __rm_if->msgq_first();
-	    exec_query(msg->query());
-    } else if (__rm_if->msgq_first_is<RobotMemoryInterface::InsertMessage>()) {
-	    RobotMemoryInterface::InsertMessage* msg = (RobotMemoryInterface::InsertMessage*) __rm_if->msgq_first();
-	    exec_insert(msg->insert());
-    } else if (__rm_if->msgq_first_is<RobotMemoryInterface::UpdateMessage>()) {
-	    RobotMemoryInterface::UpdateMessage* msg = (RobotMemoryInterface::UpdateMessage*) __rm_if->msgq_first();
-	    exec_update(msg->query(), msg->update());
-    } else if (__rm_if->msgq_first_is<RobotMemoryInterface::RemoveMessage>()) {
-	    RobotMemoryInterface::RemoveMessage* msg = (RobotMemoryInterface::RemoveMessage*) __rm_if->msgq_first();
-	    exec_remove(msg->query());
+  while (! robot_memory->rm_if_->msgq_empty() ) {
+    if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::QueryMessage>()) {
+	    RobotMemoryInterface::QueryMessage* msg = (RobotMemoryInterface::QueryMessage*) robot_memory->rm_if_->msgq_first();
+	    robot_memory->exec_query(msg->query());
+    } else if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::InsertMessage>()) {
+	    RobotMemoryInterface::InsertMessage* msg = (RobotMemoryInterface::InsertMessage*) robot_memory->rm_if_->msgq_first();
+	    robot_memory->exec_insert(msg->insert());
+    } else if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::UpdateMessage>()) {
+	    RobotMemoryInterface::UpdateMessage* msg = (RobotMemoryInterface::UpdateMessage*) robot_memory->rm_if_->msgq_first();
+	    robot_memory->exec_update(msg->query(), msg->update());
+    } else if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::RemoveMessage>()) {
+	    RobotMemoryInterface::RemoveMessage* msg = (RobotMemoryInterface::RemoveMessage*) robot_memory->rm_if_->msgq_first();
+	    robot_memory->exec_remove(msg->query());
     } else {
       logger->log_warn(name(), "Unknown message received");
     }
 
-    __rm_if->msgq_pop();
+    robot_memory->rm_if_->msgq_pop();
   }
 }
 
-void RobotMemoryThread::exec_query(std::string query_string)
-{
-	exec_query(query_string, __collection);
-}
-void RobotMemoryThread::exec_query(std::string query_string, std::string collection)
-{
-	logger->log_info(name(), "Executing Query: %s", query_string.c_str());
-
-	//only one query at a time
-	MutexLocker lock(__mutex);
-
-	//get query from string
-	Query query;
-	try{
-	  query = Query(query_string);
-	} catch (DBException &e) {
-		logger->log_error(name(), "Can't parse query_string '%s'\n Exception: %s",
-		                  query_string.c_str(), e.toString().c_str());
-		__rm_if->set_error((std::string("Can't parse query_string ") +  query_string
-		                    + "\nException: " + e.toString()).c_str());
-		__rm_if->write();
-		return;
-	}
-
-	//introspect query
-	log(query, "executing query:");
-
-	//check if virtual knowledge is queried
-	//rename field in query
-	if(query.getFilter().hasField("class")){
-		set_fields(query, std::string("{type:\"") +
-		           query.getFilter()["class"].String() + "\"}");
-		remove_field(query, "class");
-	}
-	log(query, "Virtual query:");
-	//computation on request
-	if(query.getFilter().hasField("bbinterface")){
-		collection = config->get_string("plugins/robot-memory/blackboard-collection");
-		gen_blackboard_data(query.getFilter()["bbinterface"].String());
-	}
-	log(query, "Virtual query:");
-	
-	//actually execute query
-	std::unique_ptr<DBClientCursor> cursor;
-	try{
-	  cursor = mongodb_client->query(collection, query);
-	} catch (DBException &e) {
-		logger->log_error(name(), "Error for query %s\n Exception: %s",
-		                  query_string.c_str(), e.toString().c_str());
-		__rm_if->set_error((std::string("Query error for ") +  query_string
-		                    + "\nException: " + e.toString()).c_str());
-		__rm_if->write();
-		return;
-	}
-
-	if(cursor->more()){
-		BSONObj res = cursor->next();
-		logger->log_info(name(), "Query One result:\n%s", res.toString().c_str());
-		__rm_if->set_result(res.toString().c_str());
-		__rm_if->write();
-	}
-	else {
-		logger->log_info(name(), "Query result empty");
-	}
-}
-
-void RobotMemoryThread::exec_insert(std::string insert_string)
-{
-	exec_insert(insert_string, __collection);
-}
-void RobotMemoryThread::exec_insert(std::string insert_string, std::string collection)
-{
-	logger->log_info(name(), "Executing Query: %s", insert_string.c_str());
-
-	//only one query at a time
-	MutexLocker lock(__mutex);
-
-	//get query from string
-  BSONObj obj;
-	try{
-		obj = fromjson(insert_string);
-	} catch (DBException &e) {
-		logger->log_error(name(), "Can't parse insert_string '%s'\n Exception: %s",
-		                  insert_string.c_str(), e.toString().c_str());
-		__rm_if->set_error((std::string("Can't parse insert_string ") +  insert_string
-		                    + "\nException: " + e.toString()).c_str());
-		__rm_if->write();
-		return;
-	}
-
-	log(obj, "Inserting:");
-	set_fields(obj, "{type: \"test\"}");
-	log(obj, "Updated Inserting:");
-	
-	//actually execute insert
-	try{
-	  mongodb_client->insert(collection, obj);
-	} catch (DBException &e) {
-		logger->log_error(name(), "Error for insert %s\n Exception: %s",
-		                  insert_string.c_str(), e.toString().c_str());
-		__rm_if->set_error((std::string("Query error for ") +  insert_string
-		                    + "\nException: " + e.toString()).c_str());
-		__rm_if->write();
-		return;
-	}
-
-	__rm_if->set_result("insert successful");
-	__rm_if->write();
-}
-
-void RobotMemoryThread::exec_update(std::string query_string, std::string update_string)
-{
-	exec_update(query_string, update_string, __collection);
-}
-void RobotMemoryThread::exec_update(std::string query_string, std::string update_string,
-                                    std::string collection)
-{
-	logger->log_info(name(), "Executing Update %s for query %s",
-	                 update_string.c_str(), query_string.c_str());
-
-	//only one query at a time
-	MutexLocker lock(__mutex);
-
-	//get query from string
-	Query query;
-	try{
-	  query = Query(query_string);
-	} catch (DBException &e) {
-		logger->log_error(name(), "Can't parse query_string '%s'\n Exception: %s",
-		                  query_string.c_str(), e.toString().c_str());
-		__rm_if->set_error((std::string("Can't parse query_string ") +  query_string
-		                    + "\nException: " + e.toString()).c_str());
-		__rm_if->write();
-		return;
-	}
-	BSONObj update;
-	try{
-		update = fromjson(update_string);
-	} catch (DBException &e) {
-		logger->log_error(name(), "Can't parse update_string '%s'\n Exception: %s",
-		                  update_string.c_str(), e.toString().c_str());
-		__rm_if->set_error((std::string("Can't parse update_string ") +  update_string
-		                    + "\nException: " + e.toString()).c_str());
-		__rm_if->write();
-		return;
-	}
-
-	log(query, "Updating documents for query:");
-	log(update, "Updating with:");
-	
-	//actually execute update
-	try{
-		mongodb_client->update(collection, query, update);
-	} catch (DBException &e) {
-		logger->log_error(name(), "Error for update %s for query %s\n Exception: %s",
-		                  update_string.c_str(), query_string.c_str(), e.toString().c_str());
-		__rm_if->set_error((std::string("Query error for ") +  query_string + " and update "
-		                    + update_string + "\nException: " + e.toString()).c_str());
-		__rm_if->write();
-		return;
-	}
-
-	__rm_if->set_result("update successful");
-	__rm_if->write();
-}
-
-void RobotMemoryThread::exec_remove(std::string query_string)
-{
-	exec_remove(query_string, __collection);
-}
-
-void RobotMemoryThread::exec_remove(std::string query_string, std::string collection)
-{
-	logger->log_info(name(), "Executing Remove: %s", query_string.c_str());
-
-	//only one query at a time
-	MutexLocker lock(__mutex);
-
-	//get query from string
-	Query query;
-	try{
-	  query = Query(query_string);
-	} catch (DBException &e) {
-		logger->log_error(name(), "Can't parse query_string '%s'\n Exception: %s",
-		                  query_string.c_str(), e.toString().c_str());
-		__rm_if->set_error((std::string("Can't parse query_string ") +  query_string
-		                    + "\nException: " + e.toString()).c_str());
-		__rm_if->write();
-		return;
-	}
-
-	//introspect
-	log(query, "Removing documents for query:");
-	
-	//actually execute remove
-	try{
-	  mongodb_client->remove(collection, query);
-	} catch (DBException &e) {
-		logger->log_error(name(), "Error for query %s\n Exception: %s",
-		                  query_string.c_str(), e.toString().c_str());
-		__rm_if->set_error((std::string("Query error for ") +  query_string
-		                    + "\nException: " + e.toString()).c_str());
-		__rm_if->write();
-		return;
-	}
-
-	__rm_if->set_result("remove successful");
-	__rm_if->write();
-}
-
-void
-RobotMemoryThread::log(Query query, std::string what)
-{
-	std::string output = what
-		+ "\nFilter: " + query.getFilter().toString()
-		+ "\nModifiers: " + query.getModifiers().toString()
-		+ "\nSort: " + query.getSort().toString()
-		+ "\nHint: " + query.getHint().toString()
-		+ "\nReadPref: " + query.getReadPref().toString();
-		
-	logger->log_info(name(), "%s", output.c_str());
-}
-
-void
-RobotMemoryThread::log(BSONObj obj, std::string what)
-{
-	std::string output = what
-		+ "\nObject: " + obj.toString();
-		
-	logger->log_info(name(), "%s", output.c_str());
-}
-
-void
-RobotMemoryThread::set_fields(BSONObj &obj, std::string what)
-{
-	BSONObjBuilder b;
-	b.appendElements(obj);
-	b.appendElements(fromjson(what));
-	//override
-	obj = b.obj();
-}
-
-void
-RobotMemoryThread::set_fields(Query &q, std::string what)
-{
-	BSONObjBuilder b;
-	b.appendElements(q.getFilter());
-	b.appendElements(fromjson(what));
-
-	//TODO keep other stuff in query
-	// + "\nFilter: " + query.getFilter().toString()
-	// + "\nModifiers: " + query.getModifiers().toString()
-	// + "\nSort: " + query.getSort().toString()
-	// + "\nHint: " + query.getHint().toString()
-	// + "\nReadPref: " + query.getReadPref().toString();
-     
-	//override
-	q = Query(b.obj());
-}
-
-void
-RobotMemoryThread::remove_field(Query &q, std::string what)
-{
-	BSONObjBuilder b;
-	b.appendElements(q.getFilter().removeField(what));
-	
-	//TODO keep other stuff in query
-	// + "\nFilter: " + query.getFilter().toString()
-	// + "\nModifiers: " + query.getModifiers().toString()
-	// + "\nSort: " + query.getSort().toString()
-	// + "\nHint: " + query.getHint().toString()
-	// + "\nReadPref: " + query.getReadPref().toString();
-	
-	//override
-	q = Query(b.obj());
-}
-
-void
-RobotMemoryThread::gen_blackboard_data(std::string field)
-{
-	logger->log_info(name(), "Generating virtual kb for bb");
-
-	std::string collection = config->get_string("plugins/robot-memory/blackboard-collection");
-	
-	//remove old data first
-	mongodb_client->remove(collection, Query{"{}"});
-	
-	BSONObjBuilder b;
-	b.append("type", "bbinterface");
-	__rm_if->read();
-	b.append("bbinterface", __rm_if->uid());
-	b.append("error", __rm_if->error());
-	b.append("result", __rm_if->result());
-	
-	mongodb_client->insert(collection, b.obj());  
-}
-
diff --git a/src/plugins/robot-memory/robot_memory_thread.h b/src/plugins/robot-memory/robot_memory_thread.h
index 8a5013c..b23ed42 100644
--- a/src/plugins/robot-memory/robot_memory_thread.h
+++ b/src/plugins/robot-memory/robot_memory_thread.h
@@ -31,6 +31,9 @@
 #include <aspect/blackboard.h>
 #include <aspect/blocked_timing.h>
 #include <mongo/client/dbclient.h>
+#include <aspect/aspect_provider.h>
+#include "robot_memory.h"
+#include "aspect/robot_memory_inifin.h"
 
 #include <string>
 
@@ -46,7 +49,8 @@ class RobotMemoryThread
   public fawkes::ClockAspect,
   public fawkes::MongoDBAspect,
 	public fawkes::BlockedTimingAspect,
-  public fawkes::BlackBoardAspect
+  public fawkes::BlackBoardAspect,
+  public fawkes::AspectProviderAspect
 {
  public:
   RobotMemoryThread();
@@ -60,28 +64,8 @@ class RobotMemoryThread
  protected: virtual void run() { Thread::run(); }
 
  private:
-  std::string    __collection;
-  fawkes::Mutex *__mutex;
-  fawkes::RobotMemoryInterface *__rm_if;
-
-  void exec_query(std::string query, std::string collection);
-  void exec_query(std::string query);
-  void exec_insert(std::string insert, std::string collection);
-  void exec_insert(std::string insert);
-  void exec_update(std::string query, std::string update, std::string collection);
-  void exec_update(std::string query, std::string update);
-  void exec_remove(std::string query, std::string collection);
-  void exec_remove(std::string query);
-
-  void log(mongo::Query query, std::string what);
-  void log(mongo::BSONObj obj, std::string what);
-
-  void set_fields(mongo::BSONObj &obj, std::string what);
-  void set_fields(mongo::Query &q, std::string what);
-  void remove_field(mongo::Query &q, std::string what);
-
-  //funtions to generate virtual knowledge
-  void gen_blackboard_data(std::string field);
+   RobotMemory* robot_memory;
+   fawkes::RobotMemoryIniFin robot_memory_inifin_;
 };
 
 #endif

- *commit* 16bcecd4422de9d7b18dd4ded96a6ba21cccecb2 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Aug 24 11:36:35 2016 +0200
Subject: robot-memory: clearer api functions

 src/plugins/robot-memory/robot_memory.cpp        |   56 +++++++++++-----------
 src/plugins/robot-memory/robot_memory.h          |   14 ++----
 src/plugins/robot-memory/robot_memory_thread.cpp |    8 ++--
 3 files changed, 37 insertions(+), 41 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index cd0d647..d460f5a 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -52,9 +52,9 @@ void RobotMemory::init()
 {
   //load config values
   logger_->log_info(name_, "Started RobotMemory");
-  collection_ = "fawkes.msglog";
+  default_collection_ = "fawkes.msglog";
   try {
-    collection_ = config_->get_string("/plugins/mongodb/test-collection");
+    default_collection_ = config_->get_string("/plugins/mongodb/test-collection");
   } catch (Exception &e) {}
 
   //init blackboard interface
@@ -64,13 +64,13 @@ void RobotMemory::init()
   rm_if_->write();
 }
 
-void RobotMemory::exec_query(std::string query_string)
+void RobotMemory::query(std::string query_string, std::string collection)
 {
-  exec_query(query_string, collection_);
-}
-void RobotMemory::exec_query(std::string query_string, std::string collection)
-{
-  logger_->log_info(name_, "Executing Query: %s", query_string.c_str());
+  if(collection == "")
+  {
+    collection = default_collection_;
+  }
+  logger_->log_info(name_, "Executing Query %s on collection %s", query_string.c_str(), collection);
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -122,13 +122,13 @@ void RobotMemory::exec_query(std::string query_string, std::string collection)
   }
 }
 
-void RobotMemory::exec_insert(std::string insert_string)
+void RobotMemory::insert(std::string insert_string, std::string collection)
 {
-  exec_insert(insert_string, collection_);
-}
-void RobotMemory::exec_insert(std::string insert_string, std::string collection)
-{
-  logger_->log_info(name_, "Executing Query: %s", insert_string.c_str());
+  if(collection == "")
+  {
+    collection = default_collection_;
+  }
+  logger_->log_info(name_, "Executing Query %s on collection %s", insert_string.c_str(), collection);
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -157,15 +157,15 @@ void RobotMemory::exec_insert(std::string insert_string, std::string collection)
   }
 }
 
-void RobotMemory::exec_update(std::string query_string, std::string update_string)
-{
-  exec_update(query_string, update_string, collection_);
-}
-void RobotMemory::exec_update(std::string query_string, std::string update_string,
+void RobotMemory::update(std::string query_string, std::string update_string,
                                     std::string collection)
 {
-  logger_->log_info(name_, "Executing Update %s for query %s",
-                   update_string.c_str(), query_string.c_str());
+  if(collection == "")
+  {
+    collection = default_collection_;
+  }
+  logger_->log_info(name_, "Executing Update %s for query %s on collection %s",
+                   update_string.c_str(), query_string.c_str(), collection);
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -201,14 +201,14 @@ void RobotMemory::exec_update(std::string query_string, std::string update_strin
   }
 }
 
-void RobotMemory::exec_remove(std::string query_string)
-{
-  exec_remove(query_string, collection_);
-}
-
-void RobotMemory::exec_remove(std::string query_string, std::string collection)
+void RobotMemory::remove(std::string query_string, std::string collection)
 {
-  logger_->log_info(name_, "Executing Remove: %s", query_string.c_str());
+  if(collection == "")
+  {
+    collection = default_collection_;
+  }
+  logger_->log_info(name_, "Executing Remove %s on collection %s",
+                    query_string.c_str(), collection);
 
   //only one query at a time
   MutexLocker lock(mutex_);
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 7eb00ee..8584de1 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -48,14 +48,10 @@ class RobotMemory
     virtual ~RobotMemory();
 
     //robot memory functions
-    void exec_query(std::string query, std::string collection);
-    void exec_query(std::string query);
-    void exec_insert(std::string insert, std::string collection);
-    void exec_insert(std::string insert);
-    void exec_update(std::string query, std::string update, std::string collection);
-    void exec_update(std::string query, std::string update);
-    void exec_remove(std::string query, std::string collection);
-    void exec_remove(std::string query);
+    void query(std::string query, std::string collection = "");
+    void insert(std::string insert, std::string collection = "");
+    void update(std::string query, std::string update, std::string collection = "");
+    void remove(std::string query, std::string collection = "");
 
   private:
     mongo::DBClientBase* mongodb_client_;
@@ -65,7 +61,7 @@ class RobotMemory
     fawkes::BlackBoard* blackboard_;
 
     const char* name_ = "RobotMemory";
-    std::string collection_;
+    std::string default_collection_;
     fawkes::Mutex *mutex_;
     fawkes::RobotMemoryInterface* rm_if_;
 
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 8bf74ec..5ba2c0c 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -74,16 +74,16 @@ RobotMemoryThread::loop()
   while (! robot_memory->rm_if_->msgq_empty() ) {
     if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::QueryMessage>()) {
 	    RobotMemoryInterface::QueryMessage* msg = (RobotMemoryInterface::QueryMessage*) robot_memory->rm_if_->msgq_first();
-	    robot_memory->exec_query(msg->query());
+	    robot_memory->query(msg->query());
     } else if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::InsertMessage>()) {
 	    RobotMemoryInterface::InsertMessage* msg = (RobotMemoryInterface::InsertMessage*) robot_memory->rm_if_->msgq_first();
-	    robot_memory->exec_insert(msg->insert());
+	    robot_memory->insert(msg->insert());
     } else if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::UpdateMessage>()) {
 	    RobotMemoryInterface::UpdateMessage* msg = (RobotMemoryInterface::UpdateMessage*) robot_memory->rm_if_->msgq_first();
-	    robot_memory->exec_update(msg->query(), msg->update());
+	    robot_memory->update(msg->query(), msg->update());
     } else if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::RemoveMessage>()) {
 	    RobotMemoryInterface::RemoveMessage* msg = (RobotMemoryInterface::RemoveMessage*) robot_memory->rm_if_->msgq_first();
-	    robot_memory->exec_remove(msg->query());
+	    robot_memory->remove(msg->query());
     } else {
       logger->log_warn(name(), "Unknown message received");
     }

- *commit* 9ff67ed4211180fac4acca32ef8075ef89e24eb1 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Aug 24 14:03:51 2016 +0200
Subject: gtest: tool for unit testing in a running fawkes environment

 .../robot-memory/tests => tools/gtest}/Makefile    |   21 ++++---
 src/tools/gtest/gtest_fawkes.cpp                   |   70 ++++++++++++++++++++
 2 files changed, 82 insertions(+), 9 deletions(-)


- *commit* d76752247ccedde69803f4f4e0fabf873706e343 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Aug 24 14:59:22 2016 +0200
Subject: robot-memory: created gtest plugin to run tests in fawkes

 .../aspect => robot-memory/test-plugin}/Makefile   |   21 +++---
 .../robot_memory_test_plugin.cpp}                  |   38 +++++------
 .../test-plugin/robot_memory_test_thread.cpp       |   67 ++++++++++++++++++++
 .../test-plugin/robot_memory_test_thread.h}        |   33 ++++++----
 src/plugins/robot-memory/tests/Makefile            |   45 -------------
 .../robot-memory/tests/robot_memory_test.cpp       |   34 ----------
 6 files changed, 116 insertions(+), 122 deletions(-)


- *commit* aa2664284f4c42c1fae3b46b742985fa73e72617 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Aug 24 17:40:48 2016 +0200
Subject: robot-memory-test: provide environment with access to the RobotMemory

 src/plugins/robot-memory/test-plugin/Makefile      |   24 +++++++--
 .../test-plugin/robot_memory_test.cpp}             |   40 +++++++++-----
 .../robot-memory/test-plugin/robot_memory_test.h   |   56 ++++++++++++++++++++
 .../test-plugin/robot_memory_test_thread.cpp       |   10 ++--
 .../test-plugin/robot_memory_test_thread.h         |   10 ++--
 5 files changed, 112 insertions(+), 28 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/test-plugin/Makefile b/src/plugins/robot-memory/test-plugin/Makefile
index 377737c..546954c 100644
--- a/src/plugins/robot-memory/test-plugin/Makefile
+++ b/src/plugins/robot-memory/test-plugin/Makefile
@@ -19,12 +19,28 @@ include $(BASEDIR)/etc/buildsys/config.mk
 include $(BASEDIR)/etc/buildsys/gtest.mk
 
 LIBS_robot_memory_test = m fawkescore fawkesutils fawkesaspects fawkesbaseapp \
-                      fawkesblackboard fawkesinterface
+                      fawkesblackboard fawkesinterface fawkesrobotmemory
 
-OBJS_robot_memory_test = robot_memory_test_plugin.o robot_memory_test_thread.o
-
-PLUGINS_all = $(PLUGINDIR)/robot_memory_test.$(SOEXT)
+OBJS_robot_memory_test = robot_memory_test_plugin.o robot_memory_test_thread.o robot_memory_test.o
 
 OBJS_all = $(OBJS_robot_memory_test)
 
+ifeq ($(HAVE_GTEST)$(HAVE_CPP11),11)
+  CFLAGS += $(CFLAGS_GTEST)
+  CFLAGS += $(CFLAGS_CPP11)
+  LDFLAGS += $(LDFLAGS_GTEST)
+  PLUGINS_all = $(PLUGINDIR)/robot_memory_test.$(SOEXT)
+else
+  WARN_TARGETS += warning_gtest
+endif
+
+ifeq ($(OBJSSUBMAKE),1)
+test: $(WARN_TARGETS)
+
+.PHONY: warning_gtest
+warning_gtest:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting unit tests for Robot Memory$(TNORMAL) (gtest or cpp11 not available)"
+
+endif
+
 include $(BUILDSYSDIR)/base.mk
\ No newline at end of file
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
index 5a31270..2a3d7c3 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
@@ -39,14 +39,14 @@ RobotMemoryTestThread::RobotMemoryTestThread()
 {
 }
 
-TEST(GTestTest, TestsWorking)
-{
-  ASSERT_EQ(1, 3-2);
-}
-
 void
 RobotMemoryTestThread::init()
 {
+  //prepare tests
+  logger->log_warn(name(), "Preparing tests");
+  test_env_ = new RobotMemoryTestEnvironment(robot_memory);
+  ::testing::AddGlobalTestEnvironment((testing::Environment*) test_env_);
+
   logger->log_warn(name(), "Starting tests");
   test_result_ = RUN_ALL_TESTS();
 }
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.h b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.h
index d574bff..769d47f 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.h
@@ -29,19 +29,19 @@
 #include <aspect/logging.h>
 #include <aspect/blackboard.h>
 #include <aspect/configurable.h>
-
 #include <string>
 
+#include "plugins/robot-memory/aspect/robot_memory_aspect.h"
+#include "robot_memory_test.h"
 
-namespace fawkes {
-}
 
 class RobotMemoryTestThread 
 : public fawkes::Thread,
   public fawkes::BlockedTimingAspect,
   public fawkes::LoggingAspect,
   public fawkes::ConfigurableAspect,
-  public fawkes::BlackBoardAspect
+  public fawkes::BlackBoardAspect,
+  public fawkes::RobotMemoryAspect
 {
 
  public:
@@ -57,6 +57,8 @@ class RobotMemoryTestThread
  private:
   int test_result_;
 
+  //environment to make objects available for testing
+  RobotMemoryTestEnvironment* test_env_;
 };
 
 

- *commit* 5fea1376c1ed9550d6d55aa68a6fd695682f63d9 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Aug 25 02:16:47 2016 +0200
Subject: robot-memory: appropriate return values for query,insert,update,remove

 src/plugins/robot-memory/robot_memory.cpp |   66 ++++++++++++++---------------
 src/plugins/robot-memory/robot_memory.h   |   12 ++++--
 2 files changed, 40 insertions(+), 38 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index d460f5a..d6bd428 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -54,7 +54,7 @@ void RobotMemory::init()
   logger_->log_info(name_, "Started RobotMemory");
   default_collection_ = "fawkes.msglog";
   try {
-    default_collection_ = config_->get_string("/plugins/mongodb/test-collection");
+    default_collection_ = config_->get_string("/plugins/robot-memory/default-collection");
   } catch (Exception &e) {}
 
   //init blackboard interface
@@ -64,7 +64,7 @@ void RobotMemory::init()
   rm_if_->write();
 }
 
-void RobotMemory::query(std::string query_string, std::string collection)
+QResCursor RobotMemory::query(std::string query_string, std::string collection)
 {
   if(collection == "")
   {
@@ -82,47 +82,39 @@ void RobotMemory::query(std::string query_string, std::string collection)
   } catch (DBException &e) {
     logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
                       query_string.c_str(), e.toString().c_str());
-    return;
+    return NULL;
   }
 
-  //introspect query
-  log(query, "executing query:");
+//  //introspect query
+//  log(query, "executing query:");
 
-  //check if virtual knowledge is queried
-  //rename field in query
-  if(query.getFilter().hasField("class")){
-    set_fields(query, std::string("{type:\"") +
-               query.getFilter()["class"].String() + "\"}");
-    remove_field(query, "class");
-  }
-  log(query, "Virtual query:");
 //  //TODO: computation on demand
+//  //check if virtual knowledge is queried
+//  //rename field in query
+//  if(query.getFilter().hasField("class")){
+//    set_fields(query, std::string("{type:\"") +
+//               query.getFilter()["class"].String() + "\"}");
+//    remove_field(query, "class");
+//  }
+//
 //  if(query.getFilter().hasField("bbinterface")){
 //    collection = config->get_string("plugins/robot-memory/blackboard-collection");
 //    gen_blackboard_data(query.getFilter()["bbinterface"].String());
 //  }
-  log(query, "Virtual query:");
 
   //actually execute query
-  std::unique_ptr<DBClientCursor> cursor;
+  QResCursor cursor;
   try{
     cursor = mongodb_client_->query(collection, query);
   } catch (DBException &e) {
     logger_->log_error(name_, "Error for query %s\n Exception: %s",
                       query_string.c_str(), e.toString().c_str());
-    return;
-  }
-
-  if(cursor->more()){
-    BSONObj res = cursor->next();
-    logger_->log_info(name_, "Query One result:\n%s", res.toString().c_str());
-  }
-  else {
-    logger_->log_info(name_, "Query result empty");
+    return NULL;
   }
+  return cursor;
 }
 
-void RobotMemory::insert(std::string insert_string, std::string collection)
+int RobotMemory::insert(std::string insert_string, std::string collection)
 {
   if(collection == "")
   {
@@ -140,7 +132,7 @@ void RobotMemory::insert(std::string insert_string, std::string collection)
   } catch (DBException &e) {
     logger_->log_error(name_, "Can't parse insert_string '%s'\n Exception: %s",
                       insert_string.c_str(), e.toString().c_str());
-    return;
+    return 0;
   }
 
   log(obj, "Inserting:");
@@ -153,11 +145,13 @@ void RobotMemory::insert(std::string insert_string, std::string collection)
   } catch (DBException &e) {
     logger_->log_error(name_, "Error for insert %s\n Exception: %s",
                       insert_string.c_str(), e.toString().c_str());
-    return;
+    return 0;
   }
+  //return success
+  return 1;
 }
 
-void RobotMemory::update(std::string query_string, std::string update_string,
+int RobotMemory::update(std::string query_string, std::string update_string,
                                     std::string collection)
 {
   if(collection == "")
@@ -177,7 +171,7 @@ void RobotMemory::update(std::string query_string, std::string update_string,
   } catch (DBException &e) {
     logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
                       query_string.c_str(), e.toString().c_str());
-    return;
+    return 0;
   }
   BSONObj update;
   try{
@@ -185,7 +179,7 @@ void RobotMemory::update(std::string query_string, std::string update_string,
   } catch (DBException &e) {
     logger_->log_error(name_, "Can't parse update_string '%s'\n Exception: %s",
                       update_string.c_str(), e.toString().c_str());
-    return;
+    return 0;
   }
 
   log(query, "Updating documents for query:");
@@ -197,11 +191,13 @@ void RobotMemory::update(std::string query_string, std::string update_string,
   } catch (DBException &e) {
     logger_->log_error(name_, "Error for update %s for query %s\n Exception: %s",
                       update_string.c_str(), query_string.c_str(), e.toString().c_str());
-    return;
+    return 0;
   }
+  //return success
+  return 1;
 }
 
-void RobotMemory::remove(std::string query_string, std::string collection)
+int RobotMemory::remove(std::string query_string, std::string collection)
 {
   if(collection == "")
   {
@@ -220,7 +216,7 @@ void RobotMemory::remove(std::string query_string, std::string collection)
   } catch (DBException &e) {
     logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
                       query_string.c_str(), e.toString().c_str());
-    return;
+    return 0;
   }
 
   //introspect
@@ -232,8 +228,10 @@ void RobotMemory::remove(std::string query_string, std::string collection)
   } catch (DBException &e) {
     logger_->log_error(name_, "Error for query %s\n Exception: %s",
                       query_string.c_str(), e.toString().c_str());
-    return;
+    return 0;
   }
+  //return success
+  return 1;
 }
 
 void
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 8584de1..c216df7 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -25,6 +25,7 @@
 #include <aspect/configurable.h>
 #include <aspect/logging.h>
 #include <aspect/blackboard.h>
+#include <memory>
 
 #include <mongo/client/dbclient.h>
 #include "interfaces/RobotMemoryInterface.h"
@@ -34,6 +35,9 @@ namespace fawkes {
   class RobotMemoryInterface;
 }
 
+///typedef for shorter type description
+typedef std::unique_ptr<mongo::DBClientCursor> QResCursor;
+
 /*
  *
  */
@@ -48,10 +52,10 @@ class RobotMemory
     virtual ~RobotMemory();
 
     //robot memory functions
-    void query(std::string query, std::string collection = "");
-    void insert(std::string insert, std::string collection = "");
-    void update(std::string query, std::string update, std::string collection = "");
-    void remove(std::string query, std::string collection = "");
+    QResCursor query(std::string query, std::string collection = "");
+    int insert(std::string insert, std::string collection = "");
+    int update(std::string query, std::string update, std::string collection = "");
+    int remove(std::string query, std::string collection = "");
 
   private:
     mongo::DBClientBase* mongodb_client_;

- *commit* b1c8159e2ce98f11e5a72c63706d70f6cdc0ef88 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Aug 25 02:19:47 2016 +0200
Subject: robot-memory-tests: added tests for query,insert,update,remove

 src/plugins/robot-memory/Makefile                  |    1 +
 .../robot-memory/test-plugin/robot_memory_test.cpp |   99 +++++++++++++++++++-
 .../robot-memory/test-plugin/robot_memory_test.h   |    3 +
 3 files changed, 102 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/Makefile b/src/plugins/robot-memory/Makefile
index 6deb5cb..84453a7 100644
--- a/src/plugins/robot-memory/Makefile
+++ b/src/plugins/robot-memory/Makefile
@@ -20,6 +20,7 @@ include $(BUILDCONFDIR)/tf/tf.mk
 include $(BASEDIR)/src/plugins/mongodb/mongodb.mk
 
 PRESUBDIRS = interfaces aspect
+SUBDIRS = test-plugin
 
 LIBS_robot_memory = fawkescore fawkesaspects fawkesblackboard fawkesinterface \
 		fawkesutils fawkeslogging fawkesmongodbaspect fvutils \
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index 06888ea..e326900 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -24,7 +24,8 @@
 //init static variable
 RobotMemory* RobotMemoryTestEnvironment::robot_memory = NULL;
 
-
+using namespace fawkes;
+using namespace mongo;
 
 /**
  * Setup for each test
@@ -44,6 +45,102 @@ TEST_F(RobotMemoryTest, AspectAvailable)
   ASSERT_FALSE(robot_memory==NULL);
 }
 
+TEST_F(RobotMemoryTest, QueryResultEmpty)
+{
+  QResCursor qres = robot_memory->query("{somekey:'should_not_exist'}");
+  ASSERT_FALSE(qres->more());
+}
+
+TEST_F(RobotMemoryTest, StoreAndQuery)
+{
+  ASSERT_TRUE(robot_memory->insert("{'testkey':'value'}"));
+  QResCursor qres = robot_memory->query("{'testkey':'value'}");
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value'}")));
+}
 
+TEST_F(RobotMemoryTest, StoreAndQueryOtherCollection)
+{
+  ASSERT_TRUE(robot_memory->insert("{'testkey':'value'}", "robmem.othercollection"));
+  QResCursor qres = robot_memory->query("{'testkey':'value'}", "robmem.othercollection");
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value'}")));
+}
 
+TEST_F(RobotMemoryTest, StoreUpdateQuery)
+{
+  ASSERT_TRUE(robot_memory->insert("{'inserting':'something',as:0.5}"));
+  ASSERT_TRUE(robot_memory->update("{'inserting':'something',as:0.5}",
+      "{'updated':'something',as:3.0,extra:true}"));
+  QResCursor qres = robot_memory->query("{'updated':'something'}");
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson(
+      "{'updated':'something',as:3.0,extra:true}")));
+}
+
+TEST_F(RobotMemoryTest, StoreRemoveQuery)
+{
+  ASSERT_TRUE(robot_memory->insert("{to_be:'removed'}"));
+  ASSERT_TRUE(robot_memory->remove("{to_be:'removed'}"));
+  QResCursor qres = robot_memory->query("{to_be:'removed'}");
+  ASSERT_FALSE(qres->more());
+}
+
+TEST_F(RobotMemoryTest, QueryInvalidCaught)
+{
+  ASSERT_EQ(robot_memory->query("{key:'not existing'}"), NULL);
+}
+
+TEST_F(RobotMemoryTest, InsertInvalidCaught)
+{
+  ASSERT_NO_THROW(robot_memory->insert("{'testkey'::'value'}"));
+  ASSERT_FALSE(robot_memory->insert("warbagarbl"));
+}
 
+TEST_F(RobotMemoryTest, UpdateInvalidCaught)
+{
+  ASSERT_NO_THROW(robot_memory->update("{'testkey'::'value'}",
+      "{'key':'update'}"));
+  ASSERT_NO_THROW(robot_memory->update("{'testkey':'good'}",
+      "{'bad':1.2.3}"));
+  ASSERT_FALSE(robot_memory->update("{([})]", "{'key':4}"));
+  ASSERT_FALSE(robot_memory->update("{'key':'valid'}", "invalid!"));
+}
+
+TEST_F(RobotMemoryTest, RemoveInvalidCaught)
+{
+  ASSERT_NO_THROW(robot_memory->remove("{____:4.56}"));
+  ASSERT_FALSE(robot_memory->remove("{([})]"));
+}
+
+TEST_F(RobotMemoryTest, AggregationQuery)
+{
+  //TODO: implement
+}
+
+TEST_F(RobotMemoryTest, MapReduceQuery)
+{
+  //TODO: implement
+}
+
+TEST_F(RobotMemoryTest, JavaScriptQuery)
+{
+  //TODO: implement
+}
+
+
+::testing::AssertionResult RobotMemoryTest::contains_pairs(BSONObj obj, BSONObj exp)
+{
+  for(BSONObjIterator it = exp.begin(); it.more();)
+  {
+    BSONElement kvpair = it.next();
+    printf("checking %s\n", kvpair.toString().c_str());
+    if(!obj.hasElement(kvpair.fieldName())
+        || obj.getField(kvpair.fieldName()) != kvpair)
+    {
+      return ::testing::AssertionFailure() << obj.toString()
+          << " does not include {" << kvpair.toString() << "}";
+    }
+  }
+  return ::testing::AssertionSuccess();
+}
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.h b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
index 3b0a902..d28dcca 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
@@ -50,6 +50,9 @@ class RobotMemoryTest : public ::testing::Test
  protected:
   virtual void SetUp();
   RobotMemory* robot_memory;
+
+ protected:
+  ::testing::AssertionResult contains_pairs(mongo::BSONObj obj, mongo::BSONObj exp);
 };
 
 

- *commit* baaf892b850c27b9227332829fd9f168dd89cd87 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Aug 25 21:57:23 2016 +0200
Subject: robot-memory: configurable debug output

 cfg/conf.d/robot-memory.yaml                       |    3 +-
 src/plugins/robot-memory/robot_memory.cpp          |  104 ++++++++++++++------
 src/plugins/robot-memory/robot_memory.h            |    1 +
 .../robot-memory/test-plugin/robot_memory_test.cpp |    3 +-
 .../robot-memory/test-plugin/robot_memory_test.h   |    2 +-
 5 files changed, 78 insertions(+), 35 deletions(-)

_Diff for modified files_:
diff --git a/cfg/conf.d/robot-memory.yaml b/cfg/conf.d/robot-memory.yaml
index 03e1f8e..51c959b 100644
--- a/cfg/conf.d/robot-memory.yaml
+++ b/cfg/conf.d/robot-memory.yaml
@@ -6,7 +6,8 @@ doc-url: !url http://trac.fawkesrobotics.org/wiki/Plugins/robot-memory
 plugins/robot-memory:
 
   database: fawkes
-  test-collection: "robmem.test"
+  default-collection: "robmem.test"
   interface-name: "memory"
+  more-debug-output: true
 
   blackboard-collection: "robmem.bb"
\ No newline at end of file
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index d6bd428..e3024c9 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -40,6 +40,7 @@ RobotMemory::RobotMemory(fawkes::Configuration* config, fawkes::Logger* logger,
   clock_ = clock;
   mongodb_client_ = mongodb_client;
   blackboard_ = blackboard;
+  debug_ = false;
 }
 
 RobotMemory::~RobotMemory()
@@ -56,12 +57,20 @@ void RobotMemory::init()
   try {
     default_collection_ = config_->get_string("/plugins/robot-memory/default-collection");
   } catch (Exception &e) {}
+  try {
+    debug_ = config_->get_bool("/plugins/robot-memory/more-debug-output");
+  } catch (Exception &e) {}
 
   //init blackboard interface
   rm_if_ = blackboard_->open_for_writing<RobotMemoryInterface>(config_->get_string("/plugins/robot-memory/interface-name").c_str());
   rm_if_->set_error("");
   rm_if_->set_result("");
   rm_if_->write();
+
+  if(debug_)
+  {
+    logger_->log_info(name_, "Initialized RobotMemory");
+  }
 }
 
 QResCursor RobotMemory::query(std::string query_string, std::string collection)
@@ -70,7 +79,10 @@ QResCursor RobotMemory::query(std::string query_string, std::string collection)
   {
     collection = default_collection_;
   }
-  logger_->log_info(name_, "Executing Query %s on collection %s", query_string.c_str(), collection);
+  if(debug_)
+  {
+    logger_->log_info(name_, "Executing Query %s on collection %s", query_string.c_str(), collection);
+  }
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -80,8 +92,11 @@ QResCursor RobotMemory::query(std::string query_string, std::string collection)
   try{
     query = Query(query_string);
   } catch (DBException &e) {
-    logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
-                      query_string.c_str(), e.toString().c_str());
+    if(debug_)
+    {
+      logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
+          query_string.c_str(), e.toString().c_str());
+    }
     return NULL;
   }
 
@@ -107,8 +122,11 @@ QResCursor RobotMemory::query(std::string query_string, std::string collection)
   try{
     cursor = mongodb_client_->query(collection, query);
   } catch (DBException &e) {
-    logger_->log_error(name_, "Error for query %s\n Exception: %s",
-                      query_string.c_str(), e.toString().c_str());
+    if(debug_)
+    {
+      logger_->log_error(name_, "Error for query %s\n Exception: %s",
+          query_string.c_str(), e.toString().c_str());
+    }
     return NULL;
   }
   return cursor;
@@ -120,7 +138,10 @@ int RobotMemory::insert(std::string insert_string, std::string collection)
   {
     collection = default_collection_;
   }
-  logger_->log_info(name_, "Executing Query %s on collection %s", insert_string.c_str(), collection);
+  if(debug_)
+  {
+    logger_->log_info(name_, "Executing Query %s on collection %s", insert_string.c_str(), collection);
+  }
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -130,21 +151,25 @@ int RobotMemory::insert(std::string insert_string, std::string collection)
   try{
     obj = fromjson(insert_string);
   } catch (DBException &e) {
-    logger_->log_error(name_, "Can't parse insert_string '%s'\n Exception: %s",
-                      insert_string.c_str(), e.toString().c_str());
+    if(debug_)
+    {
+      logger_->log_error(name_, "Can't parse insert_string '%s'\n Exception: %s",
+          insert_string.c_str(), e.toString().c_str());
+    }
     return 0;
   }
 
-  log(obj, "Inserting:");
   set_fields(obj, "{type: \"test\"}");
-  log(obj, "Updated Inserting:");
 
   //actually execute insert
   try{
     mongodb_client_->insert(collection, obj);
   } catch (DBException &e) {
-    logger_->log_error(name_, "Error for insert %s\n Exception: %s",
-                      insert_string.c_str(), e.toString().c_str());
+    if(debug_)
+    {
+      logger_->log_error(name_, "Error for insert %s\n Exception: %s",
+          insert_string.c_str(), e.toString().c_str());
+    }
     return 0;
   }
   //return success
@@ -158,8 +183,11 @@ int RobotMemory::update(std::string query_string, std::string update_string,
   {
     collection = default_collection_;
   }
-  logger_->log_info(name_, "Executing Update %s for query %s on collection %s",
-                   update_string.c_str(), query_string.c_str(), collection);
+  if(debug_)
+  {
+    logger_->log_info(name_, "Executing Update %s for query %s on collection %s",
+        update_string.c_str(), query_string.c_str(), collection);
+  }
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -169,28 +197,34 @@ int RobotMemory::update(std::string query_string, std::string update_string,
   try{
     query = Query(query_string);
   } catch (DBException &e) {
-    logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
-                      query_string.c_str(), e.toString().c_str());
+    if(debug_)
+    {
+      logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
+          query_string.c_str(), e.toString().c_str());
+    }
     return 0;
   }
   BSONObj update;
   try{
     update = fromjson(update_string);
   } catch (DBException &e) {
-    logger_->log_error(name_, "Can't parse update_string '%s'\n Exception: %s",
-                      update_string.c_str(), e.toString().c_str());
+    if(debug_)
+    {
+      logger_->log_error(name_, "Can't parse update_string '%s'\n Exception: %s",
+          update_string.c_str(), e.toString().c_str());
+    }
     return 0;
   }
 
-  log(query, "Updating documents for query:");
-  log(update, "Updating with:");
-
   //actually execute update
   try{
     mongodb_client_->update(collection, query, update);
   } catch (DBException &e) {
-    logger_->log_error(name_, "Error for update %s for query %s\n Exception: %s",
-                      update_string.c_str(), query_string.c_str(), e.toString().c_str());
+    if(debug_)
+    {
+      logger_->log_error(name_, "Error for update %s for query %s\n Exception: %s",
+          update_string.c_str(), query_string.c_str(), e.toString().c_str());
+    }
     return 0;
   }
   //return success
@@ -203,8 +237,11 @@ int RobotMemory::remove(std::string query_string, std::string collection)
   {
     collection = default_collection_;
   }
-  logger_->log_info(name_, "Executing Remove %s on collection %s",
-                    query_string.c_str(), collection);
+  if(debug_)
+  {
+    logger_->log_info(name_, "Executing Remove %s on collection %s",
+        query_string.c_str(), collection);
+  }
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -214,20 +251,23 @@ int RobotMemory::remove(std::string query_string, std::string collection)
   try{
     query = Query(query_string);
   } catch (DBException &e) {
-    logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
-                      query_string.c_str(), e.toString().c_str());
+    if(debug_)
+    {
+      logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
+          query_string.c_str(), e.toString().c_str());
+    }
     return 0;
   }
 
-  //introspect
-  log(query, "Removing documents for query:");
-
   //actually execute remove
   try{
     mongodb_client_->remove(collection, query);
   } catch (DBException &e) {
-    logger_->log_error(name_, "Error for query %s\n Exception: %s",
-                      query_string.c_str(), e.toString().c_str());
+    if(debug_)
+    {
+      logger_->log_error(name_, "Error for query %s\n Exception: %s",
+          query_string.c_str(), e.toString().c_str());
+    }
     return 0;
   }
   //return success
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index c216df7..7a095f4 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -66,6 +66,7 @@ class RobotMemory
 
     const char* name_ = "RobotMemory";
     std::string default_collection_;
+    bool debug_;
     fawkes::Mutex *mutex_;
     fawkes::RobotMemoryInterface* rm_if_;
 
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index e326900..6f8f68e 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -47,6 +47,7 @@ TEST_F(RobotMemoryTest, AspectAvailable)
 
 TEST_F(RobotMemoryTest, QueryResultEmpty)
 {
+  ASSERT_TRUE(robot_memory->insert("{'insert':'something to have the namespace'}"));
   QResCursor qres = robot_memory->query("{somekey:'should_not_exist'}");
   ASSERT_FALSE(qres->more());
 }
@@ -88,7 +89,7 @@ TEST_F(RobotMemoryTest, StoreRemoveQuery)
 
 TEST_F(RobotMemoryTest, QueryInvalidCaught)
 {
-  ASSERT_EQ(robot_memory->query("{key:'not existing'}"), NULL);
+  ASSERT_FALSE(robot_memory->query("{key-:+'not existing'}"));
 }
 
 TEST_F(RobotMemoryTest, InsertInvalidCaught)
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.h b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
index d28dcca..a9cdb07 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
@@ -38,7 +38,7 @@ class RobotMemoryTestEnvironment : public ::testing::Environment
   }
   virtual ~RobotMemoryTestEnvironment() {}
   void SetUp() {}
-  virtual void TearDown() {}
+  virtual void TearDown(){}
  public:
   static RobotMemory* robot_memory;
 };

- *commit* 29d5784df30b6183ad80cbfb791a47c9c46b4612 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Aug 25 21:57:57 2016 +0200
Subject: robot-memory-test: properly quit fawkes when tests finished

 .../test-plugin/robot_memory_test_thread.cpp       |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
index 2a3d7c3..5bedac1 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
@@ -23,7 +23,7 @@
 
 #include "robot_memory_test_thread.h"
 #include <core/exception.h>
-
+#include <baseapp/run.h>
 #include <gtest/gtest.h>
 
 using namespace fawkes;
@@ -54,10 +54,9 @@ RobotMemoryTestThread::init()
 void
 RobotMemoryTestThread::loop()
 {
-  logger->log_warn(name(), "Finished tests with result %d, shutting down...", test_result_);
-
-  //stop fawkes by throwing an exception
-  throw fawkes::Exception("Stopping Fawkes after running tests in %s", name());
+  logger->log_warn(name(), "Finished tests with, quitting as intended...");
+  //stop fawkes to finish the testing run
+  fawkes::runtime::quit();
 }
 
 void

- *commit* 15377b6de9b612f129dbe66070150dbe943122c7 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Aug 26 19:05:37 2016 +0200
Subject: robot-memory: better logging functions

 src/plugins/robot-memory/robot_memory.cpp |  154 +++++++++++++++--------------
 src/plugins/robot-memory/robot_memory.h   |   11 ++-
 2 files changed, 89 insertions(+), 76 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index e3024c9..b4f39ff 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -52,14 +52,18 @@ RobotMemory::~RobotMemory()
 void RobotMemory::init()
 {
   //load config values
-  logger_->log_info(name_, "Started RobotMemory");
-  default_collection_ = "fawkes.msglog";
+  log("Started RobotMemory");
+  default_collection_ = "robmem.test";
   try {
     default_collection_ = config_->get_string("/plugins/robot-memory/default-collection");
   } catch (Exception &e) {}
   try {
     debug_ = config_->get_bool("/plugins/robot-memory/more-debug-output");
   } catch (Exception &e) {}
+  database_name_ = "mobmem";
+  try {
+    database_name_ = config_->get_string("/plugins/robot-memory/database");
+  } catch (Exception &e) {}
 
   //init blackboard interface
   rm_if_ = blackboard_->open_for_writing<RobotMemoryInterface>(config_->get_string("/plugins/robot-memory/interface-name").c_str());
@@ -67,10 +71,7 @@ void RobotMemory::init()
   rm_if_->set_result("");
   rm_if_->write();
 
-  if(debug_)
-  {
-    logger_->log_info(name_, "Initialized RobotMemory");
-  }
+  log_deb("Initialized RobotMemory");
 }
 
 QResCursor RobotMemory::query(std::string query_string, std::string collection)
@@ -79,10 +80,7 @@ QResCursor RobotMemory::query(std::string query_string, std::string collection)
   {
     collection = default_collection_;
   }
-  if(debug_)
-  {
-    logger_->log_info(name_, "Executing Query %s on collection %s", query_string.c_str(), collection);
-  }
+  log_deb(std::string("Executing Query "+ query_string+" on collection "+collection));
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -92,11 +90,9 @@ QResCursor RobotMemory::query(std::string query_string, std::string collection)
   try{
     query = Query(query_string);
   } catch (DBException &e) {
-    if(debug_)
-    {
-      logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
-          query_string.c_str(), e.toString().c_str());
-    }
+    std::string error = "Can't parse query_string "
+        + query_string + "\n Exception: " + e.toString();
+    log_deb(error, "error");
     return NULL;
   }
 
@@ -122,11 +118,9 @@ QResCursor RobotMemory::query(std::string query_string, std::string collection)
   try{
     cursor = mongodb_client_->query(collection, query);
   } catch (DBException &e) {
-    if(debug_)
-    {
-      logger_->log_error(name_, "Error for query %s\n Exception: %s",
-          query_string.c_str(), e.toString().c_str());
-    }
+    std::string error = std::string("Error for query ")
+      + query_string + "\n Exception: " + e.toString();
+    log(error, "error");
     return NULL;
   }
   return cursor;
@@ -138,10 +132,8 @@ int RobotMemory::insert(std::string insert_string, std::string collection)
   {
     collection = default_collection_;
   }
-  if(debug_)
-  {
-    logger_->log_info(name_, "Executing Query %s on collection %s", insert_string.c_str(), collection);
-  }
+
+  log_deb(std::string("Executing Query "+ insert_string + " on collection " + collection));
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -151,11 +143,9 @@ int RobotMemory::insert(std::string insert_string, std::string collection)
   try{
     obj = fromjson(insert_string);
   } catch (DBException &e) {
-    if(debug_)
-    {
-      logger_->log_error(name_, "Can't parse insert_string '%s'\n Exception: %s",
-          insert_string.c_str(), e.toString().c_str());
-    }
+    std::string error = "Can't parse insert_string "
+        + insert_string + "\n Exception: " + e.toString();
+    log_deb(error, "error");
     return 0;
   }
 
@@ -165,11 +155,9 @@ int RobotMemory::insert(std::string insert_string, std::string collection)
   try{
     mongodb_client_->insert(collection, obj);
   } catch (DBException &e) {
-    if(debug_)
-    {
-      logger_->log_error(name_, "Error for insert %s\n Exception: %s",
-          insert_string.c_str(), e.toString().c_str());
-    }
+    std::string error = "Error for insert " + insert_string
+        + "\n Exception: " + e.toString();
+    log_deb(error, "error");
     return 0;
   }
   //return success
@@ -183,11 +171,7 @@ int RobotMemory::update(std::string query_string, std::string update_string,
   {
     collection = default_collection_;
   }
-  if(debug_)
-  {
-    logger_->log_info(name_, "Executing Update %s for query %s on collection %s",
-        update_string.c_str(), query_string.c_str(), collection);
-  }
+  log_deb(std::string("Executing Update "+update_string+" for query "+query_string+" on collection "+ collection));
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -197,22 +181,16 @@ int RobotMemory::update(std::string query_string, std::string update_string,
   try{
     query = Query(query_string);
   } catch (DBException &e) {
-    if(debug_)
-    {
-      logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
-          query_string.c_str(), e.toString().c_str());
-    }
+    std::string error = "Can't parse query_string " + query_string
+        + "\n Exception: " + e.toString();
+    log_deb(error, "error");
     return 0;
   }
   BSONObj update;
   try{
     update = fromjson(update_string);
   } catch (DBException &e) {
-    if(debug_)
-    {
-      logger_->log_error(name_, "Can't parse update_string '%s'\n Exception: %s",
-          update_string.c_str(), e.toString().c_str());
-    }
+    log_deb(std::string("Can't parse update_string '"+update_string+"'\n Exception: "+e.toString()),"error");
     return 0;
   }
 
@@ -220,11 +198,7 @@ int RobotMemory::update(std::string query_string, std::string update_string,
   try{
     mongodb_client_->update(collection, query, update);
   } catch (DBException &e) {
-    if(debug_)
-    {
-      logger_->log_error(name_, "Error for update %s for query %s\n Exception: %s",
-          update_string.c_str(), query_string.c_str(), e.toString().c_str());
-    }
+    log_deb(std::string("Error for update "+update_string+" for query "+query_string+"\n Exception: "+e.toString()), "error");
     return 0;
   }
   //return success
@@ -237,11 +211,7 @@ int RobotMemory::remove(std::string query_string, std::string collection)
   {
     collection = default_collection_;
   }
-  if(debug_)
-  {
-    logger_->log_info(name_, "Executing Remove %s on collection %s",
-        query_string.c_str(), collection);
-  }
+  log_deb(std::string("Executing Remove "+query_string+" on collection "+collection));
 
   //only one query at a time
   MutexLocker lock(mutex_);
@@ -251,11 +221,7 @@ int RobotMemory::remove(std::string query_string, std::string collection)
   try{
     query = Query(query_string);
   } catch (DBException &e) {
-    if(debug_)
-    {
-      logger_->log_error(name_, "Can't parse query_string '%s'\n Exception: %s",
-          query_string.c_str(), e.toString().c_str());
-    }
+    log_deb(std::string("Can't parse query_string '"+query_string+"'\n Exception: "+e.toString()), "error");
     return 0;
   }
 
@@ -263,19 +229,55 @@ int RobotMemory::remove(std::string query_string, std::string collection)
   try{
     mongodb_client_->remove(collection, query);
   } catch (DBException &e) {
-    if(debug_)
-    {
-      logger_->log_error(name_, "Error for query %s\n Exception: %s",
-          query_string.c_str(), e.toString().c_str());
-    }
+    log_deb(std::string("Error for query "+query_string+"\n Exception: "+e.toString()), "error");
     return 0;
   }
   //return success
   return 1;
 }
 
+int RobotMemory::drop_collection(std::string collection)
+{
+  log_deb("Clearing whole robot memory");
+  return remove("{}", collection);
+}
+
+int RobotMemory::clear_memory()
+{
+  log_deb("Clearing whole robot memory");
+  mongodb_client_->dropDatabase(database_name_);
+  return 1;
+}
+
 void
-RobotMemory::log(Query query, std::string what)
+RobotMemory::log(std::string what, std::string info)
+{
+  if(!info.compare("error"))
+      logger_->log_error(name_, "%s", what.c_str());
+  else if(!info.compare("warn"))
+    logger_->log_warn(name_, "%s", what.c_str());
+  else if(!info.compare("debug"))
+    logger_->log_debug(name_, "%s", what.c_str());
+  else
+    logger_->log_info(name_, "%s", what.c_str());
+}
+
+void
+RobotMemory::log_deb(std::string what, std::string level)
+{
+  if(debug_)
+    log(what, level);
+}
+
+void
+RobotMemory::log_deb(Query query, std::string what, std::string level)
+{
+  if(debug_)
+    log(query, what, level);
+}
+
+void
+RobotMemory::log(Query query, std::string what, std::string level)
 {
   std::string output = what
     + "\nFilter: " + query.getFilter().toString()
@@ -283,17 +285,21 @@ RobotMemory::log(Query query, std::string what)
     + "\nSort: " + query.getSort().toString()
     + "\nHint: " + query.getHint().toString()
     + "\nReadPref: " + query.getReadPref().toString();
+  log(output, level);
+}
 
-  logger_->log_info(name_, "%s", output.c_str());
+void
+RobotMemory::log_deb(BSONObj obj, std::string what, std::string level)
+{
+  log(obj, what, level);
 }
 
 void
-RobotMemory::log(BSONObj obj, std::string what)
+RobotMemory::log(BSONObj obj, std::string what, std::string level)
 {
   std::string output = what
     + "\nObject: " + obj.toString();
-
-  logger_->log_info(name_, "%s", output.c_str());
+  log(output, level);
 }
 
 void
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 7a095f4..e4efa09 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -56,6 +56,8 @@ class RobotMemory
     int insert(std::string insert, std::string collection = "");
     int update(std::string query, std::string update, std::string collection = "");
     int remove(std::string query, std::string collection = "");
+    int drop_collection(std::string collection);
+    int clear_memory();
 
   private:
     mongo::DBClientBase* mongodb_client_;
@@ -65,6 +67,7 @@ class RobotMemory
     fawkes::BlackBoard* blackboard_;
 
     const char* name_ = "RobotMemory";
+    std::string database_name_;
     std::string default_collection_;
     bool debug_;
     fawkes::Mutex *mutex_;
@@ -72,8 +75,12 @@ class RobotMemory
 
     void init();
 
-    void log(mongo::Query query, std::string what);
-    void log(mongo::BSONObj obj, std::string what);
+    void log(std::string what, std::string level = "info");
+    void log_deb(std::string what, std::string level = "info");
+    void log(mongo::Query query, std::string what, std::string level = "info");
+    void log(mongo::BSONObj obj, std::string what, std::string level = "info");
+    void log_deb(mongo::Query query, std::string what, std::string level = "info");
+    void log_deb(mongo::BSONObj obj, std::string what, std::string level = "info");
 
     void set_fields(mongo::BSONObj &obj, std::string what);
     void set_fields(mongo::Query &q, std::string what);

- *commit* f4bea46649b239b2a8136450c17d23b1e6512525 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Mon Aug 29 19:02:53 2016 +0200
Subject: robot-memory: dump and restore collections

 src/plugins/robot-memory/robot_memory.cpp          |   96 ++++++++++++++++++++
 src/plugins/robot-memory/robot_memory.h            |    2 +
 .../robot-memory/test-plugin/robot_memory_test.cpp |   21 ++++-
 3 files changed, 118 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index b4f39ff..724c1fc 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -21,8 +21,13 @@
 #include "robot_memory.h"
 #include <core/threading/mutex.h>
 #include <core/threading/mutex_locker.h>
+#include <utils/misc/string_conversions.h>
+#include <utils/misc/string_split.h>
 #include <memory>
 #include <string>
+#include <stdio.h>
+#include <iostream>
+#include <stdlib.h>
 
 // from MongoDB
 #include <mongo/client/dbclient.h>
@@ -249,6 +254,97 @@ int RobotMemory::clear_memory()
   return 1;
 }
 
+int RobotMemory::restore_collection(std::string collection, std::string directory)
+{
+  drop_collection(collection);
+
+  //resolve path to restore
+  if(collection.find(".") == std::string::npos)
+  {
+    log(std::string("Unable to restore collection" + collection), "error");
+    log(std::string("Specify collection like 'db.collection'"), "error");
+    return 0;
+  }
+  std::string path = StringConversions::resolve_path(directory) + "/"
+      + collection.replace(collection.find("."),1,"/") + ".bson";
+  log_deb(std::string("Restore collection " + collection + " from " + path), "warn");
+
+  //call mongorestore from folder with initial restores
+  std::string command = "/usr/bin/mongorestore --dir " + path + " --quiet";
+  log_deb(std::string("Restore command: " + command), "warn");
+  FILE *bash_output = popen(command.c_str(), "r");
+
+  //check if output is ok
+  if(!bash_output)
+  {
+    log(std::string("Unable to restore collection" + collection), "error");
+    return 0;
+  }
+  std::string output_string = "";
+  char buffer[100];
+  while (!feof(bash_output) )
+  {
+    if (fgets(buffer, 100, bash_output) == NULL)
+    {
+      break;
+    }
+    output_string += buffer;
+  }
+  pclose(bash_output);
+  if(output_string.find("Failed") != std::string::npos)
+  {
+    log(std::string("Unable to restore collection" + collection), "error");
+    log_deb(output_string, "error");
+    return 0;
+  }
+  return 1;
+}
+
+int RobotMemory::dump_collection(std::string collection, std::string directory)
+{
+  //resolve path to dump to
+  if(collection.find(".") == std::string::npos)
+  {
+    log(std::string("Unable to dump collection" + collection), "error");
+    log(std::string("Specify collection like 'db.collection'"), "error");
+    return 0;
+  }
+  std::string path = StringConversions::resolve_path(directory);
+  log_deb(std::string("Dump collection " + collection + " into " + path), "warn");
+
+  //call mongorestore from folder with initial restores
+  std::vector<std::string> split = str_split(collection, '.');
+  std::string command = "/usr/bin/mongodump --out=" + path + " --db=" + split[0]
+    + " --collection=" + split[1] + " --quiet";
+  log_deb(std::string("Dump command: " + command), "warn");
+  FILE *bash_output = popen(command.c_str(), "r");
+
+  //check if output is ok
+  if(!bash_output)
+  {
+    log(std::string("Unable to dump collection" + collection), "error");
+    return 0;
+  }
+  std::string output_string = "";
+  char buffer[100];
+  while (!feof(bash_output) )
+  {
+    if (fgets(buffer, 100, bash_output) == NULL)
+    {
+      break;
+    }
+    output_string += buffer;
+  }
+  pclose(bash_output);
+  if(output_string.find("Failed") != std::string::npos)
+  {
+    log(std::string("Unable to dump collection" + collection), "error");
+    log_deb(output_string, "error");
+    return 0;
+  }
+  return 1;
+}
+
 void
 RobotMemory::log(std::string what, std::string info)
 {
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index e4efa09..0566127 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -58,6 +58,8 @@ class RobotMemory
     int remove(std::string query, std::string collection = "");
     int drop_collection(std::string collection);
     int clear_memory();
+    int restore_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
+    int dump_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
 
   private:
     mongo::DBClientBase* mongodb_client_;
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index 6f8f68e..e9586fb 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -129,13 +129,32 @@ TEST_F(RobotMemoryTest, JavaScriptQuery)
   //TODO: implement
 }
 
+TEST_F(RobotMemoryTest, DumpAndResore)
+{
+  ASSERT_TRUE(robot_memory->drop_collection("robmem.test"));
+  ASSERT_TRUE(robot_memory->insert("{'testkey':'value',v:1}"));
+  ASSERT_TRUE(robot_memory->insert("{'testkey':'value',v:2}"));
+  ASSERT_TRUE(robot_memory->insert("{'testkey':'value',v:3}"));
+  ASSERT_TRUE(robot_memory->dump_collection("robmem.test"));
+  ASSERT_TRUE(robot_memory->drop_collection("robmem.test"));
+  ASSERT_TRUE(robot_memory->restore_collection("robmem.test"));
+  QResCursor qres = robot_memory->query("{'testkey':'value'}");
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value',v:1}")));
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value',v:2}")));
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value',v:3}")));
+  ASSERT_FALSE(qres->more());
+
+}
 
 ::testing::AssertionResult RobotMemoryTest::contains_pairs(BSONObj obj, BSONObj exp)
 {
   for(BSONObjIterator it = exp.begin(); it.more();)
   {
     BSONElement kvpair = it.next();
-    printf("checking %s\n", kvpair.toString().c_str());
+    //printf("checking %s\n", kvpair.toString().c_str());
     if(!obj.hasElement(kvpair.fieldName())
         || obj.getField(kvpair.fieldName()) != kvpair)
     {

- *commit* c41c56ebd56c74bbf5bd0d6f1ead50452145981c - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Mon Aug 29 19:44:31 2016 +0200
Subject: robot-memory: use BSONObj and Query in API

 src/plugins/robot-memory/robot_memory.cpp          |   89 +++++---------------
 src/plugins/robot-memory/robot_memory.h            |   10 ++-
 .../robot-memory/test-plugin/robot_memory_test.cpp |   21 ++---
 3 files changed, 37 insertions(+), 83 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 724c1fc..d273ce2 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -79,28 +79,15 @@ void RobotMemory::init()
   log_deb("Initialized RobotMemory");
 }
 
-QResCursor RobotMemory::query(std::string query_string, std::string collection)
+QResCursor RobotMemory::query(Query query, std::string collection)
 {
   if(collection == "")
-  {
     collection = default_collection_;
-  }
-  log_deb(std::string("Executing Query "+ query_string+" on collection "+collection));
+  log_deb(std::string("Executing Query "+ query.toString() +" on collection "+collection));
 
   //only one query at a time
   MutexLocker lock(mutex_);
 
-  //get query from string
-  Query query;
-  try{
-    query = Query(query_string);
-  } catch (DBException &e) {
-    std::string error = "Can't parse query_string "
-        + query_string + "\n Exception: " + e.toString();
-    log_deb(error, "error");
-    return NULL;
-  }
-
 //  //introspect query
 //  log(query, "executing query:");
 
@@ -124,43 +111,30 @@ QResCursor RobotMemory::query(std::string query_string, std::string collection)
     cursor = mongodb_client_->query(collection, query);
   } catch (DBException &e) {
     std::string error = std::string("Error for query ")
-      + query_string + "\n Exception: " + e.toString();
+      + query.toString() + "\n Exception: " + e.toString();
     log(error, "error");
     return NULL;
   }
   return cursor;
 }
 
-int RobotMemory::insert(std::string insert_string, std::string collection)
+int RobotMemory::insert(BSONObj obj, std::string collection)
 {
   if(collection == "")
-  {
     collection = default_collection_;
-  }
 
-  log_deb(std::string("Executing Query "+ insert_string + " on collection " + collection));
+  log_deb(std::string("Executing Query "+ obj.toString() + " on collection " + collection));
 
   //only one query at a time
   MutexLocker lock(mutex_);
 
-  //get query from string
-  BSONObj obj;
-  try{
-    obj = fromjson(insert_string);
-  } catch (DBException &e) {
-    std::string error = "Can't parse insert_string "
-        + insert_string + "\n Exception: " + e.toString();
-    log_deb(error, "error");
-    return 0;
-  }
-
   set_fields(obj, "{type: \"test\"}");
 
   //actually execute insert
   try{
     mongodb_client_->insert(collection, obj);
   } catch (DBException &e) {
-    std::string error = "Error for insert " + insert_string
+    std::string error = "Error for insert " + obj.toString()
         + "\n Exception: " + e.toString();
     log_deb(error, "error");
     return 0;
@@ -169,72 +143,54 @@ int RobotMemory::insert(std::string insert_string, std::string collection)
   return 1;
 }
 
-int RobotMemory::update(std::string query_string, std::string update_string,
-                                    std::string collection)
+int RobotMemory::insert(std::string obj_str, std::string collection)
+{
+  return insert(fromjson(obj_str), collection);
+}
+
+int RobotMemory::update(Query query, BSONObj update, std::string collection)
 {
   if(collection == "")
   {
     collection = default_collection_;
   }
-  log_deb(std::string("Executing Update "+update_string+" for query "+query_string+" on collection "+ collection));
+  log_deb(std::string("Executing Update "+update.toString()+" for query "+query.toString()+" on collection "+ collection));
 
   //only one query at a time
   MutexLocker lock(mutex_);
 
-  //get query from string
-  Query query;
-  try{
-    query = Query(query_string);
-  } catch (DBException &e) {
-    std::string error = "Can't parse query_string " + query_string
-        + "\n Exception: " + e.toString();
-    log_deb(error, "error");
-    return 0;
-  }
-  BSONObj update;
-  try{
-    update = fromjson(update_string);
-  } catch (DBException &e) {
-    log_deb(std::string("Can't parse update_string '"+update_string+"'\n Exception: "+e.toString()),"error");
-    return 0;
-  }
-
   //actually execute update
   try{
     mongodb_client_->update(collection, query, update);
   } catch (DBException &e) {
-    log_deb(std::string("Error for update "+update_string+" for query "+query_string+"\n Exception: "+e.toString()), "error");
+    log_deb(std::string("Error for update "+update.toString()+" for query "+query.toString()+"\n Exception: "+e.toString()), "error");
     return 0;
   }
   //return success
   return 1;
 }
 
-int RobotMemory::remove(std::string query_string, std::string collection)
+int RobotMemory::update(Query query, std::string update_str, std::string collection)
+{
+  return update(query, fromjson(update_str), collection);
+}
+
+int RobotMemory::remove(Query query, std::string collection)
 {
   if(collection == "")
   {
     collection = default_collection_;
   }
-  log_deb(std::string("Executing Remove "+query_string+" on collection "+collection));
+  log_deb(std::string("Executing Remove "+query.toString()+" on collection "+collection));
 
   //only one query at a time
   MutexLocker lock(mutex_);
 
-  //get query from string
-  Query query;
-  try{
-    query = Query(query_string);
-  } catch (DBException &e) {
-    log_deb(std::string("Can't parse query_string '"+query_string+"'\n Exception: "+e.toString()), "error");
-    return 0;
-  }
-
   //actually execute remove
   try{
     mongodb_client_->remove(collection, query);
   } catch (DBException &e) {
-    log_deb(std::string("Error for query "+query_string+"\n Exception: "+e.toString()), "error");
+    log_deb(std::string("Error for query "+query.toString()+"\n Exception: "+e.toString()), "error");
     return 0;
   }
   //return success
@@ -442,4 +398,3 @@ RobotMemory::remove_field(Query &q, std::string what)
   //override
   q = Query(b.obj());
 }
-
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 0566127..58c17f7 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -52,10 +52,12 @@ class RobotMemory
     virtual ~RobotMemory();
 
     //robot memory functions
-    QResCursor query(std::string query, std::string collection = "");
-    int insert(std::string insert, std::string collection = "");
-    int update(std::string query, std::string update, std::string collection = "");
-    int remove(std::string query, std::string collection = "");
+    QResCursor query(mongo::Query query, std::string collection = "");
+    int insert(mongo::BSONObj obj, std::string collection = "");
+    int insert(std::string obj_str, std::string collection = "");
+    int update(mongo::Query query, mongo::BSONObj update, std::string collection = "");
+    int update(mongo::Query query, std::string update_str, std::string collection = "");
+    int remove(mongo::Query query, std::string collection = "");
     int drop_collection(std::string collection);
     int clear_memory();
     int restore_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index e9586fb..1e35e04 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -87,31 +87,28 @@ TEST_F(RobotMemoryTest, StoreRemoveQuery)
   ASSERT_FALSE(qres->more());
 }
 
-TEST_F(RobotMemoryTest, QueryInvalidCaught)
+TEST_F(RobotMemoryTest, QueryInvalid)
 {
-  ASSERT_FALSE(robot_memory->query("{key-:+'not existing'}"));
+  ASSERT_THROW(robot_memory->query("{key-:+'not existing'}"), mongo::DBException);
 }
 
 TEST_F(RobotMemoryTest, InsertInvalidCaught)
 {
-  ASSERT_NO_THROW(robot_memory->insert("{'testkey'::'value'}"));
-  ASSERT_FALSE(robot_memory->insert("warbagarbl"));
+  ASSERT_THROW(robot_memory->insert("{'testkey'::'value'}"), mongo::DBException);
+  ASSERT_THROW(robot_memory->insert("warbagarbl"), mongo::DBException);
 }
 
 TEST_F(RobotMemoryTest, UpdateInvalidCaught)
 {
-  ASSERT_NO_THROW(robot_memory->update("{'testkey'::'value'}",
-      "{'key':'update'}"));
-  ASSERT_NO_THROW(robot_memory->update("{'testkey':'good'}",
-      "{'bad':1.2.3}"));
-  ASSERT_FALSE(robot_memory->update("{([})]", "{'key':4}"));
-  ASSERT_FALSE(robot_memory->update("{'key':'valid'}", "invalid!"));
+  ASSERT_THROW(robot_memory->update("{'testkey':'good'}",
+      "{'bad':1.2.3}"), mongo::DBException);
+  ASSERT_THROW(robot_memory->update("{([})]", "{'key':4}"), mongo::DBException);
 }
 
 TEST_F(RobotMemoryTest, RemoveInvalidCaught)
 {
-  ASSERT_NO_THROW(robot_memory->remove("{____:4.56}"));
-  ASSERT_FALSE(robot_memory->remove("{([})]"));
+  ASSERT_THROW(robot_memory->remove("{____:4.56!}"), mongo::DBException);
+  ASSERT_THROW(robot_memory->remove("{([})]"), mongo::DBException);
 }
 
 TEST_F(RobotMemoryTest, AggregationQuery)

- *commit* 8929eccd8ab91547209b76ea04c112754cc13c6b - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Mon Aug 29 20:27:26 2016 +0200
Subject: clips-robot-memory: start for CLIPS feature from refbox clips-mongodb

 src/plugins/Makefile                               |    2 +-
 src/plugins/clips-robot-memory/Makefile            |   60 ++
 .../clips_robot_memory_plugin.cpp}                 |   20 +-
 .../clips_robot_memory_thread.cpp                  |  680 ++++++++++++++++++++
 .../clips-robot-memory/clips_robot_memory_thread.h |   95 +++
 5 files changed, 846 insertions(+), 11 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/Makefile b/src/plugins/Makefile
index 499bb73..bde3bfe 100644
--- a/src/plugins/Makefile
+++ b/src/plugins/Makefile
@@ -26,7 +26,7 @@ SUBDIRS	= bbsync bblogger webview ttmainloop rrd rrdweb \
 	  static_transforms navgraph navgraph-clusters navgraph-generator colli \
 	  clips clips-agent clips-protobuf clips-webview clips-navgraph clips-ros \
 	  clips-tf openprs openprs-agent eclipse-clp \
-	  mongodb mongodb_log robot-memory\
+	  mongodb mongodb_log robot-memory clips-robot-memory \
 	  openni refboxcomm ros player xmlrpc gossip \
 	  robot_state_publisher gazebo dynamixel navgraph-interactive \
 	  asp

- *commit* b7a6f91e0a8f140aa4e12cc43fbbbbcda6d8e838 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Sep 1 15:00:10 2016 +0200
Subject: robot-memory: add upsert option in update function

 src/plugins/robot-memory/robot_memory.cpp          |    8 ++++----
 src/plugins/robot-memory/robot_memory.h            |    4 ++--
 .../robot-memory/test-plugin/robot_memory_test.cpp |   10 ++++++++++
 3 files changed, 16 insertions(+), 6 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index d273ce2..9a4e65d 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -148,7 +148,7 @@ int RobotMemory::insert(std::string obj_str, std::string collection)
   return insert(fromjson(obj_str), collection);
 }
 
-int RobotMemory::update(Query query, BSONObj update, std::string collection)
+int RobotMemory::update(Query query, BSONObj update, std::string collection, bool upsert)
 {
   if(collection == "")
   {
@@ -161,7 +161,7 @@ int RobotMemory::update(Query query, BSONObj update, std::string collection)
 
   //actually execute update
   try{
-    mongodb_client_->update(collection, query, update);
+    mongodb_client_->update(collection, query, update, upsert);
   } catch (DBException &e) {
     log_deb(std::string("Error for update "+update.toString()+" for query "+query.toString()+"\n Exception: "+e.toString()), "error");
     return 0;
@@ -170,9 +170,9 @@ int RobotMemory::update(Query query, BSONObj update, std::string collection)
   return 1;
 }
 
-int RobotMemory::update(Query query, std::string update_str, std::string collection)
+int RobotMemory::update(Query query, std::string update_str, std::string collection, bool upsert)
 {
-  return update(query, fromjson(update_str), collection);
+  return update(query, fromjson(update_str), collection, upsert);
 }
 
 int RobotMemory::remove(Query query, std::string collection)
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 58c17f7..2ad892b 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -55,8 +55,8 @@ class RobotMemory
     QResCursor query(mongo::Query query, std::string collection = "");
     int insert(mongo::BSONObj obj, std::string collection = "");
     int insert(std::string obj_str, std::string collection = "");
-    int update(mongo::Query query, mongo::BSONObj update, std::string collection = "");
-    int update(mongo::Query query, std::string update_str, std::string collection = "");
+    int update(mongo::Query query, mongo::BSONObj update, std::string collection = "", bool upsert = false);
+    int update(mongo::Query query, std::string update_str, std::string collection = "", bool upsert = false);
     int remove(mongo::Query query, std::string collection = "");
     int drop_collection(std::string collection);
     int clear_memory();
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index 1e35e04..a24e29e 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -87,6 +87,16 @@ TEST_F(RobotMemoryTest, StoreRemoveQuery)
   ASSERT_FALSE(qres->more());
 }
 
+TEST_F(RobotMemoryTest, Upsert)
+{
+  ASSERT_TRUE(robot_memory->update("{upsert:'not existing'}", "{upsert:'should not exist'}", "", false));
+  QResCursor qres = robot_memory->query("{upsert:'should not exist'}");
+  ASSERT_FALSE(qres->more());
+  ASSERT_TRUE(robot_memory->update("{upsert:'not existing'}", "{upsert:'should exist'}", "", true));
+  qres = robot_memory->query("{upsert:'should exist'}");
+  ASSERT_TRUE(qres->more());
+}
+
 TEST_F(RobotMemoryTest, QueryInvalid)
 {
   ASSERT_THROW(robot_memory->query("{key-:+'not existing'}"), mongo::DBException);

- *commit* ef0eff479b0e62e8bc94143fc6595379219182db - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Sep 1 16:25:04 2016 +0200
Subject: robot-memory: removed setting type in document for testing

 src/plugins/robot-memory/robot_memory.cpp |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 9a4e65d..dce9510 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -128,8 +128,6 @@ int RobotMemory::insert(BSONObj obj, std::string collection)
   //only one query at a time
   MutexLocker lock(mutex_);
 
-  set_fields(obj, "{type: \"test\"}");
-
   //actually execute insert
   try{
     mongodb_client_->insert(collection, obj);

- *commit* 5a1175768a048035d1d0355b4c5a9a2645dc86d9 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Sep 1 17:42:09 2016 +0200
Subject: clips-robot-memory: adjusted plugin to use the robot memory

 .../clips_robot_memory_thread.cpp                  |  113 +++++++++-----------
 .../clips-robot-memory/clips_robot_memory_thread.h |   21 ++--
 2 files changed, 60 insertions(+), 74 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
index 725ae1f..fdd9231 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
@@ -62,32 +62,32 @@ ClipsRobotMemoryThread::clips_context_init(const std::string &env_name,
 
   clips.lock();
 
-  clips_->add_function("bson-create", sigc::slot<CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_create)));
-  clips_->add_function("bson-parse", sigc::slot<CLIPS::Value, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_parse)));
-  clips_->add_function("bson-destroy", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_destroy)));
-  clips_->add_function("bson-append", sigc::slot<void, void *, std::string, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_append)));
-  clips_->add_function("bson-append-array", sigc::slot<void, void *, std::string, CLIPS::Values>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_append_array)));
-  clips_->add_function("bson-array-start", sigc::slot<CLIPS::Value, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_array_start)));
-  clips_->add_function("bson-array-finish", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_array_finish)));
-  clips_->add_function("bson-array-append", sigc::slot<void, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_array_append)));
-
-  clips_->add_function("bson-append-time", sigc::slot<void, void *, std::string, CLIPS::Values>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_append_time)));
-  clips_->add_function("bson-tostring", sigc::slot<std::string, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_tostring)));
-  clips_->add_function("mongodb-insert", sigc::slot<void, std::string, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_mongodb_insert)));
-  clips_->add_function("mongodb-upsert", sigc::slot<void, std::string, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_mongodb_upsert)));
-  clips_->add_function("mongodb-update", sigc::slot<void, std::string, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_mongodb_update)));
-  clips_->add_function("mongodb-replace", sigc::slot<void, std::string, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_mongodb_replace)));
-  clips_->add_function("mongodb-query", sigc::slot<CLIPS::Value, std::string, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_mongodb_query)));
-  clips_->add_function("mongodb-query-sort", sigc::slot<CLIPS::Value, std::string, void *, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_mongodb_query_sort)));
-  clips_->add_function("mongodb-cursor-destroy", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_mongodb_cursor_destroy)));
-  clips_->add_function("mongodb-cursor-more", sigc::slot<CLIPS::Value, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_mongodb_cursor_more)));
-  clips_->add_function("mongodb-cursor-next", sigc::slot<CLIPS::Value, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_mongodb_cursor_next)));
-  clips_->add_function("bson-field-names", sigc::slot<CLIPS::Values, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_field_names)));
-  clips_->add_function("bson-get", sigc::slot<CLIPS::Value, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get)));
-  clips_->add_function("bson-get-array", sigc::slot<CLIPS::Values, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get_array)));
-  clips_->add_function("bson-get-time", sigc::slot<CLIPS::Values, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get_time)));
-
-  clips_->build("(deffacts have-feature-mongodb (have-feature MongoDB))");
+  clips->add_function("bson-create", sigc::slot<CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_create)));
+  clips->add_function("bson-parse", sigc::slot<CLIPS::Value, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_parse)));
+  clips->add_function("bson-destroy", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_destroy)));
+  clips->add_function("bson-append", sigc::slot<void, void *, std::string, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_append)));
+  clips->add_function("bson-append-array", sigc::slot<void, void *, std::string, CLIPS::Values>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_append_array)));
+  clips->add_function("bson-array-start", sigc::slot<CLIPS::Value, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_array_start)));
+  clips->add_function("bson-array-finish", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_array_finish)));
+  clips->add_function("bson-array-append", sigc::slot<void, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_array_append)));
+
+  clips->add_function("bson-append-time", sigc::slot<void, void *, std::string, CLIPS::Values>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_append_time)));
+  clips->add_function("bson-tostring", sigc::slot<std::string, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_tostring)));
+  clips->add_function("robmem-insert", sigc::slot<void, std::string, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_insert)));
+  clips->add_function("robmem-upsert", sigc::slot<void, std::string, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_upsert)));
+  clips->add_function("robmem-update", sigc::slot<void, std::string, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_update)));
+  clips->add_function("robmem-replace", sigc::slot<void, std::string, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_replace)));
+  clips->add_function("robmem-query", sigc::slot<CLIPS::Value, std::string, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_query)));
+  clips->add_function("robmem-query-sort", sigc::slot<CLIPS::Value, std::string, void *, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_query_sort)));
+  clips->add_function("robmem-cursor-destroy", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_cursor_destroy)));
+  clips->add_function("robmem-cursor-more", sigc::slot<CLIPS::Value, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_cursor_more)));
+  clips->add_function("robmem-cursor-next", sigc::slot<CLIPS::Value, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_cursor_next)));
+  clips->add_function("bson-field-names", sigc::slot<CLIPS::Values, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_field_names)));
+  clips->add_function("bson-get", sigc::slot<CLIPS::Value, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get)));
+  clips->add_function("bson-get-array", sigc::slot<CLIPS::Values, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get_array)));
+  clips->add_function("bson-get-time", sigc::slot<CLIPS::Values, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get_time)));
+
+  clips->build("(deffacts have-feature-mongodb (have-feature MongoDB))");
 
   //TODO: clips->batch_evaluate(SRCDIR"/plugins/clips-robot-memory/robot_memory.clp");
 
@@ -118,7 +118,7 @@ ClipsRobotMemoryThread::clips_bson_parse(std::string document)
 #ifdef HAVE_MONGODB_VERSION_H
   } catch (mongo::MsgAssertionException &e) {
 #else
-  } catch (bson::assertion &e) {
+  } catch (mongo::AssertionException &e) {
 #endif
     logger->log_error("MongoDB", "Parsing JSON doc failed: %s\n%s",
            e.what(), document.c_str());
@@ -175,7 +175,7 @@ ClipsRobotMemoryThread::clips_bson_append(void *bson, std::string field_name, CL
 #ifdef HAVE_MONGODB_VERSION_H
   } catch (mongo::MsgAssertionException &e) {
 #else
-  } catch (bson::assertion &e) {
+  } catch (mongo::AssertionException &e) {
 #endif
     logger->log_error("MongoDB", "Failed to append array value to field %s: %s",
            field_name.c_str(), e.what());
@@ -224,7 +224,7 @@ ClipsRobotMemoryThread::clips_bson_append_array(void *bson,
 #ifdef HAVE_MONGODB_VERSION_H
   } catch (mongo::MsgAssertionException &e) {
 #else
-  } catch (bson::assertion &e) {
+  } catch (mongo::AssertionException &e) {
 #endif
     logger->log_error("MongoDB", "Failed to append array value to field %s: %s",
            field_name.c_str(), e.what());
@@ -282,7 +282,7 @@ ClipsRobotMemoryThread::clips_bson_array_append(void *barr, CLIPS::Value value)
 #ifdef HAVE_MONGODB_VERSION_H
   } catch (mongo::MsgAssertionException &e) {
 #else
-  } catch (bson::assertion &e) {
+  } catch (mongo::AssertionException &e) {
 #endif
     logger->log_error("MongoDB", "Failed to append to array: %s", e.what());
   }
@@ -309,7 +309,7 @@ ClipsRobotMemoryThread::clips_bson_append_time(void *bson, std::string field_nam
 #ifdef HAVE_MONGODB_VERSION_H
   } catch (mongo::MsgAssertionException &e) {
 #else
-  } catch (bson::assertion &e) {
+  } catch (mongo::AssertionException &e) {
 #endif
     logger->log_error("MongoDB", "Failed to append time value to field %s: %s",
            field_name.c_str(), e.what());
@@ -317,17 +317,12 @@ ClipsRobotMemoryThread::clips_bson_append_time(void *bson, std::string field_nam
 }
 
 void
-ClipsRobotMemoryThread::clips_mongodb_insert(std::string collection, void *bson)
+ClipsRobotMemoryThread::clips_robotmemory_insert(std::string collection, void *bson)
 {
-  if (! cfg_mongodb_enabled_) {
-    logger->log_warn("MongoDB", "Insert requested while MongoDB disabled");
-    return;
-  }
-
   mongo::BSONObjBuilder *b = static_cast<mongo::BSONObjBuilder *>(bson);
 
   try {
-    mongodb_->insert(collection, b->asTempObj());
+    robot_memory->insert(b->asTempObj(), collection);
   } catch (mongo::DBException &e) {
     logger->log_warn("MongoDB", "Insert failed: %s", e.what());
   }
@@ -335,14 +330,9 @@ ClipsRobotMemoryThread::clips_mongodb_insert(std::string collection, void *bson)
 
 
 void
-ClipsRobotMemoryThread::mongodb_update(std::string &collection, mongo::BSONObj obj,
+ClipsRobotMemoryThread::robotmemory_update(std::string &collection, mongo::BSONObj obj,
          CLIPS::Value &query, bool upsert)
 {
-  if (! cfg_mongodb_enabled_) {
-    logger->log_warn("MongoDB", "Update requested while MongoDB disabled");
-    return;
-  }
-
   try {
     mongo::BSONObj query_obj;
     if (query.type() == CLIPS::TYPE_STRING) {
@@ -355,11 +345,11 @@ ClipsRobotMemoryThread::mongodb_update(std::string &collection, mongo::BSONObj o
       return;
     }
 
-    mongodb_->update(collection, query_obj, obj, upsert);
+    robot_memory->update(query_obj, obj, collection, upsert);
 #ifdef HAVE_MONGODB_VERSION_H
   } catch (mongo::MsgAssertionException &e) {
 #else
-  } catch (bson::assertion &e) {
+  } catch (mongo::AssertionException &e) {
 #endif
     logger->log_warn("MongoDB", "Compiling query failed: %s", e.what());
   } catch (mongo::DBException &e) {
@@ -369,18 +359,18 @@ ClipsRobotMemoryThread::mongodb_update(std::string &collection, mongo::BSONObj o
 
 
 void
-ClipsRobotMemoryThread::clips_mongodb_upsert(std::string collection, void *bson, CLIPS::Value query)
+ClipsRobotMemoryThread::clips_robotmemory_upsert(std::string collection, void *bson, CLIPS::Value query)
 {
   mongo::BSONObjBuilder *b = static_cast<mongo::BSONObjBuilder *>(bson);
   if (! b) {
     logger->log_warn("MongoDB", "Invalid BSON Obj Builder passed");
     return;
   }
-  mongodb_update(collection, b->asTempObj(), query, true);
+  robotmemory_update(collection, b->asTempObj(), query, true);
 }
 
 void
-ClipsRobotMemoryThread::clips_mongodb_update(std::string collection, void *bson, CLIPS::Value query)
+ClipsRobotMemoryThread::clips_robotmemory_update(std::string collection, void *bson, CLIPS::Value query)
 {
   mongo::BSONObjBuilder *b = static_cast<mongo::BSONObjBuilder *>(bson);
   if (! b) {
@@ -391,25 +381,20 @@ ClipsRobotMemoryThread::clips_mongodb_update(std::string collection, void *bson,
   mongo::BSONObjBuilder update_doc;
   update_doc.append("$set", b->asTempObj());
 
-  mongodb_update(collection, update_doc.obj(), query, false);
+  robotmemory_update(collection, update_doc.obj(), query, false);
 }
 
 void
-ClipsRobotMemoryThread::clips_mongodb_replace(std::string collection, void *bson, CLIPS::Value query)
+ClipsRobotMemoryThread::clips_robotmemory_replace(std::string collection, void *bson, CLIPS::Value query)
 {
   mongo::BSONObjBuilder *b = static_cast<mongo::BSONObjBuilder *>(bson);
   if (! b) logger->log_warn("MongoDB", "Invalid BSON Obj Builder passed");
-  mongodb_update(collection, b->asTempObj(), query, false);
+  robotmemory_update(collection, b->asTempObj(), query, false);
 }
 
 CLIPS::Value
-ClipsRobotMemoryThread::clips_mongodb_query_sort(std::string collection, void *bson, void *bson_sort)
+ClipsRobotMemoryThread::clips_robotmemory_query_sort(std::string collection, void *bson, void *bson_sort)
 {
-  if (! cfg_mongodb_enabled_) {
-    logger->log_warn("MongoDB", "Query requested while MongoDB disabled");
-    return CLIPS::Value("FALSE", CLIPS::TYPE_SYMBOL);
-  }
-
   mongo::BSONObjBuilder *b = static_cast<mongo::BSONObjBuilder *>(bson);
 
   try {
@@ -420,7 +405,7 @@ ClipsRobotMemoryThread::clips_mongodb_query_sort(std::string collection, void *b
     }
 
 #if __cplusplus >= 201103L
-    std::unique_ptr<mongo::DBClientCursor> c = mongodb_->query(collection, q);
+    std::unique_ptr<mongo::DBClientCursor> c = robot_memory->query(q, collection);
 
     return CLIPS::Value(new std::unique_ptr<mongo::DBClientCursor>(std::move(c)),
                         CLIPS::TYPE_EXTERNAL_ADDRESS);
@@ -438,13 +423,13 @@ ClipsRobotMemoryThread::clips_mongodb_query_sort(std::string collection, void *b
 }
 
 CLIPS::Value
-ClipsRobotMemoryThread::clips_mongodb_query(std::string collection, void *bson)
+ClipsRobotMemoryThread::clips_robotmemory_query(std::string collection, void *bson)
 {
-  return clips_mongodb_query_sort(collection, bson, NULL);
+  return clips_robotmemory_query_sort(collection, bson, NULL);
 }
 
 void
-ClipsRobotMemoryThread::clips_mongodb_cursor_destroy(void *cursor)
+ClipsRobotMemoryThread::clips_robotmemory_cursor_destroy(void *cursor)
 {
 #if __cplusplus >= 201103L
   std::unique_ptr<mongo::DBClientCursor> *c =
@@ -463,7 +448,7 @@ ClipsRobotMemoryThread::clips_mongodb_cursor_destroy(void *cursor)
 }
 
 CLIPS::Value
-ClipsRobotMemoryThread::clips_mongodb_cursor_more(void *cursor)
+ClipsRobotMemoryThread::clips_robotmemory_cursor_more(void *cursor)
 {
 #if __cplusplus >= 201103L
   std::unique_ptr<mongo::DBClientCursor> *c =
@@ -482,7 +467,7 @@ ClipsRobotMemoryThread::clips_mongodb_cursor_more(void *cursor)
 }
 
 CLIPS::Value
-ClipsRobotMemoryThread::clips_mongodb_cursor_next(void *cursor)
+ClipsRobotMemoryThread::clips_robotmemory_cursor_next(void *cursor)
 {
 #if __cplusplus >= 201103L
   std::unique_ptr<mongo::DBClientCursor> *c =
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.h b/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
index 25b2b84..6b43d48 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
@@ -28,6 +28,7 @@
 #include <core/threading/thread.h>
 #include <aspect/logging.h>
 #include <aspect/configurable.h>
+#include <plugins/clips/aspect/clips_feature.h>
 #include <plugins/robot-memory/aspect/robot_memory_aspect.h>
 
 #include <string>
@@ -74,17 +75,17 @@ class ClipsRobotMemoryThread
   void          clips_bson_array_finish(void *barr);
   void          clips_bson_array_append(void *barr, CLIPS::Value value);
   std::string   clips_bson_tostring(void *bson);
-  void          clips_mongodb_upsert(std::string collection, void *bson, CLIPS::Value query);
-  void          clips_mongodb_update(std::string collection, void *bson, CLIPS::Value query);
-  void          clips_mongodb_replace(std::string collection, void *bson, CLIPS::Value query);
-  void          clips_mongodb_insert(std::string collection, void *bson);
-  void          mongodb_update(std::string &collection, mongo::BSONObj obj,
+  void          clips_robotmemory_upsert(std::string collection, void *bson, CLIPS::Value query);
+  void          clips_robotmemory_update(std::string collection, void *bson, CLIPS::Value query);
+  void          clips_robotmemory_replace(std::string collection, void *bson, CLIPS::Value query);
+  void          clips_robotmemory_insert(std::string collection, void *bson);
+  void          robotmemory_update(std::string &collection, mongo::BSONObj obj,
                                CLIPS::Value &query, bool upsert);
-  CLIPS::Value  clips_mongodb_query_sort(std::string collection, void *bson, void *bson_sort);
-  CLIPS::Value  clips_mongodb_query(std::string collection, void *bson);
-  CLIPS::Value  clips_mongodb_cursor_more(void *cursor);
-  CLIPS::Value  clips_mongodb_cursor_next(void *cursor);
-  void          clips_mongodb_cursor_destroy(void *cursor);
+  CLIPS::Value  clips_robotmemory_query_sort(std::string collection, void *bson, void *bson_sort);
+  CLIPS::Value  clips_robotmemory_query(std::string collection, void *bson);
+  CLIPS::Value  clips_robotmemory_cursor_more(void *cursor);
+  CLIPS::Value  clips_robotmemory_cursor_next(void *cursor);
+  void          clips_robotmemory_cursor_destroy(void *cursor);
   CLIPS::Values clips_bson_field_names(void *bson);
   CLIPS::Value  clips_bson_get(void *bson, std::string field_name);
   CLIPS::Values clips_bson_get_array(void *bson, std::string field_name);

- *commit* 5193fd949c8c8720b2cf4a5c2e0eefb78b871508 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Sep 13 18:01:15 2016 +0200
Subject: clips-robot-memory: function to create BSON doc from structured fact

 .../clips_robot_memory_thread.cpp                  |    3 +-
 src/plugins/clips-robot-memory/robot-memory.clp    |   29 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
index fdd9231..7b5c589 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
@@ -89,7 +89,8 @@ ClipsRobotMemoryThread::clips_context_init(const std::string &env_name,
 
   clips->build("(deffacts have-feature-mongodb (have-feature MongoDB))");
 
-  //TODO: clips->batch_evaluate(SRCDIR"/plugins/clips-robot-memory/robot_memory.clp");
+  //load helper functions written in CLIPS
+  clips->batch_evaluate(SRCDIR"/robot-memory.clp");
 
   clips.unlock();
 }

- *commit* 333d69f01bb2f061e0b82b2e5a2b2708e8d48ffd - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Sep 13 18:19:27 2016 +0200
Subject: clips-robot-memory: create BSON document from ordered fact

 src/plugins/clips-robot-memory/robot-memory.clp |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/robot-memory.clp b/src/plugins/clips-robot-memory/robot-memory.clp
index dc29baf..aa75186 100644
--- a/src/plugins/clips-robot-memory/robot-memory.clp
+++ b/src/plugins/clips-robot-memory/robot-memory.clp
@@ -13,7 +13,7 @@
 (deffunction rm-structured-fact-to-bson (?fact)
   (bind ?doc (bson-create))
   (bind ?templ (fact-relation ?fact))
-  (bson-append ?doc "type" (str-cat ?templ))
+  (bson-append ?doc "relation" (str-cat ?templ))
   ;append kv-pair for each field
   (progn$ (?slot (fact-slot-names ?fact))
     (if (deftemplate-slot-multip ?templ ?slot)
@@ -27,3 +27,15 @@
   )      
   (return ?doc)
 )
+
+;; Creates a BSON document from an ordered fact
+; @param ?fact Fact-Pointer
+; @return BSON document
+(deffunction rm-ordered-fact-to-bson (?fact)
+  (bind ?doc (bson-create))
+  (bind ?templ (fact-relation ?fact))
+  (bson-append ?doc "relation" (str-cat ?templ))
+  ;append values as array
+  (bson-append-array ?doc "values" (fact-slot-value ?fact implied))
+  (return ?doc)
+)

- *commit* 99337cec1665536e44167905c12bf272669c51d1 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Sep 13 19:15:24 2016 +0200
Subject: clips-robot-memory: assert facts from bson document

 src/plugins/clips-robot-memory/robot-memory.clp |   34 +++++++++++++++++++++++
 1 files changed, 34 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/robot-memory.clp b/src/plugins/clips-robot-memory/robot-memory.clp
index aa75186..709f6bb 100644
--- a/src/plugins/clips-robot-memory/robot-memory.clp
+++ b/src/plugins/clips-robot-memory/robot-memory.clp
@@ -39,3 +39,37 @@
   (bson-append-array ?doc "values" (fact-slot-value ?fact implied))
   (return ?doc)
 )
+
+;; Assert (structured/ordered) fact from a BSON document
+; @param ?doc BSON document
+(deffunction rm-assert-from-bson (?doc)
+  (bind ?relation "")
+  (bind ?values "")
+  (bind ?keys (bson-field-names ?doc))
+  (if (member$ "relation" ?keys)
+    then
+    (bind ?relation (bson-get ?doc "relation"))
+    else
+    (printout error "Can not create fact from " (bson-tostring ?doc) crlf)
+    (return)
+  )
+  (if (member$ ?relation (get-deftemplate-list *))
+    then ;structured fact
+    (progn$ (?slot ?keys)
+      (if (deftemplate-slot-existp ?relation ?slot) then
+        (if (deftemplate-slot-multip ?relation ?slot)
+          then
+          (bind ?values (str-cat ?values "(" ?relation " " (bson-get ?doc ?slot) ")"))
+          else
+          (bind ?values (str-cat ?values "(" ?relation " " (implode$ (bson-get-array ?doc ?slot)) ")"))
+        )
+      )
+    )
+    else ;ordered fact
+    (if (member$ "values" ?keys) then
+      (bind ?values (str-cat ?values "(" ?relation " " (implode$ (bson-get-array ?doc "values")) ")"))
+    )
+  )
+  
+  (assert-string (str-cat "(" ?relation " " ?values ")"))
+)

- *commit* 3cc3e1026428906366e8411ddc00ed93751f904d - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Sep 21 17:55:02 2016 +0200
Subject: robot-memory: startup local mongod processes

 src/plugins/robot-memory/robot_memory_plugin.cpp |   16 +++-
 src/plugins/robot-memory/robot_memory_setup.cpp  |  122 ++++++++++++++++++++++
 src/plugins/robot-memory/robot_memory_setup.h    |   56 ++++++++++
 src/plugins/robot-memory/robot_memory_thread.cpp |    6 +-
 src/plugins/robot-memory/robot_memory_thread.h   |    2 +-
 5 files changed, 198 insertions(+), 4 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_plugin.cpp b/src/plugins/robot-memory/robot_memory_plugin.cpp
index 2160ed6..c0d4b0f 100644
--- a/src/plugins/robot-memory/robot_memory_plugin.cpp
+++ b/src/plugins/robot-memory/robot_memory_plugin.cpp
@@ -19,6 +19,9 @@
  */
 
 #include "robot_memory_thread.h"
+#include "robot_memory_setup.h"
+#include <string>
+#include <logging/console.h>
 
 #include <core/plugin.h>
 
@@ -37,14 +40,25 @@ class RobotMemoryPlugin : public fawkes::Plugin
    */
   RobotMemoryPlugin(Configuration *config) : Plugin(config)
   {
-	  thread_list.push_back(new RobotMemoryThread());
+    //before starting the robot memory (thread), we have to setup the mongod and mongos processes
+    //because the mongodb aspect of the robot memory hat to connect to it
+    logger_for_setup = new ConsoleLogger(Logger::LL_WARN);
+    setup = new RobotMemorySetup(config, logger_for_setup);
+    setup->setup_mongods();
+
+    std::string mongo_client_connection = config->get_string("plugins/robot-memory/setup/mongo-client-connection");
+	  thread_list.push_back(new RobotMemoryThread(mongo_client_connection));
   }
 
 
   ~RobotMemoryPlugin()
   {
+    delete setup;
+    delete logger_for_setup;
   }
 
+  RobotMemorySetup* setup;
+  Logger *logger_for_setup;
 };
 
 
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 5ba2c0c..807c55d 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -35,9 +35,11 @@ using namespace fawkes;
  */
 
 /** Constructor. */
-RobotMemoryThread::RobotMemoryThread()
+RobotMemoryThread::RobotMemoryThread(std::string mongo_client_connection)
 	: Thread("RobotMemoryThread", Thread::OPMODE_WAITFORWAKEUP),
-	  BlockedTimingAspect(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PROCESS),
+    ConfigurableAspect(),
+    MongoDBAspect(mongo_client_connection.c_str()),
+    BlockedTimingAspect(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PROCESS),
     AspectProviderAspect(&robot_memory_inifin_)
 {
 }
diff --git a/src/plugins/robot-memory/robot_memory_thread.h b/src/plugins/robot-memory/robot_memory_thread.h
index b23ed42..610252f 100644
--- a/src/plugins/robot-memory/robot_memory_thread.h
+++ b/src/plugins/robot-memory/robot_memory_thread.h
@@ -53,7 +53,7 @@ class RobotMemoryThread
   public fawkes::AspectProviderAspect
 {
  public:
-  RobotMemoryThread();
+  RobotMemoryThread(std::string mongo_client_connection);
   virtual ~RobotMemoryThread();
 
   virtual void init();

- *commit* 65bf4bca135a067270031d4a3a598524101f1f18 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Sep 21 19:48:29 2016 +0200
Subject: utils: string_conversions: resolve ~ in path

 src/libs/utils/misc/string_conversions.cpp |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/libs/utils/misc/string_conversions.cpp b/src/libs/utils/misc/string_conversions.cpp
index f3bac1d..7cf194c 100644
--- a/src/libs/utils/misc/string_conversions.cpp
+++ b/src/libs/utils/misc/string_conversions.cpp
@@ -289,6 +289,7 @@ StringConversions::resolve_path(std::string s)
   resolve_map["@CONFDIR@"] = CONFDIR;
   resolve_map["@SRCDIR@"] = SRCDIR;
   resolve_map["@FAWKES_BASEDIR@"] = FAWKES_BASEDIR;
+  resolve_map["~"] = getenv("HOME");
   std::string res = s;
   for(std::map<std::string, std::string>::iterator it = resolve_map.begin(); it != resolve_map.end(); it++)
   {

- *commit* 003b16f4f89d974735dac0ce80be9a5514cad249 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Sep 21 19:48:59 2016 +0200
Subject: robot-memory: setup config server for distributed robot memory

 src/plugins/robot-memory/robot_memory_setup.cpp |   44 ++++++++++++++++++++---
 src/plugins/robot-memory/robot_memory_setup.h   |    3 +-
 2 files changed, 41 insertions(+), 6 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index dd56a12..49fffb1 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -20,8 +20,10 @@
  */
 
 #include "robot_memory_setup.h"
+#include <plugin/loader.h>
 #include <mongo/client/dbclient.h>
 #include <mongo/client/init.h>
+#include <utils/misc/string_conversions.h>
 
 using namespace fawkes;
 
@@ -43,17 +45,37 @@ RobotMemorySetup::~RobotMemorySetup()
 void RobotMemorySetup::setup_mongods()
 {
   //start local mongod if necessary
-  unsigned int local_port = config->get_uint("plugins/robot-memory/setup/local/port");
+  unsigned int local_port = config->get_int("plugins/robot-memory/setup/local/port");
   if (!is_mongo_running(local_port))
   {
     const char *argv[] = {"mongod","--port", std::to_string(local_port).c_str(), NULL};
     std::string cmd = command_args_tostring(argv);
-    //logger->log_debug("RobotMemorySetup", "Port: '%s'", std::to_string(local_port).c_str());
     logger->log_info("RobotMemorySetup", "Starting local mongod process: '%s'", cmd.c_str());
     local_mongod = new SubProcess("mongod-local", "mongod", argv, NULL, logger);
     logger->log_info("RobotMemorySetup", "Started local mongod");
     wait_until_started(local_port, cmd);
   }
+
+  //only start other processes when we want to run the robot memory distributed
+  if(!config->get_bool("plugins/robot-memory/setup/distributed"))
+    return;
+
+  unsigned int config_port = config->get_int("plugins/robot-memory/setup/config/port");
+  if (!is_mongo_running(config_port))
+  {
+    std::string repl_set_name = config->get_string("plugins/robot-memory/setup/config/replica-set-name");
+    std::string db_path = StringConversions::resolve_path(config->get_string("plugins/robot-memory/setup/config/db-path").c_str());
+    const char *argv[] = {"mongod", "--configsvr", "--port", std::to_string(config_port).c_str(),
+        //"--replSet", repl_set_name.c_str(),
+        "--dbpath", db_path.c_str(), NULL};
+    logger->log_info("RobotMemorySetup", "Running on port: %s", std::to_string(config_port));
+    std::string cmd = command_args_tostring(argv);
+    prepare_mongo_db_path(db_path);
+    logger->log_info("RobotMemorySetup", "Starting config mongod process: '%s'", cmd.c_str());
+    config_mongod = new SubProcess("mongod-config", "mongod", argv, NULL, logger);
+    logger->log_info("RobotMemorySetup", "Started config mongod");
+    wait_until_started(config_port, cmd);
+  }
 }
 
 /**
@@ -64,8 +86,12 @@ void RobotMemorySetup::shutdown_mongods()
 {
   if (local_mongod)
     delete local_mongod;
-
-  //TODO:remember and shutdown Subprocesses
+  if (config_mongod)
+    delete config_mongod;
+  if (distribuded_mongod)
+    delete distribuded_mongod;
+  if (mongos)
+    delete mongos;
 }
 
 /**
@@ -118,5 +144,13 @@ void RobotMemorySetup::wait_until_started(unsigned int port, std::string cmd, in
       return;
     usleep(wait_step);
   }
-  logger->log_error("RobotMemorySetup", "MongoDB did not starup in the given time. Please start '%s' manually once.", cmd.c_str());
+  std::string err_msg = "MongoDB did not starup in the given time. Please start '"
+      +cmd+"' manually once.";
+  throw PluginLoadException("robot-memory", err_msg.c_str());
+}
+
+void RobotMemorySetup::prepare_mongo_db_path(std::string path)
+{
+  std::string command = "mkdir -p " + path;
+  popen(command.c_str(), "r");
 }
diff --git a/src/plugins/robot-memory/robot_memory_setup.h b/src/plugins/robot-memory/robot_memory_setup.h
index 248b93e..c3bf1ea 100644
--- a/src/plugins/robot-memory/robot_memory_setup.h
+++ b/src/plugins/robot-memory/robot_memory_setup.h
@@ -45,7 +45,8 @@ class RobotMemorySetup
     fawkes::Logger *logger;
 
     bool is_mongo_running(unsigned int port);
-    void wait_until_started(unsigned int port, std::string cmd, int timout = 10000000);
+    void wait_until_started(unsigned int port, std::string cmd, int timout = 15000000);
+    void prepare_mongo_db_path(std::string path);
 
     fawkes::SubProcess *local_mongod;
     fawkes::SubProcess *config_mongod;

- *commit* 39a0f2cdb2c94402d19972396dd734104374538b - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Sep 22 20:01:32 2016 +0200
Subject: robot-memory: setup replicaset and mongos process

 src/plugins/robot-memory/robot_memory_setup.cpp |   69 ++++++++++++++---------
 src/plugins/robot-memory/robot_memory_setup.h   |    1 +
 2 files changed, 44 insertions(+), 26 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index 49fffb1..1b78571 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -45,37 +45,54 @@ RobotMemorySetup::~RobotMemorySetup()
 void RobotMemorySetup::setup_mongods()
 {
   //start local mongod if necessary
-  unsigned int local_port = config->get_int("plugins/robot-memory/setup/local/port");
-  if (!is_mongo_running(local_port))
-  {
-    const char *argv[] = {"mongod","--port", std::to_string(local_port).c_str(), NULL};
-    std::string cmd = command_args_tostring(argv);
-    logger->log_info("RobotMemorySetup", "Starting local mongod process: '%s'", cmd.c_str());
-    local_mongod = new SubProcess("mongod-local", "mongod", argv, NULL, logger);
-    logger->log_info("RobotMemorySetup", "Started local mongod");
-    wait_until_started(local_port, cmd);
-  }
+  unsigned int local_port = config->get_uint("plugins/robot-memory/setup/local/port");
+  std::string local_port_str = std::to_string(local_port);
+  const char *local_argv[] = {"mongod", "--port", local_port_str.c_str(), NULL};
+  start_mongo_process("mongod-local", local_port, local_argv);
 
   //only start other processes when we want to run the robot memory distributed
   if(!config->get_bool("plugins/robot-memory/setup/distributed"))
     return;
 
-  unsigned int config_port = config->get_int("plugins/robot-memory/setup/config/port");
-  if (!is_mongo_running(config_port))
-  {
-    std::string repl_set_name = config->get_string("plugins/robot-memory/setup/config/replica-set-name");
-    std::string db_path = StringConversions::resolve_path(config->get_string("plugins/robot-memory/setup/config/db-path").c_str());
-    const char *argv[] = {"mongod", "--configsvr", "--port", std::to_string(config_port).c_str(),
-        //"--replSet", repl_set_name.c_str(),
-        "--dbpath", db_path.c_str(), NULL};
-    logger->log_info("RobotMemorySetup", "Running on port: %s", std::to_string(config_port));
-    std::string cmd = command_args_tostring(argv);
-    prepare_mongo_db_path(db_path);
-    logger->log_info("RobotMemorySetup", "Starting config mongod process: '%s'", cmd.c_str());
-    config_mongod = new SubProcess("mongod-config", "mongod", argv, NULL, logger);
-    logger->log_info("RobotMemorySetup", "Started config mongod");
-    wait_until_started(config_port, cmd);
-  }
+  unsigned int config_port = config->get_uint("plugins/robot-memory/setup/config/port");
+  std::string db_path = StringConversions::resolve_path(config->get_string("plugins/robot-memory/setup/config/db-path").c_str());
+  prepare_mongo_db_path(db_path);
+  std::string config_port_str = std::to_string(config_port);
+  const char *config_argv[] = {"mongod", "--configsvr", "--port",
+      config_port_str.c_str(), "--dbpath", db_path.c_str(), NULL};
+  start_mongo_process("mongod-config", config_port, config_argv);
+
+  unsigned int distributed_port = config->get_uint("plugins/robot-memory/setup/replicated/port");
+  std::string distributed_db_path = StringConversions::resolve_path(config->get_string("plugins/robot-memory/setup/replicated/db-path").c_str());
+  prepare_mongo_db_path(distributed_db_path);
+  std::string distributed_port_str = std::to_string(distributed_port);
+  std::string distributed_replset = config->get_string("plugins/robot-memory/setup/replicated/replica-set-name");
+  const char *distributed_argv[] = {"mongod", "--port", distributed_port_str.c_str(),
+      "--dbpath", distributed_db_path.c_str(),
+      "--replSet", distributed_replset.c_str(),NULL};
+  start_mongo_process("mongod-replicated", distributed_port, distributed_argv);
+
+  unsigned int mongos_port = config->get_uint("plugins/robot-memory/setup/mongos/port");
+  std::string mongos_port_str = std::to_string(mongos_port);
+  std::string confighost = "localhost:" + config_port_str;
+  const char *mongos_argv[] = {"mongos", "--port", mongos_port_str.c_str(),
+      "--configdb", confighost.c_str(), NULL};
+  start_mongo_process("mongos", mongos_port, mongos_argv);
+}
+
+/**
+ * Start a single mongo process
+ */
+void RobotMemorySetup::start_mongo_process(std::string proc_name, unsigned int port, const char *argv[])
+{
+  if (!is_mongo_running(port))
+    {
+      std::string cmd = command_args_tostring(argv);
+      logger->log_info("RobotMemorySetup", "Starting %s process: '%s'", proc_name.c_str(), cmd.c_str());
+      config_mongod = new SubProcess(proc_name.c_str(), argv[0], argv, NULL, logger);
+      logger->log_info("RobotMemorySetup", "Started %s", proc_name.c_str());
+      wait_until_started(port, cmd);
+    }
 }
 
 /**
diff --git a/src/plugins/robot-memory/robot_memory_setup.h b/src/plugins/robot-memory/robot_memory_setup.h
index c3bf1ea..d4d0196 100644
--- a/src/plugins/robot-memory/robot_memory_setup.h
+++ b/src/plugins/robot-memory/robot_memory_setup.h
@@ -47,6 +47,7 @@ class RobotMemorySetup
     bool is_mongo_running(unsigned int port);
     void wait_until_started(unsigned int port, std::string cmd, int timout = 15000000);
     void prepare_mongo_db_path(std::string path);
+    void start_mongo_process(std::string proc_name, unsigned int port, const char *argv[]);
 
     fawkes::SubProcess *local_mongod;
     fawkes::SubProcess *config_mongod;

- *commit* 985a882afcf73c6caa52bbda741d7d8ec2367d03 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Sep 23 19:16:30 2016 +0200
Subject: clips-robot-memory: add remove function

 .../clips_robot_memory_thread.cpp                  |   15 ++++++++++++++-
 .../clips-robot-memory/clips_robot_memory_thread.h |    1 +
 2 files changed, 15 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
index 7b5c589..eebe069 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
@@ -78,6 +78,7 @@ ClipsRobotMemoryThread::clips_context_init(const std::string &env_name,
   clips->add_function("robmem-update", sigc::slot<void, std::string, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_update)));
   clips->add_function("robmem-replace", sigc::slot<void, std::string, void *, CLIPS::Value>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_replace)));
   clips->add_function("robmem-query", sigc::slot<CLIPS::Value, std::string, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_query)));
+  clips->add_function("robmem-remove", sigc::slot<void, std::string, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_remove)));
   clips->add_function("robmem-query-sort", sigc::slot<CLIPS::Value, std::string, void *, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_query_sort)));
   clips->add_function("robmem-cursor-destroy", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_cursor_destroy)));
   clips->add_function("robmem-cursor-more", sigc::slot<CLIPS::Value, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_cursor_more)));
@@ -411,7 +412,7 @@ ClipsRobotMemoryThread::clips_robotmemory_query_sort(std::string collection, voi
     return CLIPS::Value(new std::unique_ptr<mongo::DBClientCursor>(std::move(c)),
                         CLIPS::TYPE_EXTERNAL_ADDRESS);
 #else
-    std::auto_ptr<mongo::DBClientCursor> c = mongodb_->query(collection, q);
+    std::auto_ptr<mongo::DBClientCursor> c = robot_memory->query(collection, q);
 
     return CLIPS::Value(new std::auto_ptr<mongo::DBClientCursor>(c),
                         CLIPS::TYPE_EXTERNAL_ADDRESS);
@@ -423,6 +424,18 @@ ClipsRobotMemoryThread::clips_robotmemory_query_sort(std::string collection, voi
   }
 }
 
+void
+ClipsRobotMemoryThread::clips_robotmemory_remove(std::string collection, void *bson)
+{
+  mongo::BSONObjBuilder *b = static_cast<mongo::BSONObjBuilder *>(bson);
+  try {
+    mongo::Query q(b->asTempObj());
+    robot_memory->remove(q, collection);
+  } catch (mongo::DBException &e) {
+    logger->log_warn("MongoDB", "Remove failed: %s", e.what());
+  }
+}
+
 CLIPS::Value
 ClipsRobotMemoryThread::clips_robotmemory_query(std::string collection, void *bson)
 {
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.h b/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
index 6b43d48..31f9c87 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
@@ -83,6 +83,7 @@ class ClipsRobotMemoryThread
                                CLIPS::Value &query, bool upsert);
   CLIPS::Value  clips_robotmemory_query_sort(std::string collection, void *bson, void *bson_sort);
   CLIPS::Value  clips_robotmemory_query(std::string collection, void *bson);
+  void          clips_robotmemory_remove(std::string collection, void *bson);
   CLIPS::Value  clips_robotmemory_cursor_more(void *cursor);
   CLIPS::Value  clips_robotmemory_cursor_next(void *cursor);
   void          clips_robotmemory_cursor_destroy(void *cursor);

- *commit* b21f756c17b4cf0cc488f91faf48390f56c31d46 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Sep 28 13:06:57 2016 +0200
Subject: robot-memory: config sharded cluster automatically

 src/plugins/robot-memory/robot_memory_setup.cpp |   31 +++++++++++++++++++++++
 src/plugins/robot-memory/robot_memory_setup.h   |    1 +
 2 files changed, 32 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index 1b78571..6b45bf4 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -54,6 +54,7 @@ void RobotMemorySetup::setup_mongods()
   if(!config->get_bool("plugins/robot-memory/setup/distributed"))
     return;
 
+  //start config server
   unsigned int config_port = config->get_uint("plugins/robot-memory/setup/config/port");
   std::string db_path = StringConversions::resolve_path(config->get_string("plugins/robot-memory/setup/config/db-path").c_str());
   prepare_mongo_db_path(db_path);
@@ -62,6 +63,7 @@ void RobotMemorySetup::setup_mongods()
       config_port_str.c_str(), "--dbpath", db_path.c_str(), NULL};
   start_mongo_process("mongod-config", config_port, config_argv);
 
+  //start own part of replica set
   unsigned int distributed_port = config->get_uint("plugins/robot-memory/setup/replicated/port");
   std::string distributed_db_path = StringConversions::resolve_path(config->get_string("plugins/robot-memory/setup/replicated/db-path").c_str());
   prepare_mongo_db_path(distributed_db_path);
@@ -72,12 +74,23 @@ void RobotMemorySetup::setup_mongods()
       "--replSet", distributed_replset.c_str(),NULL};
   start_mongo_process("mongod-replicated", distributed_port, distributed_argv);
 
+  //configure replica set
+  std::string repl_config = "{_id:'" + distributed_replset + "', members:"
+      + config->get_string("plugins/robot-memory/setup/replicated/replica-set-members") + "}";
+  run_mongo_command(distributed_port, std::string("{replSetInitiate:" + repl_config + "}"));
+
+  //start mongos for accessing
   unsigned int mongos_port = config->get_uint("plugins/robot-memory/setup/mongos/port");
   std::string mongos_port_str = std::to_string(mongos_port);
   std::string confighost = "localhost:" + config_port_str;
   const char *mongos_argv[] = {"mongos", "--port", mongos_port_str.c_str(),
       "--configdb", confighost.c_str(), NULL};
   start_mongo_process("mongos", mongos_port, mongos_argv);
+
+  //configure mongos (add parts of the sharded cluster)
+  run_mongo_command(mongos_port, std::string("{addShard: 'localhost:" + local_port_str + "'}"), "host already used");
+  run_mongo_command(mongos_port, std::string("{addShard: '" + distributed_replset +
+    "/localhost:" + distributed_port_str + "'}"), "host already used");
 }
 
 /**
@@ -171,3 +184,21 @@ void RobotMemorySetup::prepare_mongo_db_path(std::string path)
   std::string command = "mkdir -p " + path;
   popen(command.c_str(), "r");
 }
+
+void RobotMemorySetup::run_mongo_command(unsigned int port, std::string command,
+  std::string err_msg_to_ignore)
+{
+  std::string errmsg;
+  mongo::DBClientConnection con(false);
+  bool could_connect = con.connect(std::string("localhost:" + std::to_string(port)), errmsg);
+  if(!could_connect)
+  {
+    std::string err_msg = "Could not connect to mongo process to execute command: "+ errmsg;
+    throw PluginLoadException("robot-memory", err_msg.c_str());
+  }
+  mongo::BSONObj res;
+  logger->log_info("RobotMemorySetup", "Executing db command: %s", command.c_str());
+  con.runCommand("admin", mongo::fromjson(command), res);
+  if(res.getField("ok").Double() == 0.0 && res.getField("errmsg").String().compare(err_msg_to_ignore) != 0)
+    throw PluginLoadException("robot-memory", std::string("Running DB command " + command + " failed: " + res.toString()).c_str());
+}
diff --git a/src/plugins/robot-memory/robot_memory_setup.h b/src/plugins/robot-memory/robot_memory_setup.h
index d4d0196..06987ed 100644
--- a/src/plugins/robot-memory/robot_memory_setup.h
+++ b/src/plugins/robot-memory/robot_memory_setup.h
@@ -48,6 +48,7 @@ class RobotMemorySetup
     void wait_until_started(unsigned int port, std::string cmd, int timout = 15000000);
     void prepare_mongo_db_path(std::string path);
     void start_mongo_process(std::string proc_name, unsigned int port, const char *argv[]);
+    void run_mongo_command(unsigned int port, std::string command, std::string err_msg_to_ignore="");
 
     fawkes::SubProcess *local_mongod;
     fawkes::SubProcess *config_mongod;

- *commit* d70a2682b9905c89500abcd65b1df2dc30382138 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Sep 28 14:51:15 2016 +0200
Subject: robot-memory: set read preference 'nearest' to read locally

 src/plugins/robot-memory/robot_memory.cpp       |    3 +++
 src/plugins/robot-memory/robot_memory_setup.cpp |    8 +++++---
 2 files changed, 8 insertions(+), 3 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index dce9510..23c4b43 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -105,6 +105,9 @@ QResCursor RobotMemory::query(Query query, std::string collection)
 //    gen_blackboard_data(query.getFilter()["bbinterface"].String());
 //  }
 
+  //set read preference of query to nearest to read from the local replica set member first
+  query.readPref(ReadPreference_Nearest, BSONArray());
+
   //actually execute query
   QResCursor cursor;
   try{
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index 6b45bf4..0968af9 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -77,7 +77,9 @@ void RobotMemorySetup::setup_mongods()
   //configure replica set
   std::string repl_config = "{_id:'" + distributed_replset + "', members:"
       + config->get_string("plugins/robot-memory/setup/replicated/replica-set-members") + "}";
-  run_mongo_command(distributed_port, std::string("{replSetInitiate:" + repl_config + "}"));
+  run_mongo_command(distributed_port, std::string("{replSetInitiate:" + repl_config + "}"), "already initialized");
+  //wait for replica set initialization and election
+  usleep(1000000);
 
   //start mongos for accessing
   unsigned int mongos_port = config->get_uint("plugins/robot-memory/setup/mongos/port");
@@ -199,6 +201,6 @@ void RobotMemorySetup::run_mongo_command(unsigned int port, std::string command,
   mongo::BSONObj res;
   logger->log_info("RobotMemorySetup", "Executing db command: %s", command.c_str());
   con.runCommand("admin", mongo::fromjson(command), res);
-  if(res.getField("ok").Double() == 0.0 && res.getField("errmsg").String().compare(err_msg_to_ignore) != 0)
-    throw PluginLoadException("robot-memory", std::string("Running DB command " + command + " failed: " + res.toString()).c_str());
+//  if(res.getField("ok").Double() == 0.0 && res.getField("errmsg").String().compare(err_msg_to_ignore) != 0)
+//    throw PluginLoadException("robot-memory", std::string("Running DB command " + command + " failed: " + res.toString()).c_str());
 }

- *commit* 3d0bc35f212aa0515350fa242d92efa64cb310c4 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Sep 28 14:53:39 2016 +0200
Subject: robot-memory-test: use simulated replica set in tests

 src/tools/gtest/gtest_fawkes.cpp |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

_Diff for modified files_:
diff --git a/src/tools/gtest/gtest_fawkes.cpp b/src/tools/gtest/gtest_fawkes.cpp
index 390ec1f..6c89db3 100644
--- a/src/tools/gtest/gtest_fawkes.cpp
+++ b/src/tools/gtest/gtest_fawkes.cpp
@@ -45,15 +45,19 @@ int main(int argc, char **argv) {
 
     //init arguments to start fawkes with
     char **fawkes_argv;
-    fawkes_argv = new char*[3];
+    fawkes_argv = new char*[5];
     fawkes_argv[0] = new char[6];
     strcpy(fawkes_argv[0], "fawkes");
     fawkes_argv[1] = new char[2];
     strcpy(fawkes_argv[1], "-p");
     fawkes_argv[2] = new char[128];
     strcpy(fawkes_argv[2], "m-robot-memory,robot_memory_test");
+    fawkes_argv[3] = new char[2];
+    strcpy(fawkes_argv[3], "-c");
+    fawkes_argv[4] = new char[128];
+    strcpy(fawkes_argv[4], "gazsim-configurations/default/robotino1.yaml");
 
-    if (! fawkes::runtime::init(3, fawkes_argv, retval)) {
+    if (! fawkes::runtime::init(5, fawkes_argv, retval)) {
       return retval;
     }
     fawkes::runtime::run();

- *commit* e2d046ba7e35f92777df7f30135fb3b96f93dd1a - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Sep 28 15:47:38 2016 +0200
Subject: robot-memory: made setup robust against missing db+shards already added

 src/plugins/robot-memory/robot_memory_setup.cpp |   20 +++++++++++++-------
 src/plugins/robot-memory/robot_memory_setup.h   |    3 ++-
 2 files changed, 15 insertions(+), 8 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index 0968af9..ec4d27b 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -79,7 +79,8 @@ void RobotMemorySetup::setup_mongods()
       + config->get_string("plugins/robot-memory/setup/replicated/replica-set-members") + "}";
   run_mongo_command(distributed_port, std::string("{replSetInitiate:" + repl_config + "}"), "already initialized");
   //wait for replica set initialization and election
-  usleep(1000000);
+  usleep(3000000);
+  run_mongo_command(distributed_port, std::string("{create: '" + distributed_replset + ".config'}"), "collection already exists");
 
   //start mongos for accessing
   unsigned int mongos_port = config->get_uint("plugins/robot-memory/setup/mongos/port");
@@ -90,9 +91,13 @@ void RobotMemorySetup::setup_mongods()
   start_mongo_process("mongos", mongos_port, mongos_argv);
 
   //configure mongos (add parts of the sharded cluster)
-  run_mongo_command(mongos_port, std::string("{addShard: 'localhost:" + local_port_str + "'}"), "host already used");
-  run_mongo_command(mongos_port, std::string("{addShard: '" + distributed_replset +
-    "/localhost:" + distributed_port_str + "'}"), "host already used");
+  mongo::BSONObj current_shards =  run_mongo_command(mongos_port, std::string("{listShards:1}"));
+  if(current_shards.getField("shards").Array().size() == 0)
+  {
+    run_mongo_command(mongos_port, std::string("{addShard: 'localhost:" + local_port_str + "'}"), "host already used");
+    run_mongo_command(mongos_port, std::string("{addShard: '" + distributed_replset +
+      "/localhost:" + distributed_port_str + "'}"), "host already used");
+  }
 }
 
 /**
@@ -187,7 +192,7 @@ void RobotMemorySetup::prepare_mongo_db_path(std::string path)
   popen(command.c_str(), "r");
 }
 
-void RobotMemorySetup::run_mongo_command(unsigned int port, std::string command,
+mongo::BSONObj RobotMemorySetup::run_mongo_command(unsigned int port, std::string command,
   std::string err_msg_to_ignore)
 {
   std::string errmsg;
@@ -201,6 +206,7 @@ void RobotMemorySetup::run_mongo_command(unsigned int port, std::string command,
   mongo::BSONObj res;
   logger->log_info("RobotMemorySetup", "Executing db command: %s", command.c_str());
   con.runCommand("admin", mongo::fromjson(command), res);
-//  if(res.getField("ok").Double() == 0.0 && res.getField("errmsg").String().compare(err_msg_to_ignore) != 0)
-//    throw PluginLoadException("robot-memory", std::string("Running DB command " + command + " failed: " + res.toString()).c_str());
+  if(res.getField("ok").Double() == 0.0 && res.getField("errmsg").String().compare(err_msg_to_ignore) != 0)
+    throw PluginLoadException("robot-memory", std::string("Running DB command " + command + " failed: " + res.toString()).c_str());
+  return res;
 }
diff --git a/src/plugins/robot-memory/robot_memory_setup.h b/src/plugins/robot-memory/robot_memory_setup.h
index 06987ed..1764c4d 100644
--- a/src/plugins/robot-memory/robot_memory_setup.h
+++ b/src/plugins/robot-memory/robot_memory_setup.h
@@ -26,6 +26,7 @@
 #include <logging/logger.h>
 #include <utils/sub_process/proc.h>
 #include <utils/misc/string_commands.h>
+#include <mongo/client/dbclient.h>
 
 /** @class RobotMemorySetup  robot_memory_setup.h
  *
@@ -48,7 +49,7 @@ class RobotMemorySetup
     void wait_until_started(unsigned int port, std::string cmd, int timout = 15000000);
     void prepare_mongo_db_path(std::string path);
     void start_mongo_process(std::string proc_name, unsigned int port, const char *argv[]);
-    void run_mongo_command(unsigned int port, std::string command, std::string err_msg_to_ignore="");
+    mongo::BSONObj run_mongo_command(unsigned int port, std::string command, std::string err_msg_to_ignore="");
 
     fawkes::SubProcess *local_mongod;
     fawkes::SubProcess *config_mongod;

- *commit* d04d59de3cfa0439cc5fd9159f1e5a83e3420ee3 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Sep 28 16:18:59 2016 +0200
Subject: robot-memory: use default db name when modified for simulation

 src/plugins/robot-memory/robot_memory.cpp |   33 ++++++++++++++++++----------
 src/plugins/robot-memory/robot_memory.h   |    2 +
 2 files changed, 23 insertions(+), 12 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 23c4b43..5fba663 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -81,8 +81,7 @@ void RobotMemory::init()
 
 QResCursor RobotMemory::query(Query query, std::string collection)
 {
-  if(collection == "")
-    collection = default_collection_;
+  check_collection_name(collection);
   log_deb(std::string("Executing Query "+ query.toString() +" on collection "+collection));
 
   //only one query at a time
@@ -123,8 +122,7 @@ QResCursor RobotMemory::query(Query query, std::string collection)
 
 int RobotMemory::insert(BSONObj obj, std::string collection)
 {
-  if(collection == "")
-    collection = default_collection_;
+  check_collection_name(collection);
 
   log_deb(std::string("Executing Query "+ obj.toString() + " on collection " + collection));
 
@@ -151,10 +149,7 @@ int RobotMemory::insert(std::string obj_str, std::string collection)
 
 int RobotMemory::update(Query query, BSONObj update, std::string collection, bool upsert)
 {
-  if(collection == "")
-  {
-    collection = default_collection_;
-  }
+  check_collection_name(collection);
   log_deb(std::string("Executing Update "+update.toString()+" for query "+query.toString()+" on collection "+ collection));
 
   //only one query at a time
@@ -178,10 +173,7 @@ int RobotMemory::update(Query query, std::string update_str, std::string collect
 
 int RobotMemory::remove(Query query, std::string collection)
 {
-  if(collection == "")
-  {
-    collection = default_collection_;
-  }
+  check_collection_name(collection);
   log_deb(std::string("Executing Remove "+query.toString()+" on collection "+collection));
 
   //only one query at a time
@@ -399,3 +391,20 @@ RobotMemory::remove_field(Query &q, std::string what)
   //override
   q = Query(b.obj());
 }
+
+/**
+ * Check if collection name is valid and correct it if necessary
+ */
+void
+RobotMemory::check_collection_name(std::string &collection)
+{
+  if(collection == "")
+  {
+      collection = default_collection_;
+  }
+  else if(default_collection_ != "robmem" && collection.find("robmem.") == 1)
+  {
+    //change used database name (e.g. for the case of multiple simulated dababases)
+    collection.replace(0, 6, default_collection_);
+  }
+}
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 2ad892b..4de84fd 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -89,6 +89,8 @@ class RobotMemory
     void set_fields(mongo::BSONObj &obj, std::string what);
     void set_fields(mongo::Query &q, std::string what);
     void remove_field(mongo::Query &q, std::string what);
+
+    void check_collection_name(std::string &collection);
 };
 
 #endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_ROBOT_MEMORY_H_ */

- *commit* 8bfca895b1f774152fc9e46461cfa4ed3b728642 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Sep 28 18:35:30 2016 +0200
Subject: robot-memory: added dependencies in plugins/Makefile

 src/plugins/Makefile |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/Makefile b/src/plugins/Makefile
index bde3bfe..a1abd75 100644
--- a/src/plugins/Makefile
+++ b/src/plugins/Makefile
@@ -39,10 +39,11 @@ katana jaco: openrave
 amcl colli navgraph perception robotino: ros
 mongodb_log: mongodb
 mongodb: rrd
-clips-navgraph clips-agent clips-protobuf clips-tf: clips
+clips-navgraph clips-agent clips-protobuf clips-tf clips-robot-memory: clips
 clips-navgraph navgraph-clusters: navgraph
 clips-webview: clips webview
 clips-ros: clips ros
+clips-robot-memory: robot-memory
 gazebo: robotino
 skiller: navgraph
 perception: mongodb

- *commit* 5a3683b3ec6b083c43c06b057cfdceb5b9be8bd2 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Sep 29 16:23:16 2016 +0200
Subject: utils: fixed makefile to create lua/fawkesutils after new requirements

 src/libs/utils/Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/libs/utils/Makefile b/src/libs/utils/Makefile
index 12da36a..abb419d 100644
--- a/src/libs/utils/Makefile
+++ b/src/libs/utils/Makefile
@@ -52,7 +52,7 @@ ifeq ($(HAVE_TOLUA)$(HAVE_CPP11)$(HAVE_BOOST_LIBS),111)
   LIBS_all += $(LUALIBDIR)/fawkesutils.so
   LDFLAGS += $(call boost-libs-ldflags,$(REQ_BOOST_LIBS))
 
-  LIBS_all  = $(LIBDIR)/libfawkesutils.so
+  LIBS_all  += $(LIBDIR)/libfawkesutils.so
   TARGETS_all += $(SRCDIR)/fawkesutils_tolua.cpp
 else
   ifneq ($(HAVE_CPP11),1)

- *commit* 1c6c8442522bc5702596ed309333eff17011ae2e - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Sep 29 20:22:42 2016 +0200
Subject: robot-memory: create dbs and assing them to shards

 src/plugins/robot-memory/robot_memory_setup.cpp |   28 +++++++++++++++++++++-
 src/plugins/robot-memory/robot_memory_setup.h   |    1 +
 2 files changed, 27 insertions(+), 2 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index ec4d27b..e983d5f 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -46,6 +46,7 @@ void RobotMemorySetup::setup_mongods()
 {
   //start local mongod if necessary
   unsigned int local_port = config->get_uint("plugins/robot-memory/setup/local/port");
+  std::string local_db_name = config->get_string("plugins/robot-memory/database");
   std::string local_port_str = std::to_string(local_port);
   const char *local_argv[] = {"mongod", "--port", local_port_str.c_str(), NULL};
   start_mongo_process("mongod-local", local_port, local_argv);
@@ -62,6 +63,7 @@ void RobotMemorySetup::setup_mongods()
   const char *config_argv[] = {"mongod", "--configsvr", "--port",
       config_port_str.c_str(), "--dbpath", db_path.c_str(), NULL};
   start_mongo_process("mongod-config", config_port, config_argv);
+  create_database(local_port, local_db_name);
 
   //start own part of replica set
   unsigned int distributed_port = config->get_uint("plugins/robot-memory/setup/replicated/port");
@@ -80,7 +82,7 @@ void RobotMemorySetup::setup_mongods()
   run_mongo_command(distributed_port, std::string("{replSetInitiate:" + repl_config + "}"), "already initialized");
   //wait for replica set initialization and election
   usleep(3000000);
-  run_mongo_command(distributed_port, std::string("{create: '" + distributed_replset + ".config'}"), "collection already exists");
+  create_database(distributed_port, distributed_replset);
 
   //start mongos for accessing
   unsigned int mongos_port = config->get_uint("plugins/robot-memory/setup/mongos/port");
@@ -98,6 +100,9 @@ void RobotMemorySetup::setup_mongods()
     run_mongo_command(mongos_port, std::string("{addShard: '" + distributed_replset +
       "/localhost:" + distributed_port_str + "'}"), "host already used");
   }
+  //define which db is in which shard
+  run_mongo_command(mongos_port, std::string("{movePrimary: '" + distributed_replset + "', to: '" + distributed_replset + "'}"), "it is already the primary");
+  run_mongo_command(mongos_port, std::string("{movePrimary: '" + local_db_name + "', to: 'shard0000'}"), "it is already the primary");
 }
 
 /**
@@ -206,7 +211,26 @@ mongo::BSONObj RobotMemorySetup::run_mongo_command(unsigned int port, std::strin
   mongo::BSONObj res;
   logger->log_info("RobotMemorySetup", "Executing db command: %s", command.c_str());
   con.runCommand("admin", mongo::fromjson(command), res);
-  if(res.getField("ok").Double() == 0.0 && res.getField("errmsg").String().compare(err_msg_to_ignore) != 0)
+  con.reset();
+  if(res.getField("ok").type() != mongo::BSONType::NumberDouble || (res.getField("ok").Double() == 0.0 && res.getField("errmsg").String().compare(err_msg_to_ignore) != 0))
     throw PluginLoadException("robot-memory", std::string("Running DB command " + command + " failed: " + res.toString()).c_str());
   return res;
 }
+
+void RobotMemorySetup::create_database(unsigned int port, std::string name)
+{
+  //to create a database you have to insert at least one document
+  std::string errmsg;
+  mongo::DBClientConnection con(false);
+  bool could_connect = con.connect(std::string("localhost:" + std::to_string(port)), errmsg);
+  if(!could_connect)
+  {
+    std::string err_msg = "Could not connect to mongo process to execute command: "+ errmsg;
+    throw PluginLoadException("robot-memory", err_msg.c_str());
+  }
+  mongo::BSONObj first_doc = mongo::fromjson("{initialized:1}");
+  con.insert(name + ".config", first_doc);
+  con.reset();
+
+
+}
diff --git a/src/plugins/robot-memory/robot_memory_setup.h b/src/plugins/robot-memory/robot_memory_setup.h
index 1764c4d..300e9a7 100644
--- a/src/plugins/robot-memory/robot_memory_setup.h
+++ b/src/plugins/robot-memory/robot_memory_setup.h
@@ -50,6 +50,7 @@ class RobotMemorySetup
     void prepare_mongo_db_path(std::string path);
     void start_mongo_process(std::string proc_name, unsigned int port, const char *argv[]);
     mongo::BSONObj run_mongo_command(unsigned int port, std::string command, std::string err_msg_to_ignore="");
+    void create_database(unsigned int port, std::string name);
 
     fawkes::SubProcess *local_mongod;
     fawkes::SubProcess *config_mongod;

- *commit* 22cd83f26224a039f9dda901e46a7e986333f582 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 6 18:00:00 2016 +0200
Subject: utils: added libdeamon to makefile to close sockets in SubProcess

 src/libs/utils/Makefile |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/libs/utils/Makefile b/src/libs/utils/Makefile
index abb419d..eb81688 100644
--- a/src/libs/utils/Makefile
+++ b/src/libs/utils/Makefile
@@ -45,6 +45,14 @@ OBJS_lua_fawkesutils = fawkesutils_tolua.o
 CFLAGS  += $(CFLAGS_LIBMAGIC)
 LDFLAGS += $(LDFLAGS_LIBMAGIC)
 
+HAVE_LIBDAEMON = $(if $(shell $(PKGCONFIG) --exists 'libdaemon'; echo $${?/1/}),1,0)
+ifeq ($(HAVE_LIBDAEMON),1)
+  CFLAGS  +=  -DHAVE_LIBDAEMON $(shell $(PKGCONFIG) --cflags 'libdaemon')
+  LDFLAGS += $(shell $(PKGCONFIG) --libs 'libdaemon')
+else
+  WARN_TARGETS += warning_libdaemon
+endif
+
 OBJS_all = $(OBJS_libfawkesutils) $(OBJS_lua_fawkesutils)
 
 ifeq ($(HAVE_TOLUA)$(HAVE_CPP11)$(HAVE_BOOST_LIBS),111)
@@ -81,6 +89,8 @@ warning_cpp11:
 		"(CPP11 not available)"
 $(WARN_TARGETS_BOOST): warning_boost_%:
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Cannot build utils library$(TNORMAL) (Boost library $* not found)"endif
+warning_libdaemon:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Sub-process cannot close all file handles$(TNORMAL) (libdaemon not found)"
 
 endif
 

- *commit* abffeeff1f677d731905824320d475e87a6b20a1 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Mon Oct 3 17:20:38 2016 +0200
Subject: robot-memory: first prototype for event triggers using the oplog

 src/plugins/robot-memory/event_trigger_manager.cpp |   96 ++++++++++++++++++++
 src/plugins/robot-memory/event_trigger_manager.h   |   66 ++++++++++++++
 src/plugins/robot-memory/robot_memory.cpp          |    9 ++
 src/plugins/robot-memory/robot_memory.h            |    3 +
 src/plugins/robot-memory/robot_memory_thread.cpp   |    2 +
 5 files changed, 176 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 5fba663..cd14986 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -51,6 +51,7 @@ RobotMemory::RobotMemory(fawkes::Configuration* config, fawkes::Logger* logger,
 RobotMemory::~RobotMemory()
 {
   delete mutex_;
+  delete trigger_manager_;
   blackboard_->close(rm_if_);
 }
 
@@ -76,9 +77,17 @@ void RobotMemory::init()
   rm_if_->set_result("");
   rm_if_->write();
 
+  //Setup event trigger manager
+  trigger_manager_ = new EventTriggerManager(logger_, config_);
+
   log_deb("Initialized RobotMemory");
 }
 
+void RobotMemory::loop()
+{
+  trigger_manager_->check_events();
+}
+
 QResCursor RobotMemory::query(Query query, std::string collection)
 {
   check_collection_name(collection);
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 4de84fd..3417f74 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -29,6 +29,7 @@
 
 #include <mongo/client/dbclient.h>
 #include "interfaces/RobotMemoryInterface.h"
+#include "event_trigger_manager.h"
 
 namespace fawkes {
   class Mutex;
@@ -76,8 +77,10 @@ class RobotMemory
     bool debug_;
     fawkes::Mutex *mutex_;
     fawkes::RobotMemoryInterface* rm_if_;
+    EventTriggerManager* trigger_manager_;
 
     void init();
+    void loop();
 
     void log(std::string what, std::string level = "info");
     void log_deb(std::string what, std::string level = "info");
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 807c55d..5509a14 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -92,5 +92,7 @@ RobotMemoryThread::loop()
 
     robot_memory->rm_if_->msgq_pop();
   }
+
+  robot_memory->loop();
 }
 

- *commit* bbac921ebf1d0c78d00ffcc0a20528b254eaff3a - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 6 11:44:14 2016 +0200
Subject: robot-memory: handling trigger callback functions

 .../robot-memory/event_trigger.cpp}                |   32 ++++------
 src/plugins/robot-memory/event_trigger.h           |   51 +++++++++++++++
 src/plugins/robot-memory/event_trigger_manager.cpp |   66 +++++++++++++++----
 src/plugins/robot-memory/event_trigger_manager.h   |   10 ++-
 src/plugins/robot-memory/robot_memory.cpp          |   18 +++++
 src/plugins/robot-memory/robot_memory.h            |    7 ++-
 6 files changed, 146 insertions(+), 38 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/event_trigger_manager.cpp b/src/plugins/robot-memory/event_trigger_manager.cpp
index 46991b8..21d99f9 100644
--- a/src/plugins/robot-memory/event_trigger_manager.cpp
+++ b/src/plugins/robot-memory/event_trigger_manager.cpp
@@ -21,10 +21,16 @@
 
 #include "event_trigger_manager.h"
 #include <plugin/loader.h>
+#include <boost/bind.hpp>
 
 using namespace fawkes;
 using namespace mongo;
 
+void EventTriggerManager::callback_test(mongo::BSONObj update)
+{
+  logger_->log_info(name.c_str(), "callback: %s", update.toString().c_str());
+}
+
 EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
 {
   logger_ = logger;
@@ -49,39 +55,71 @@ EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
   }
 
   //test setup
-  register_trigger(mongo::fromjson("{}"), "syncedrobmem.test");
+  register_trigger(mongo::fromjson("{test: 0}"), "syncedrobmem.test", &EventTriggerManager::callback_test, this);
 
   logger_->log_info(name.c_str(), "Initialized");
 }
 
 EventTriggerManager::~EventTriggerManager()
 {
+  for(EventTrigger *trigger : triggers)
+    {
+      delete trigger;
+    }
 }
 
 void EventTriggerManager::check_events()
 {
-  while(oplog_cursor->more())
+  for(EventTrigger *trigger : triggers)
   {
-    BSONObj change = oplog_cursor->next();
-    logger_->log_info(name.c_str(), "Oplog has more: %s", change.toString().c_str());
-  }
-  if(oplog_cursor->isDead())
-  {
-    logger_->log_info(name.c_str(), "Tailable Cursor is dead, requerying");
-    oplog_cursor = create_oplog_cursor(con_replica_, "local.oplog.rs", oplog_query);
+    while(trigger->oplog_cursor->more())
+    {
+      BSONObj change = trigger->oplog_cursor->next();
+      //actually call the callback function
+      trigger->callback(change);
+    }
+    if(trigger->oplog_cursor->isDead())
+    {
+      logger_->log_debug(name.c_str(), "Tailable Cursor is dead, requerying");
+      trigger->oplog_cursor = create_oplog_cursor(con_replica_, "local.oplog.rs", trigger->oplog_query);
+    }
   }
 }
 
-void EventTriggerManager::register_trigger(mongo::Query query, std::string collection)
+template<typename T>
+void EventTriggerManager::register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *obj)
 {
   logger_->log_info(name.c_str(), "Registering Trigger");
 
-  oplog_query = query;
+  //construct query for oplog
+  BSONObjBuilder query_builder;
+  query_builder.append("ns", collection);
+  // added/updated object is a subdocument in the oplog document
+  for(BSONObjIterator it = query.getFilter().begin(); it.more();)
+  {
+    BSONElement elem = it.next();
+    query_builder.appendAs(elem, std::string("o.") + elem.fieldName());
+  }
+  mongo::Query oplog_query = query_builder.obj();
   oplog_query.readPref(ReadPreference_Nearest, BSONArray());
-  oplog_collection = collection;
 
-  //TODO: check if collection is local or replicated
-  oplog_cursor = create_oplog_cursor(con_replica_, "local.oplog.rs", oplog_query);
+  //check if collection is local or replicated
+  mongo::DBClientConnection* con;
+  std::string oplog;
+  if(collection.find(repl_set) == 0)
+  {
+    con = con_replica_;
+    oplog = "local.oplog.rs";
+  }
+  else
+  {
+    con = con_local_;
+    oplog = "local.oplog";
+  }
+
+  EventTrigger *trigger = new EventTrigger(oplog_query, collection, boost::bind(callback, obj, _1));
+  trigger->oplog_cursor = create_oplog_cursor(con, oplog, oplog_query);
+  triggers.push_back(trigger);
 }
 
 QResCursor EventTriggerManager::create_oplog_cursor(mongo::DBClientConnection* con, std::string oplog, mongo::Query query)
diff --git a/src/plugins/robot-memory/event_trigger_manager.h b/src/plugins/robot-memory/event_trigger_manager.h
index e1168d8..ab45725 100644
--- a/src/plugins/robot-memory/event_trigger_manager.h
+++ b/src/plugins/robot-memory/event_trigger_manager.h
@@ -25,6 +25,8 @@
 #include <mongo/client/dbclient.h>
 #include <aspect/logging.h>
 #include <aspect/configurable.h>
+#include <list>
+#include "event_trigger.h"
 
 
 ///typedef for shorter type description
@@ -42,11 +44,13 @@ class EventTriggerManager
     EventTriggerManager(fawkes::Logger* logger, fawkes::Configuration* config);
     virtual ~EventTriggerManager();
 
-    void register_trigger(mongo::Query query, std::string collection);
+    template<typename T>
+    void register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
 
   private:
     void check_events();
     QResCursor create_oplog_cursor(mongo::DBClientConnection* con, std::string oplog, mongo::Query query);
+    void callback_test(mongo::BSONObj update);
 
     std::string name = "RobotMemory EventTriggerManager";
     fawkes::Logger* logger_;
@@ -58,9 +62,7 @@ class EventTriggerManager
 
     std::string repl_set, local_db;
 
-    mongo::Query oplog_query;
-    std::string oplog_collection;
-    QResCursor oplog_cursor;
+    std::list<EventTrigger*> triggers;
 };
 
 #endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_ */
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index cd14986..720bacc 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -417,3 +417,21 @@ RobotMemory::check_collection_name(std::string &collection)
     collection.replace(0, 6, default_collection_);
   }
 }
+
+/**
+ * Register a trigger that notifies you when the event specified in the query happens
+ */
+template<typename T>
+void RobotMemory::register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+{
+  trigger_manager_->register_trigger(query, collection, callback, _obj);
+}
+
+/**
+ * Register a trigger that notifies you when the event specified in the query happens
+ */
+template<typename T>
+void RobotMemory::register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+{
+  register_trigger(fromjson(query_str), collection, callback);
+}
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 3417f74..4eabaec 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -39,7 +39,7 @@ namespace fawkes {
 ///typedef for shorter type description
 typedef std::unique_ptr<mongo::DBClientCursor> QResCursor;
 
-/*
+/**
  *
  */
 class RobotMemory
@@ -64,6 +64,11 @@ class RobotMemory
     int restore_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
     int dump_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
 
+    template<typename T>
+    void register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+    template<typename T>
+    void register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+
   private:
     mongo::DBClientBase* mongodb_client_;
     fawkes::Configuration* config_;

- *commit* dd13c1c7e28c8808e6c672b0423d67af512cba03 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 6 18:36:45 2016 +0200
Subject: robot-memory: enable oplog on local mongodb with single replSet

 src/plugins/robot-memory/robot_memory_setup.cpp |   21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index e983d5f..fc4bc29 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -24,6 +24,7 @@
 #include <mongo/client/dbclient.h>
 #include <mongo/client/init.h>
 #include <utils/misc/string_conversions.h>
+#include <stdio.h>
 
 using namespace fawkes;
 
@@ -48,8 +49,14 @@ void RobotMemorySetup::setup_mongods()
   unsigned int local_port = config->get_uint("plugins/robot-memory/setup/local/port");
   std::string local_db_name = config->get_string("plugins/robot-memory/database");
   std::string local_port_str = std::to_string(local_port);
-  const char *local_argv[] = {"mongod", "--port", local_port_str.c_str(), NULL};
+  const char *local_argv[] = {"mongod", "--port", local_port_str.c_str(),
+      "--replSet", "local", NULL}; //'local' replica set to enable the oplog
   start_mongo_process("mongod-local", local_port, local_argv);
+  std::string local_config = "{_id: 'local', members:[{_id:1,host:'localhost:" + local_port_str + "'}]}";
+  run_mongo_command(local_port, std::string("{replSetInitiate:" + local_config + "}"), "already initialized");
+  //wait for initialization
+  usleep(1000000);
+  create_database(local_port, local_db_name);
 
   //only start other processes when we want to run the robot memory distributed
   if(!config->get_bool("plugins/robot-memory/setup/distributed"))
@@ -113,10 +120,10 @@ void RobotMemorySetup::start_mongo_process(std::string proc_name, unsigned int p
   if (!is_mongo_running(port))
     {
       std::string cmd = command_args_tostring(argv);
-      logger->log_info("RobotMemorySetup", "Starting %s process: '%s'", proc_name.c_str(), cmd.c_str());
+      logger->log_error("RobotMemorySetup", "Starting %s process: '%s'", proc_name.c_str(), cmd.c_str());
       config_mongod = new SubProcess(proc_name.c_str(), argv[0], argv, NULL, logger);
       logger->log_info("RobotMemorySetup", "Started %s", proc_name.c_str());
-      wait_until_started(port, cmd);
+      wait_until_started(port, cmd, config->get_int("plugins/robot-memory/setup/max_setup_time"));
     }
 }
 
@@ -126,13 +133,13 @@ void RobotMemorySetup::start_mongo_process(std::string proc_name, unsigned int p
  */
 void RobotMemorySetup::shutdown_mongods()
 {
-  if (local_mongod)
+  if(local_mongod)
     delete local_mongod;
-  if (config_mongod)
+  if(config_mongod)
     delete config_mongod;
-  if (distribuded_mongod)
+  if(distribuded_mongod)
     delete distribuded_mongod;
-  if (mongos)
+  if(mongos)
     delete mongos;
 }
 

- *commit* 93b17b985c3a73ade24c8a5fa3fe2af9194824f8 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 6 18:46:06 2016 +0200
Subject: robot-memory: tests and fixes for event triggers

 src/plugins/robot-memory/Makefile                  |   17 +++++--
 src/plugins/robot-memory/event_trigger_manager.cpp |   52 ++++----------------
 src/plugins/robot-memory/event_trigger_manager.h   |   41 ++++++++++++++-
 src/plugins/robot-memory/robot_memory.cpp          |   17 ++-----
 src/plugins/robot-memory/robot_memory.h            |   28 ++++++++++-
 .../robot-memory/test-plugin/robot_memory_test.cpp |   44 +++++++++++++++++
 .../robot-memory/test-plugin/robot_memory_test.h   |   18 +++++++
 .../test-plugin/robot_memory_test_thread.cpp       |    5 +-
 8 files changed, 156 insertions(+), 66 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/Makefile b/src/plugins/robot-memory/Makefile
index 84453a7..d25debd 100644
--- a/src/plugins/robot-memory/Makefile
+++ b/src/plugins/robot-memory/Makefile
@@ -18,10 +18,14 @@ BASEDIR = ../../..
 include $(BASEDIR)/etc/buildsys/config.mk
 include $(BUILDCONFDIR)/tf/tf.mk
 include $(BASEDIR)/src/plugins/mongodb/mongodb.mk
+include $(BASEDIR)/etc/buildsys/boost.mk
 
 PRESUBDIRS = interfaces aspect
 SUBDIRS = test-plugin
 
+REQ_BOOST_LIBS = bind function
+HAVE_BOOST_LIBS = $(call boost-have-libs,$(REQ_BOOST_LIBS))
+
 LIBS_robot_memory = fawkescore fawkesaspects fawkesblackboard fawkesinterface \
 		fawkesutils fawkeslogging fawkesmongodbaspect fvutils \
 		fawkestf RobotMemoryInterface fawkesrobotmemory
@@ -29,9 +33,9 @@ OBJS_robot_memory = $(patsubst %.cpp,%.o,$(patsubst qa/%,,$(subst $(SRCDIR)/,,$(
 
 OBJS_all    = $(OBJS_robot_memory)
 
-ifeq ($(HAVE_MONGODB)$(HAVE_TF),11)
-  CFLAGS += $(CFLAGS_TF) $(CFLAGS_MONGODB)
-  LDFLAGS += $(LDFLAGS_TF) $(LDFLAGS_MONGODB)
+ifeq ($(HAVE_MONGODB)$(HAVE_TF)$(HAVE_BOOST_LIBS),111)
+  CFLAGS += $(CFLAGS_TF) $(CFLAGS_MONGODB) $(call boost-libs-cflags,$(REQ_BOOST_LIBS))
+  LDFLAGS += $(LDFLAGS_TF) $(LDFLAGS_MONGODB) $(call boost-libs-ldflags,$(REQ_BOOST_LIBS))
   PLUGINS_all = $(PLUGINDIR)/robot-memory.so
 else
   ifneq ($(HAVE_MONGODB),1)
@@ -40,6 +44,9 @@ else
   ifneq ($(HAVE_TF),1)
     WARN_TARGETS += warning_tf
   endif
+  ifneq ($(HAVE_BOOST_LIBS),1)
+    WARN_TARGETS_BOOST = $(foreach l,$(REQ_BOOST_LIBS),$(if $(call boost-have-lib,$l),, warning_boost_$l))
+  endif
 endif
 
 ifeq ($(OBJSSUBMAKE),1)
@@ -49,7 +56,9 @@ all: $(WARN_TARGETS)
 warning_mongodb:
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting RobotMemory Plugin$(TNORMAL) (mongodb[-devel] not installed)"
 warning_tf:
-	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting PCL utility library$(TNORMAL) (tf framework not available)"
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting RobotMemory Plugin$(TNORMAL) (tf framework not available)"
+$(WARN_TARGETS_BOOST): warning_boost_%:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Cannot build RobotMemory Plugin$(TNORMAL) (Boost library $* not found)"endif
 endif
 
 include $(BUILDSYSDIR)/base.mk
diff --git a/src/plugins/robot-memory/event_trigger_manager.cpp b/src/plugins/robot-memory/event_trigger_manager.cpp
index 21d99f9..b2af921 100644
--- a/src/plugins/robot-memory/event_trigger_manager.cpp
+++ b/src/plugins/robot-memory/event_trigger_manager.cpp
@@ -19,6 +19,7 @@
  *  Read the full text in the LICENSE.GPL file in the doc directory.
  */
 
+
 #include "event_trigger_manager.h"
 #include <plugin/loader.h>
 #include <boost/bind.hpp>
@@ -26,11 +27,6 @@
 using namespace fawkes;
 using namespace mongo;
 
-void EventTriggerManager::callback_test(mongo::BSONObj update)
-{
-  logger_->log_info(name.c_str(), "callback: %s", update.toString().c_str());
-}
-
 EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
 {
   logger_ = logger;
@@ -47,16 +43,12 @@ EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
   }
   repl_set = config_->get_string("plugins/robot-memory/setup/replicated/replica-set-name");
   con_replica_ = new mongo::DBClientConnection();
-  //TODO: connect to repl set instead of instance
   if(!con_replica_->connect("localhost:" + std::to_string(config_->get_uint("plugins/robot-memory/setup/replicated/port")), errmsg))
   {
     std::string err_msg = "Could not connect to replica set: "+ errmsg;
     throw PluginLoadException("robot-memory", err_msg.c_str());
   }
 
-  //test setup
-  register_trigger(mongo::fromjson("{test: 0}"), "syncedrobmem.test", &EventTriggerManager::callback_test, this);
-
   logger_->log_info(name.c_str(), "Initialized");
 }
 
@@ -75,6 +67,7 @@ void EventTriggerManager::check_events()
     while(trigger->oplog_cursor->more())
     {
       BSONObj change = trigger->oplog_cursor->next();
+      //logger_->log_info(name.c_str(), "Triggering: %s", change.toString().c_str());
       //actually call the callback function
       trigger->callback(change);
     }
@@ -86,40 +79,14 @@ void EventTriggerManager::check_events()
   }
 }
 
-template<typename T>
-void EventTriggerManager::register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *obj)
+/**
+ * Remove a previously registered trigger
+ * @param trigger Pointer to the trigger to remove
+ */
+void EventTriggerManager::remove_trigger(EventTrigger* trigger)
 {
-  logger_->log_info(name.c_str(), "Registering Trigger");
-
-  //construct query for oplog
-  BSONObjBuilder query_builder;
-  query_builder.append("ns", collection);
-  // added/updated object is a subdocument in the oplog document
-  for(BSONObjIterator it = query.getFilter().begin(); it.more();)
-  {
-    BSONElement elem = it.next();
-    query_builder.appendAs(elem, std::string("o.") + elem.fieldName());
-  }
-  mongo::Query oplog_query = query_builder.obj();
-  oplog_query.readPref(ReadPreference_Nearest, BSONArray());
-
-  //check if collection is local or replicated
-  mongo::DBClientConnection* con;
-  std::string oplog;
-  if(collection.find(repl_set) == 0)
-  {
-    con = con_replica_;
-    oplog = "local.oplog.rs";
-  }
-  else
-  {
-    con = con_local_;
-    oplog = "local.oplog";
-  }
-
-  EventTrigger *trigger = new EventTrigger(oplog_query, collection, boost::bind(callback, obj, _1));
-  trigger->oplog_cursor = create_oplog_cursor(con, oplog, oplog_query);
-  triggers.push_back(trigger);
+  triggers.remove(trigger);
+  delete trigger;
 }
 
 QResCursor EventTriggerManager::create_oplog_cursor(mongo::DBClientConnection* con, std::string oplog, mongo::Query query)
@@ -132,3 +99,4 @@ QResCursor EventTriggerManager::create_oplog_cursor(mongo::DBClientConnection* c
   }
   return res;
 }
+
diff --git a/src/plugins/robot-memory/event_trigger_manager.h b/src/plugins/robot-memory/event_trigger_manager.h
index ab45725..f25253d 100644
--- a/src/plugins/robot-memory/event_trigger_manager.h
+++ b/src/plugins/robot-memory/event_trigger_manager.h
@@ -27,6 +27,7 @@
 #include <aspect/configurable.h>
 #include <list>
 #include "event_trigger.h"
+#include <boost/bind.hpp>
 
 
 ///typedef for shorter type description
@@ -45,12 +46,46 @@ class EventTriggerManager
     virtual ~EventTriggerManager();
 
     template<typename T>
-    void register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+    EventTrigger* register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *obj)
+    {
+      //construct query for oplog
+      mongo::BSONObjBuilder query_builder;
+      query_builder.append("ns", collection);
+      // added/updated object is a subdocument in the oplog document
+      for(mongo::BSONObjIterator it = query.getFilter().begin(); it.more();)
+      {
+        mongo::BSONElement elem = it.next();
+        query_builder.appendAs(elem, std::string("o.") + elem.fieldName());
+      }
+      mongo::Query oplog_query = query_builder.obj();
+      oplog_query.readPref(mongo::ReadPreference_Nearest, mongo::BSONArray());
+
+      //check if collection is local or replicated
+      mongo::DBClientConnection* con;
+      std::string oplog;
+      if(collection.find(repl_set) == 0)
+      {
+        con = con_replica_;
+        oplog = "local.oplog.rs";
+      }
+      else
+      {
+        con = con_local_;
+        oplog = "local.oplog.rs";
+      }
+
+      EventTrigger *trigger = new EventTrigger(oplog_query, collection, boost::bind(callback, obj, _1));
+      trigger->oplog_cursor = create_oplog_cursor(con, oplog, oplog_query);
+      triggers.push_back(trigger);
+      return trigger;
+    }
+
+
+    void remove_trigger(EventTrigger* trigger);
 
   private:
     void check_events();
     QResCursor create_oplog_cursor(mongo::DBClientConnection* con, std::string oplog, mongo::Query query);
-    void callback_test(mongo::BSONObj update);
 
     std::string name = "RobotMemory EventTriggerManager";
     fawkes::Logger* logger_;
@@ -65,4 +100,4 @@ class EventTriggerManager
     std::list<EventTrigger*> triggers;
 };
 
-#endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_ */
+#endif //FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 720bacc..e48d09a 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -419,19 +419,10 @@ RobotMemory::check_collection_name(std::string &collection)
 }
 
 /**
- * Register a trigger that notifies you when the event specified in the query happens
+ * Remove a previously registered trigger
+ * @param trigger Pointer to the trigger to remove
  */
-template<typename T>
-void RobotMemory::register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+void RobotMemory::remove_trigger(EventTrigger* trigger)
 {
-  trigger_manager_->register_trigger(query, collection, callback, _obj);
-}
-
-/**
- * Register a trigger that notifies you when the event specified in the query happens
- */
-template<typename T>
-void RobotMemory::register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
-{
-  register_trigger(fromjson(query_str), collection, callback);
+  trigger_manager_->remove_trigger(trigger);
 }
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 4eabaec..f3046b5 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -64,10 +64,34 @@ class RobotMemory
     int restore_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
     int dump_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
 
+    /**
+     * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
+     * @param query Query the updated document has to match
+     * @param collection db.collection to use
+     * @param callback Callback function (e.g. &Class::callback)
+     * @param _obj Pointer to class the callback is a function of (usaually this)
+     * @return Trigger object pointer, save it to remove the trigger later
+     */
     template<typename T>
-    void register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+    EventTrigger* register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+    {
+      return trigger_manager_->register_trigger(query, collection, callback, _obj);
+    }
+    /**
+     * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
+     * @param query_str Query as JSON string
+     * @param collection db.collection to use
+     * @param callback Callback function (e.g. &Class::callback)
+     * @param _obj Pointer to class the callback is a function of (usaually this)
+     * @return Trigger object pointer, save it to remove the trigger later
+     */
     template<typename T>
-    void register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+    EventTrigger* register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+    {
+      return register_trigger(mongo::fromjson(query_str), collection, callback);
+    }
+
+    void remove_trigger(EventTrigger* trigger);
 
   private:
     mongo::DBClientBase* mongodb_client_;
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index a24e29e..2474a68 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -156,6 +156,50 @@ TEST_F(RobotMemoryTest, DumpAndResore)
 
 }
 
+TEST_F(RobotMemoryTest, EventTriggerLocal)
+{
+  RobotMemoryCallback* rmc = new RobotMemoryCallback();
+  rmc->callback_counter = 0;
+  EventTrigger* trigger1 = robot_memory->register_trigger(fromjson("{test:1}"),
+      "robmem.test", &RobotMemoryCallback::callback_test, rmc);
+  EventTrigger* trigger2 = robot_memory->register_trigger(fromjson("{test:2}"),
+      "robmem.test", &RobotMemoryCallback::callback_test, rmc);
+
+  robot_memory->insert(fromjson("{test:0, updateid:55}"), "robmem.test");
+  robot_memory->insert(fromjson("{test:1, updateid:42}"), "robmem.test");
+  robot_memory->update(fromjson("{updateid:42}"), fromjson("{test:2, updateid:42}"), "robmem.test");
+
+  //wait for robot memory to call triggers
+  usleep(500000);
+
+  ASSERT_EQ(2, rmc->callback_counter);
+
+  robot_memory->remove_trigger(trigger1);
+  robot_memory->remove_trigger(trigger2);
+}
+
+TEST_F(RobotMemoryTest, EventTriggerReplica)
+{
+  RobotMemoryCallback* rmc = new RobotMemoryCallback();
+  rmc->callback_counter = 0;
+  EventTrigger* trigger1 = robot_memory->register_trigger(fromjson("{test:1}"),
+      "syncedrobmem.test", &RobotMemoryCallback::callback_test, rmc);
+  EventTrigger* trigger2 = robot_memory->register_trigger(fromjson("{test:2}"),
+      "syncedrobmem.test", &RobotMemoryCallback::callback_test, rmc);
+
+  robot_memory->insert(fromjson("{test:0, updateid:55}"), "syncedrobmem.test");
+  robot_memory->insert(fromjson("{test:1, updateid:42}"), "syncedrobmem.test");
+  robot_memory->update(fromjson("{updateid:42}"), fromjson("{test:2, updateid:42}"), "syncedrobmem.test");
+
+  //wait for robot memory to call triggers
+  usleep(500000);
+
+  ASSERT_EQ(2, rmc->callback_counter);
+
+  robot_memory->remove_trigger(trigger1);
+  robot_memory->remove_trigger(trigger2);
+}
+
 ::testing::AssertionResult RobotMemoryTest::contains_pairs(BSONObj obj, BSONObj exp)
 {
   for(BSONObjIterator it = exp.begin(); it.more();)
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.h b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
index a9cdb07..665b1c1 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
@@ -55,5 +55,23 @@ class RobotMemoryTest : public ::testing::Test
   ::testing::AssertionResult contains_pairs(mongo::BSONObj obj, mongo::BSONObj exp);
 };
 
+/**
+ * Class to register callbacks independent of how many tests are using them at the moment
+ */
+class RobotMemoryCallback
+{
+  public:
+    RobotMemoryCallback()
+  {
+      callback_counter = 0;
+  };
+   ~RobotMemoryCallback(){};
+   int callback_counter;
+   void callback_test(mongo::BSONObj update)
+   {
+     callback_counter++;
+   }
+};
+
 
 #endif
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
index 5bedac1..640917b 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
@@ -47,13 +47,14 @@ RobotMemoryTestThread::init()
   test_env_ = new RobotMemoryTestEnvironment(robot_memory);
   ::testing::AddGlobalTestEnvironment((testing::Environment*) test_env_);
 
-  logger->log_warn(name(), "Starting tests");
-  test_result_ = RUN_ALL_TESTS();
 }
 
 void
 RobotMemoryTestThread::loop()
 {
+  logger->log_warn(name(), "Starting tests");
+  test_result_ = RUN_ALL_TESTS();
+  usleep(100000);
   logger->log_warn(name(), "Finished tests with, quitting as intended...");
   //stop fawkes to finish the testing run
   fawkes::runtime::quit();

- *commit* 541da32fde934b81b326295b2c04ecb24dae8476 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 6 19:01:30 2016 +0200
Subject: robot-memory: fixed DumpRestore test

 .../robot-memory/test-plugin/robot_memory_test.cpp |   21 ++++++++++++++-----
 1 files changed, 15 insertions(+), 6 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index 2474a68..9714625 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -20,6 +20,8 @@
  */
 
 #include "robot_memory_test.h"
+#include <list>
+#include <algorithm>
 
 //init static variable
 RobotMemory* RobotMemoryTestEnvironment::robot_memory = NULL;
@@ -146,14 +148,21 @@ TEST_F(RobotMemoryTest, DumpAndResore)
   ASSERT_TRUE(robot_memory->drop_collection("robmem.test"));
   ASSERT_TRUE(robot_memory->restore_collection("robmem.test"));
   QResCursor qres = robot_memory->query("{'testkey':'value'}");
+  std::list<int> values = {3, 2, 1};
   ASSERT_TRUE(qres->more());
-  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value',v:1}")));
+  int got = qres->next().getField("v").Int();
+  ASSERT_TRUE(std::find(values.begin(), values.end(), got) != values.end());
+  values.remove(got);
   ASSERT_TRUE(qres->more());
-  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value',v:2}")));
+  got = qres->next().getField("v").Int();
+  ASSERT_TRUE(std::find(values.begin(), values.end(), got) != values.end());
+  values.remove(got);
   ASSERT_TRUE(qres->more());
-  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value',v:3}")));
+  got = qres->next().getField("v").Int();
+  ASSERT_TRUE(std::find(values.begin(), values.end(), got) != values.end());
+  values.remove(got);
+  ASSERT_EQ(0, values.size());
   ASSERT_FALSE(qres->more());
-
 }
 
 TEST_F(RobotMemoryTest, EventTriggerLocal)
@@ -170,7 +179,7 @@ TEST_F(RobotMemoryTest, EventTriggerLocal)
   robot_memory->update(fromjson("{updateid:42}"), fromjson("{test:2, updateid:42}"), "robmem.test");
 
   //wait for robot memory to call triggers
-  usleep(500000);
+  usleep(100000);
 
   ASSERT_EQ(2, rmc->callback_counter);
 
@@ -192,7 +201,7 @@ TEST_F(RobotMemoryTest, EventTriggerReplica)
   robot_memory->update(fromjson("{updateid:42}"), fromjson("{test:2, updateid:42}"), "syncedrobmem.test");
 
   //wait for robot memory to call triggers
-  usleep(500000);
+  usleep(100000);
 
   ASSERT_EQ(2, rmc->callback_counter);
 

- *commit* ccf97d831f7af2c5483a8e632cb9d9472695dee8 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Mon Oct 10 14:27:53 2016 +0200
Subject: clips-robot-memory: first steps of trigger integration

 src/plugins/clips-robot-memory/Makefile            |    2 +-
 .../clips_rm_trigger.cpp}                          |   45 +++++++++---------
 src/plugins/clips-robot-memory/clips_rm_trigger.h  |   50 ++++++++++++++++++++
 .../clips_robot_memory_thread.cpp                  |   36 ++++++++++++++
 .../clips-robot-memory/clips_robot_memory_thread.h |    6 ++
 src/plugins/robot-memory/event_trigger_manager.cpp |    2 +-
 src/plugins/robot-memory/robot_memory_setup.cpp    |    2 +-
 7 files changed, 118 insertions(+), 25 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/Makefile b/src/plugins/clips-robot-memory/Makefile
index e91e1ca..7f4de4b 100644
--- a/src/plugins/clips-robot-memory/Makefile
+++ b/src/plugins/clips-robot-memory/Makefile
@@ -23,7 +23,7 @@ LIBS_clips_robot_memory = m fawkescore fawkesutils fawkesaspects fawkesbaseapp \
                       fawkesblackboard fawkesinterface fawkesclipsaspect \
                       fawkesrobotmemory
 
-OBJS_clips_robot_memory = clips_robot_memory_plugin.o clips_robot_memory_thread.o
+OBJS_clips_robot_memory = clips_robot_memory_plugin.o clips_robot_memory_thread.o clips_rm_trigger.o
 
 OBJS_all = $(OBJS_clips_robot_memory)
 
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
index eebe069..4b9d723 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
@@ -51,6 +51,10 @@ void
 ClipsRobotMemoryThread::finalize()
 {
   envs_.clear();
+  for(ClipsRmTrigger* trigger : clips_triggers_)
+  {
+    delete trigger;
+  }
 }
 
 void
@@ -83,6 +87,14 @@ ClipsRobotMemoryThread::clips_context_init(const std::string &env_name,
   clips->add_function("robmem-cursor-destroy", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_cursor_destroy)));
   clips->add_function("robmem-cursor-more", sigc::slot<CLIPS::Value, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_cursor_more)));
   clips->add_function("robmem-cursor-next", sigc::slot<CLIPS::Value, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_cursor_next)));
+  clips->add_function("robmem-trigger-register",
+      sigc::slot<CLIPS::Value, std::string, void *, std::string>(
+        sigc::bind<0>(
+          sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_register_trigger),
+    env_name)
+      )
+    );
+  clips->add_function("robmem-trigger-destroy", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_destroy_trigger)));
   clips->add_function("bson-field-names", sigc::slot<CLIPS::Values, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_field_names)));
   clips->add_function("bson-get", sigc::slot<CLIPS::Value, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get)));
   clips->add_function("bson-get-array", sigc::slot<CLIPS::Values, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get_array)));
@@ -677,3 +689,27 @@ ClipsRobotMemoryThread::clips_bson_get_time(void *bson, std::string field_name)
   return rv;
 }
 
+
+CLIPS::Value
+ClipsRobotMemoryThread::clips_robotmemory_register_trigger(std::string env_name, std::string collection, void *query, std::string assert_name)
+{
+  mongo::BSONObjBuilder *b = static_cast<mongo::BSONObjBuilder *>(query);
+  try {
+    mongo::Query q(b->asTempObj());
+    ClipsRmTrigger *clips_trigger = new ClipsRmTrigger(assert_name, robot_memory, envs_[env_name]);
+    clips_trigger->set_trigger(robot_memory->register_trigger(q, collection, &ClipsRmTrigger::callback, clips_trigger));
+    clips_triggers_.push_back(clips_trigger);
+    return CLIPS::Value(clips_trigger);
+  } catch (mongo::DBException &e) {
+    logger->log_warn("CLIPS RobotMemory", "Trigger query failed: %s", e.what());
+    return CLIPS::Value("FALSE", CLIPS::TYPE_SYMBOL);
+  }
+}
+
+void
+ClipsRobotMemoryThread::clips_robotmemory_destroy_trigger(void *trigger)
+{
+  ClipsRmTrigger *clips_trigger = static_cast<ClipsRmTrigger *>(trigger);
+  clips_triggers_.remove(clips_trigger);
+  delete clips_trigger; //the triger unregisteres itself at the robot memory
+}
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.h b/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
index 31f9c87..f4fd1f4 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
@@ -30,6 +30,7 @@
 #include <aspect/configurable.h>
 #include <plugins/clips/aspect/clips_feature.h>
 #include <plugins/robot-memory/aspect/robot_memory_aspect.h>
+#include "clips_rm_trigger.h"
 
 #include <string>
 #include <clipsmm.h>
@@ -63,6 +64,7 @@ class ClipsRobotMemoryThread
 
  private:
   std::map<std::string, fawkes::LockPtr<CLIPS::Environment> >  envs_;
+
   CLIPS::Value  clips_bson_create();
   CLIPS::Value  clips_bson_parse(std::string document);
   void          clips_bson_destroy(void *bson);
@@ -91,6 +93,10 @@ class ClipsRobotMemoryThread
   CLIPS::Value  clips_bson_get(void *bson, std::string field_name);
   CLIPS::Values clips_bson_get_array(void *bson, std::string field_name);
   CLIPS::Values clips_bson_get_time(void *bson, std::string field_name);
+  CLIPS::Value  clips_robotmemory_register_trigger(std::string env_name, std::string collection, void *query, std::string assert_name);
+  void  clips_robotmemory_destroy_trigger(void *trigger);
+
+  std::list<ClipsRmTrigger*>  clips_triggers_;
 };
 
 
diff --git a/src/plugins/robot-memory/event_trigger_manager.cpp b/src/plugins/robot-memory/event_trigger_manager.cpp
index b2af921..8262815 100644
--- a/src/plugins/robot-memory/event_trigger_manager.cpp
+++ b/src/plugins/robot-memory/event_trigger_manager.cpp
@@ -49,7 +49,7 @@ EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
     throw PluginLoadException("robot-memory", err_msg.c_str());
   }
 
-  logger_->log_info(name.c_str(), "Initialized");
+  logger_->log_debug(name.c_str(), "Initialized");
 }
 
 EventTriggerManager::~EventTriggerManager()
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index fc4bc29..9f1d077 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -120,7 +120,7 @@ void RobotMemorySetup::start_mongo_process(std::string proc_name, unsigned int p
   if (!is_mongo_running(port))
     {
       std::string cmd = command_args_tostring(argv);
-      logger->log_error("RobotMemorySetup", "Starting %s process: '%s'", proc_name.c_str(), cmd.c_str());
+      logger->log_warn("RobotMemorySetup", "Starting %s process: '%s'", proc_name.c_str(), cmd.c_str());
       config_mongod = new SubProcess(proc_name.c_str(), argv[0], argv, NULL, logger);
       logger->log_info("RobotMemorySetup", "Started %s", proc_name.c_str());
       wait_until_started(port, cmd, config->get_int("plugins/robot-memory/setup/max_setup_time"));

- *commit* f9e5dcdf867c842195802934c391159306c4f7b6 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Oct 11 16:20:28 2016 +0200
Subject: clips-robot-memory: fixed getting sub-documents

 .../clips_robot_memory_thread.cpp                  |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
index 4b9d723..80ed7e4 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
@@ -571,7 +571,7 @@ ClipsRobotMemoryThread::clips_bson_get(void *bson, std::string field_name)
   case mongo::Object:
     {
       mongo::BSONObjBuilder *b = new mongo::BSONObjBuilder();
-      b->appendElements(o);
+      b->appendElements(el.Obj());
       return CLIPS::Value(b);
     }
   default:

- *commit* 8fa54256f2154ce789fdd13616182c53fb769380 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Oct 11 17:51:43 2016 +0200
Subject: clips-robot-memroy: fixed assert-from-bson

 src/plugins/clips-robot-memory/robot-memory.clp |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/robot-memory.clp b/src/plugins/clips-robot-memory/robot-memory.clp
index 709f6bb..3994c39 100644
--- a/src/plugins/clips-robot-memory/robot-memory.clp
+++ b/src/plugins/clips-robot-memory/robot-memory.clp
@@ -48,20 +48,20 @@
   (bind ?keys (bson-field-names ?doc))
   (if (member$ "relation" ?keys)
     then
-    (bind ?relation (bson-get ?doc "relation"))
+    (bind ?relation (sym-cat (bson-get ?doc "relation")))
     else
     (printout error "Can not create fact from " (bson-tostring ?doc) crlf)
     (return)
   )
-  (if (member$ ?relation (get-deftemplate-list *))
+  (if (member$ ?relation (get-deftemplate-list MAIN))
     then ;structured fact
     (progn$ (?slot ?keys)
-      (if (deftemplate-slot-existp ?relation ?slot) then
-        (if (deftemplate-slot-multip ?relation ?slot)
+      (if (deftemplate-slot-existp ?relation (sym-cat ?slot)) then
+        (if (deftemplate-slot-multip ?relation (sym-cat ?slot))
           then
-          (bind ?values (str-cat ?values "(" ?relation " " (bson-get ?doc ?slot) ")"))
+          (bind ?values (str-cat ?values "(" ?slot " " (implode$ (bson-get-array ?doc ?slot)) ")"))
           else
-          (bind ?values (str-cat ?values "(" ?relation " " (implode$ (bson-get-array ?doc ?slot)) ")"))
+          (bind ?values (str-cat ?values "(" ?slot " " (bson-get ?doc ?slot) ")"))
         )
       )
     )

- *commit* 5373f4a6e235b04143cc6baaae409eb45c0cd2e4 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Oct 11 22:00:57 2016 +0200
Subject: clips-robot-memory: assert trigger facts for db updates

 .../clips-robot-memory/clips_rm_trigger.cpp        |   35 ++++++++++++++++++-
 src/plugins/clips-robot-memory/clips_rm_trigger.h  |    4 ++-
 .../clips_robot_memory_thread.cpp                  |    5 ++-
 src/plugins/clips-robot-memory/robot-memory.clp    |   17 +++++++++-
 4 files changed, 56 insertions(+), 5 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/clips_rm_trigger.cpp b/src/plugins/clips-robot-memory/clips_rm_trigger.cpp
index bee73b2..ad8aba5 100644
--- a/src/plugins/clips-robot-memory/clips_rm_trigger.cpp
+++ b/src/plugins/clips-robot-memory/clips_rm_trigger.cpp
@@ -20,14 +20,18 @@
  */
 
 #include "clips_rm_trigger.h"
+#include <clipsmm.h>
 
 using namespace fawkes;
+using namespace mongo;
 
-ClipsRmTrigger::ClipsRmTrigger(std::string assert_name, RobotMemory *robot_memory, LockPtr<CLIPS::Environment> &clips)
+ClipsRmTrigger::ClipsRmTrigger(std::string assert_name, RobotMemory *robot_memory,
+  LockPtr<CLIPS::Environment> &clips, fawkes::Logger *logger)
 {
   this->assert_name = assert_name;
   this->robot_memory = robot_memory;
   this->clips = clips;
+  this->logger = logger;
 }
 
 ClipsRmTrigger::~ClipsRmTrigger()
@@ -49,6 +53,33 @@ void ClipsRmTrigger::set_trigger(EventTrigger *trigger)
  */
 void ClipsRmTrigger::callback(mongo::BSONObj update)
 {
-  clips->assert_fact_f("(robmem-update-triggered)");
+  clips->assert_fact_f("( %s)", assert_name.c_str());
+  CLIPS::Template::pointer temp = clips->get_template("robmem-trigger");
+  if (temp) {
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    CLIPS::Fact::pointer fact = CLIPS::Fact::create(**clips, temp);
+    fact->set_slot("name", assert_name.c_str());
+    CLIPS::Values rcvd_at(2, CLIPS::Value(CLIPS::TYPE_INTEGER));
+    rcvd_at[0] = tv.tv_sec;
+    rcvd_at[1] = tv.tv_usec;
+    fact->set_slot("rcvd-at", rcvd_at);
+    BSONObjBuilder *b = new BSONObjBuilder();
+    b->appendElements(update);
+    void *ptr = b;
+    fact->set_slot("ptr", CLIPS::Value(ptr));
+    CLIPS::Fact::pointer new_fact = clips->assert_fact(fact);
+
+    if (new_fact) {
+      //TODO: msg_facts_[new_fact->index()] = new_fact;
+    } else {
+      logger->log_warn("CLIPS-RobotMemory", "Asserting robmem-trigger fact failed");
+      delete static_cast<BSONObjBuilder *>(ptr);
+    }
+  } else {
+    logger->log_warn("CLIPS-RobotMemory",
+        "Did not get template, did you load robot-memory.clp?");
+  }
+
 }
 
diff --git a/src/plugins/clips-robot-memory/clips_rm_trigger.h b/src/plugins/clips-robot-memory/clips_rm_trigger.h
index a9d8d53..20095e5 100644
--- a/src/plugins/clips-robot-memory/clips_rm_trigger.h
+++ b/src/plugins/clips-robot-memory/clips_rm_trigger.h
@@ -26,6 +26,7 @@
 #include <plugins/robot-memory/robot_memory.h>
 #include <clipsmm.h>
 #include <core/utils/lockptr.h>
+#include <logging/logger.h>
 
 /** @class ClipsRmTrigger  clips_rm_trigger.h
  *
@@ -34,7 +35,7 @@
 class ClipsRmTrigger
 {
   public:
-    ClipsRmTrigger(std::string assert_name, RobotMemory *robot_memory, fawkes::LockPtr<CLIPS::Environment> &clips);
+    ClipsRmTrigger(std::string assert_name, RobotMemory *robot_memory, fawkes::LockPtr<CLIPS::Environment> &clips, fawkes::Logger *logger);
     virtual ~ClipsRmTrigger();
 
     void callback(mongo::BSONObj update);
@@ -45,6 +46,7 @@ class ClipsRmTrigger
     EventTrigger *trigger;
     RobotMemory *robot_memory;
     fawkes::LockPtr<CLIPS::Environment> clips;
+    fawkes::Logger *logger;
 };
 
 #endif /* FAWKES_SRC_PLUGINS_CLIPS_ROBOT_MEMORY_CLIPS_RM_TRIGGER_H_ */
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
index 80ed7e4..ec8043f 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
@@ -574,6 +574,9 @@ ClipsRobotMemoryThread::clips_bson_get(void *bson, std::string field_name)
       b->appendElements(el.Obj());
       return CLIPS::Value(b);
     }
+  case 7: //ObjectId
+    return CLIPS::Value(el.OID().toString());
+
   default:
     return CLIPS::Value("INVALID_VALUE_TYPE", CLIPS::TYPE_SYMBOL);
   }
@@ -696,7 +699,7 @@ ClipsRobotMemoryThread::clips_robotmemory_register_trigger(std::string env_name,
   mongo::BSONObjBuilder *b = static_cast<mongo::BSONObjBuilder *>(query);
   try {
     mongo::Query q(b->asTempObj());
-    ClipsRmTrigger *clips_trigger = new ClipsRmTrigger(assert_name, robot_memory, envs_[env_name]);
+    ClipsRmTrigger *clips_trigger = new ClipsRmTrigger(assert_name, robot_memory, envs_[env_name], logger);
     clips_trigger->set_trigger(robot_memory->register_trigger(q, collection, &ClipsRmTrigger::callback, clips_trigger));
     clips_triggers_.push_back(clips_trigger);
     return CLIPS::Value(clips_trigger);
diff --git a/src/plugins/clips-robot-memory/robot-memory.clp b/src/plugins/clips-robot-memory/robot-memory.clp
index 3994c39..2cb9f9f 100644
--- a/src/plugins/clips-robot-memory/robot-memory.clp
+++ b/src/plugins/clips-robot-memory/robot-memory.clp
@@ -7,6 +7,12 @@
 ;  Licensed under GPLv2+ license, cf. LICENSE file
 ;---------------------------------------------------------------------------
 
+(deftemplate robmem-trigger
+  (slot name (type STRING))
+  (multislot rcvd-at (type INTEGER) (cardinality 2 2))
+  (slot ptr (type EXTERNAL-ADDRESS))
+)
+
 ;; Creates a BSON document from a structured fact
 ; @param ?fact Fact-Pointer
 ; @return BSON document
@@ -70,6 +76,15 @@
       (bind ?values (str-cat ?values "(" ?relation " " (implode$ (bson-get-array ?doc "values")) ")"))
     )
   )
-  
+
   (assert-string (str-cat "(" ?relation " " ?values ")"))
 )
+
+(defrule rm-cleanup-trigger-facts
+  "remove all trigger update facts when they were not used (by a rule with a higher priority in this iteration)"
+  (declare (salience -4000))
+  ?rt <- (robmem-trigger (ptr ?bson))
+  =>
+  (retract ?rt)
+  (bson-destroy ?bson)
+)

- *commit* 5faa7384cd612f2dd8a3f5cad24c3d4aa916f073 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Oct 11 21:51:46 2016 +0200
Subject: colli: renamed AStar class to avoid conflict with utils/search/astar

 src/plugins/colli/search/astar.cpp        |   20 ++++++++++----------
 src/plugins/colli/search/astar.h          |    6 +++---
 src/plugins/colli/search/astar_search.cpp |    2 +-
 src/plugins/colli/search/astar_search.h   |    4 ++--
 4 files changed, 16 insertions(+), 16 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/colli/search/astar.cpp b/src/plugins/colli/search/astar.cpp
index 8038016..75be545 100644
--- a/src/plugins/colli/search/astar.cpp
+++ b/src/plugins/colli/search/astar.cpp
@@ -52,7 +52,7 @@ namespace fawkes
  * @param logger The fawkes logger
  * @param config The fawkes configuration
  */
-AStar::AStar( LaserOccupancyGrid * occGrid, Logger* logger, Configuration* config )
+AStarColli::AStarColli( LaserOccupancyGrid * occGrid, Logger* logger, Configuration* config )
  : logger_( logger )
 {
   logger_->log_debug("AStar", "(Constructor): Initializing AStar");
@@ -86,7 +86,7 @@ AStar::AStar( LaserOccupancyGrid * occGrid, Logger* logger, Configuration* confi
 /** Destructor.
  *  This destructor deletes all the states allocated during construction.
  */
-AStar::~AStar()
+AStarColli::~AStarColli()
 {
   logger_->log_debug("AStar", "(Destructor): Destroying AStar");
   for( int i = 0; i < max_states_; i++ )
@@ -106,7 +106,7 @@ AStar::~AStar()
  * @param solution a vector that will be filled with the found path
  */
 void
-AStar::solve( const point_t &robo_pos, const point_t &target_pos, vector<point_t> &solution )
+AStarColli::solve( const point_t &robo_pos, const point_t &target_pos, vector<point_t> &solution )
 {
   // initialize counter, vectors/lists/queues
   astar_state_count_ = 0;
@@ -146,7 +146,7 @@ AStar::solve( const point_t &robo_pos, const point_t &target_pos, vector<point_t
  *  Its really easy, you can find it like this everywhere.
  */
 AStarState*
-AStar::search( )
+AStarColli::search( )
 {
   AStarState * best = 0;
 
@@ -197,7 +197,7 @@ AStar::search( )
  *    afterwards a number that is smaller tham 14 bits!
  */
 int
-AStar::calculate_key( int x, int y )
+AStarColli::calculate_key( int x, int y )
 {
   return (x << 15) | y;  // This line is a crime! But fast ;-)
 }
@@ -209,7 +209,7 @@ AStar::calculate_key( int x, int y )
  *   Afterwards these children are put on the openlist.
  */
 void
-AStar::generate_children( AStarState * father )
+AStarColli::generate_children( AStarState * father )
 {
   AStarState * child;
   int key;
@@ -301,7 +301,7 @@ AStar::generate_children( AStarState * father )
  *    because we are calculating on a grid...
  */
 int
-AStar::heuristic( AStarState * state )
+AStarColli::heuristic( AStarState * state )
 {
   //  return (int)( abs( state->x_ - target_state_.x_ ));
   return (int)( abs( state->x_ - target_state_.x_ ) +
@@ -313,7 +313,7 @@ AStar::heuristic( AStarState * state )
  *  This method checks, if a state is a goal state.
  */
 bool
-AStar::is_goal( AStarState * state )
+AStarColli::is_goal( AStarState * state )
 {
   return ( (target_state_.x_ == state->x_) &&
            (target_state_.y_ == state->y_) );
@@ -325,7 +325,7 @@ AStar::is_goal( AStarState * state )
  *    tree into the solution/plan vector.
  */
 void
-AStar::get_solution_sequence( AStarState * node, vector<point_t> &solution )
+AStarColli::get_solution_sequence( AStarState * node, vector<point_t> &solution )
 {
   AStarState * state = node;
   while ( state != 0 ) {
@@ -350,7 +350,7 @@ AStar::get_solution_sequence( AStarState * node, vector<point_t> &solution )
  * @return a new modified point.
  */
 point_t
-AStar::remove_target_from_obstacle( int target_x, int target_y, int step_x, int step_y  )
+AStarColli::remove_target_from_obstacle( int target_x, int target_y, int step_x, int step_y  )
 {
   // initializing lists...
   while ( open_list_.size() > 0 )
diff --git a/src/plugins/colli/search/astar.h b/src/plugins/colli/search/astar.h
index b984e1e..588c248 100644
--- a/src/plugins/colli/search/astar.h
+++ b/src/plugins/colli/search/astar.h
@@ -46,11 +46,11 @@ typedef struct point_struct point_t;
  *  This is an implementation of the A* search algorithm in a
  *    highly efficient way (I hope ;-).
  */
-class AStar
+class AStarColli
 {
  public:
-  AStar( LaserOccupancyGrid * occGrid, Logger* logger, Configuration* config );
-  ~AStar();
+  AStarColli( LaserOccupancyGrid * occGrid, Logger* logger, Configuration* config );
+  ~AStarColli();
 
   /* =========================================== */
   /* ************* PUBLIC METHODS ************** */
diff --git a/src/plugins/colli/search/astar_search.cpp b/src/plugins/colli/search/astar_search.cpp
index 9b20a31..70c282a 100644
--- a/src/plugins/colli/search/astar_search.cpp
+++ b/src/plugins/colli/search/astar_search.cpp
@@ -52,7 +52,7 @@ Search::Search( LaserOccupancyGrid * occ_grid, Logger* logger, Configuration* co
   logger_->log_debug("search", "(Constructor): Entering");
   std::string cfg_prefix = "/plugins/colli/search/";
   cfg_search_line_allowed_cost_max_  = config->get_int((cfg_prefix + "line/cost_max").c_str());
-  astar_ = new AStar( occ_grid, logger, config );
+  astar_ = new AStarColli( occ_grid, logger, config );
   logger_->log_debug("search", "(Constructor): Exiting");
 }
 
diff --git a/src/plugins/colli/search/astar_search.h b/src/plugins/colli/search/astar_search.h
index 14ff889..bed2fee 100644
--- a/src/plugins/colli/search/astar_search.h
+++ b/src/plugins/colli/search/astar_search.h
@@ -34,7 +34,7 @@ namespace fawkes
 #endif
 
 class LaserOccupancyGrid;
-class AStar;
+class AStarColli;
 class Logger;
 class Configuration;
 
@@ -77,7 +77,7 @@ class Search: public AbstractSearch
   bool is_obstacle_between( const point_t &a, const point_t &b, const int maxcount );
 
 
-  AStar * astar_;              /**< the A* search algorithm */
+  AStarColli * astar_;              /**< the A* search algorithm */
   std::vector< point_t > plan_; /**< the local representation of the plan */
 
   point_t robo_position_, target_position_;

- *commit* 2533050b3314ceb8788771ce3a250cf1851f224e - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 13 13:21:38 2016 +0200
Subject: robot-memory: proper first setup of local mongod with oplog

 src/plugins/robot-memory/robot_memory_setup.cpp |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index 9f1d077..db73a54 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -48,11 +48,12 @@ void RobotMemorySetup::setup_mongods()
   //start local mongod if necessary
   unsigned int local_port = config->get_uint("plugins/robot-memory/setup/local/port");
   std::string local_db_name = config->get_string("plugins/robot-memory/database");
+  std::string local_repl_name = config->get_string("plugins/robot-memory/setup/local/replica-set-name");
   std::string local_port_str = std::to_string(local_port);
   const char *local_argv[] = {"mongod", "--port", local_port_str.c_str(),
-      "--replSet", "local", NULL}; //'local' replica set to enable the oplog
+      "--replSet", local_repl_name.c_str(), NULL}; //local replica set just to enable the oplog
   start_mongo_process("mongod-local", local_port, local_argv);
-  std::string local_config = "{_id: 'local', members:[{_id:1,host:'localhost:" + local_port_str + "'}]}";
+  std::string local_config = "{_id: '" + local_repl_name + "', members:[{_id:1,host:'localhost:" + local_port_str + "'}]}";
   run_mongo_command(local_port, std::string("{replSetInitiate:" + local_config + "}"), "already initialized");
   //wait for initialization
   usleep(1000000);
@@ -101,15 +102,16 @@ void RobotMemorySetup::setup_mongods()
 
   //configure mongos (add parts of the sharded cluster)
   mongo::BSONObj current_shards =  run_mongo_command(mongos_port, std::string("{listShards:1}"));
-  if(current_shards.getField("shards").Array().size() == 0)
+  if(current_shards.getField("shards").Array().size() < 2)
   {
-    run_mongo_command(mongos_port, std::string("{addShard: 'localhost:" + local_port_str + "'}"), "host already used");
+    run_mongo_command(mongos_port, std::string("{addShard: '" + local_repl_name +
+      "/localhost:" + local_port_str + "'}"), "host already used");
     run_mongo_command(mongos_port, std::string("{addShard: '" + distributed_replset +
       "/localhost:" + distributed_port_str + "'}"), "host already used");
   }
   //define which db is in which shard
   run_mongo_command(mongos_port, std::string("{movePrimary: '" + distributed_replset + "', to: '" + distributed_replset + "'}"), "it is already the primary");
-  run_mongo_command(mongos_port, std::string("{movePrimary: '" + local_db_name + "', to: 'shard0000'}"), "it is already the primary");
+  run_mongo_command(mongos_port, std::string("{movePrimary: '" + local_db_name + "', to: '" + local_repl_name + "'}"), "it is already the primary");
 }
 
 /**

- *commit* 3c154a899de821498c9be1e49378bb7523060e37 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 13 13:42:00 2016 +0200
Subject: pddl-robot-memory: plugin skeleton for generating pddl from the robot memory

 src/plugins/Makefile                               |    2 +-
 .../{ttmainloop => pddl-robot-memory}/Makefile     |   20 +++++----
 .../pddl_robot_memory_plugin.cpp}                  |   20 ++++----
 .../pddl_robot_memory_thread.cpp}                  |   47 +++++++++++---------
 .../pddl_robot_memory_thread.h}                    |   27 +++++------
 5 files changed, 60 insertions(+), 56 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/Makefile b/src/plugins/Makefile
index a1abd75..e3aa8c8 100644
--- a/src/plugins/Makefile
+++ b/src/plugins/Makefile
@@ -26,7 +26,7 @@ SUBDIRS	= bbsync bblogger webview ttmainloop rrd rrdweb \
 	  static_transforms navgraph navgraph-clusters navgraph-generator colli \
 	  clips clips-agent clips-protobuf clips-webview clips-navgraph clips-ros \
 	  clips-tf openprs openprs-agent eclipse-clp \
-	  mongodb mongodb_log robot-memory clips-robot-memory \
+	  mongodb mongodb_log robot-memory clips-robot-memory pddl-robot-memory \
 	  openni refboxcomm ros player xmlrpc gossip \
 	  robot_state_publisher gazebo dynamixel navgraph-interactive \
 	  asp

- *commit* d6fb4e58fcb897edf2feff3f1791a900d676061c - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 13 15:31:14 2016 +0200
Subject: pddl-robot-memory: reading template and writing output file

 src/plugins/Makefile                               |    1 +
 src/plugins/pddl-robot-memory/Makefile             |   28 +++++++++++++-
 .../pddl-robot-memory/pddl_robot_memory_thread.cpp |   40 ++++++++++++++++++++
 .../pddl-robot-memory/pddl_robot_memory_thread.h   |   10 +++-
 4 files changed, 74 insertions(+), 5 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/Makefile b/src/plugins/Makefile
index e3aa8c8..791fbaf 100644
--- a/src/plugins/Makefile
+++ b/src/plugins/Makefile
@@ -44,6 +44,7 @@ clips-navgraph navgraph-clusters: navgraph
 clips-webview: clips webview
 clips-ros: clips ros
 clips-robot-memory: robot-memory
+pddl-robot-memory: robot-memory
 gazebo: robotino
 skiller: navgraph
 perception: mongodb
diff --git a/src/plugins/pddl-robot-memory/Makefile b/src/plugins/pddl-robot-memory/Makefile
index 062b212..fbfa08b 100644
--- a/src/plugins/pddl-robot-memory/Makefile
+++ b/src/plugins/pddl-robot-memory/Makefile
@@ -16,14 +16,38 @@
 
 BASEDIR = ../../..
 include $(BASEDIR)/etc/buildsys/config.mk
+include $(BASEDIR)/src/plugins/mongodb/mongodb.mk
 
 LIBS_pddl_robot_memory = m fawkescore fawkesutils fawkesaspects fawkesbaseapp \
-                      fawkesblackboard fawkesinterface
+                      fawkesblackboard fawkesinterface fawkesrobotmemory
 
 OBJS_pddl_robot_memory = pddl_robot_memory_plugin.o pddl_robot_memory_thread.o
 
-PLUGINS_all = $(PLUGINDIR)/pddl_robot_memory.$(SOEXT)
 
 OBJS_all = $(OBJS_pddl_robot_memory)
 
+ifeq ($(HAVE_CPP11)$(HAVE_MONGODB),11)
+  CFLAGS  += $(CFLAGS_CPP11)
+
+  PLUGINS_all = $(PLUGINDIR)/pddl-robot-memory.$(SOEXT)	  
+else
+  ifneq ($(HAVE_CPP11),1)
+    WARN_TARGETS += warning_cpp11
+  endif
+  ifneq ($(HAVE_TF),1)
+    WARN_TARGETS = warning_mongodb
+  endif
+endif
+
+ifeq ($(OBJSSUBMAKE),1)
+all: $(WARN_TARGETS)
+
+.PHONY: warning_tf warning_clips warning_cpp11
+warning_mongodb:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting clips-robot-memory plugin$(TNORMAL) (mongodb not available)"
+warning_cpp11:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Cannot build clips-robot-memory plugin$(TNORMAL) (C++11 not supported)"
+
+endif
+
 include $(BUILDSYSDIR)/base.mk
\ No newline at end of file
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
index 82d7d96..8edfd10 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
@@ -22,6 +22,8 @@
  */
 
 #include "pddl_robot_memory_thread.h"
+#include <fstream>
+#include <utils/misc/string_conversions.h>
 
 using namespace fawkes;
 
@@ -39,6 +41,44 @@ PddlRobotMemoryThread::PddlRobotMemoryThread()
 void
 PddlRobotMemoryThread::init()
 {
+  //read config values
+  collection = config->get_string("plugins/pddl-robot-memory/collection");
+  input_path = StringConversions::resolve_path("@BASEDIR@/src/agents/" +
+    config->get_string("plugins/pddl-robot-memory/input-problem-description"));
+  output_path = StringConversions::resolve_path("@BASEDIR@/src/agents/" +
+    config->get_string("plugins/pddl-robot-memory/output-problem-description"));
+
+  //read input template of problem description
+  std::string input;
+  std::ifstream istream(input_path);
+  if(istream.is_open())
+  {
+    input = std::string((std::istreambuf_iterator<char>(istream)), std::istreambuf_iterator<char>());
+    istream.close();
+  }
+  else
+  {
+    logger->log_error(name(), "Could not open %s", input_path.c_str());
+  }
+
+  //TODO: expand template
+  std::string output = input;
+
+  //generate output
+  logger->log_info(name(), "Output:\n%s", output.c_str());
+  logger->log_info(name(), "opening: %s", input_path.c_str());
+  std::ofstream ostream(output_path);
+  if(ostream.is_open())
+  {
+    ostream << output.c_str();
+    ostream.close();
+  }
+  else
+  {
+    logger->log_error(name(), "Could not open %s", output_path.c_str());
+  }
+
+  logger->log_info(name(), "Generation of PDDL problem description finished");
 }
 
 void
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h
index fe21f91..53b0dad 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h
@@ -29,6 +29,7 @@
 #include <aspect/logging.h>
 #include <aspect/blackboard.h>
 #include <aspect/configurable.h>
+#include <plugins/robot-memory/aspect/robot_memory_aspect.h>
 
 #include <string>
 
@@ -40,7 +41,8 @@ class PddlRobotMemoryThread
   public fawkes::BlockedTimingAspect,
   public fawkes::LoggingAspect,
   public fawkes::ConfigurableAspect,
-  public fawkes::BlackBoardAspect
+  public fawkes::BlackBoardAspect,
+  public fawkes::RobotMemoryAspect
 {
 
  public:
@@ -54,9 +56,11 @@ class PddlRobotMemoryThread
   protected: virtual void run() { Thread::run(); }
 
  private:
-  //Define class member variables here
+  std::string collection;
+  std::string input_path;
+  std::string output_path;
 
 };
 
 
-#endif
\ No newline at end of file
+#endif

- *commit* 954978e4960c16dbb36a79afe4af5e85a150e6a6 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 13 19:39:36 2016 +0200
Subject: pddl-robot-memory: use ctemplate as template engine for generating .pddl

 src/plugins/pddl-robot-memory/Makefile             |   16 ++++++++----
 .../protobuf.mk => pddl-robot-memory/ctemplate.mk} |   25 ++++++++-----------
 .../pddl-robot-memory/pddl_robot_memory_thread.cpp |    7 ++++-
 3 files changed, 28 insertions(+), 20 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/pddl-robot-memory/Makefile b/src/plugins/pddl-robot-memory/Makefile
index fbfa08b..fcc15df 100644
--- a/src/plugins/pddl-robot-memory/Makefile
+++ b/src/plugins/pddl-robot-memory/Makefile
@@ -17,6 +17,7 @@
 BASEDIR = ../../..
 include $(BASEDIR)/etc/buildsys/config.mk
 include $(BASEDIR)/src/plugins/mongodb/mongodb.mk
+include $(BASEDIR)/src/plugins/pddl-robot-memory/ctemplate.mk
 
 LIBS_pddl_robot_memory = m fawkescore fawkesutils fawkesaspects fawkesbaseapp \
                       fawkesblackboard fawkesinterface fawkesrobotmemory
@@ -26,8 +27,9 @@ OBJS_pddl_robot_memory = pddl_robot_memory_plugin.o pddl_robot_memory_thread.o
 
 OBJS_all = $(OBJS_pddl_robot_memory)
 
-ifeq ($(HAVE_CPP11)$(HAVE_MONGODB),11)
+ifeq ($(HAVE_CPP11)$(HAVE_MONGODB)$(HAVE_CTEMPLATE),111)
   CFLAGS  += $(CFLAGS_CPP11)
+  LDFLAGS += $(LDFLAGS_CTEMPLATE)
 
   PLUGINS_all = $(PLUGINDIR)/pddl-robot-memory.$(SOEXT)	  
 else
@@ -37,17 +39,21 @@ else
   ifneq ($(HAVE_TF),1)
     WARN_TARGETS = warning_mongodb
   endif
+  ifneq ($(HAVE_CTEMPLATE),1)
+    WARN_TARGETS = warning_ctemplate
+  endif
 endif
 
 ifeq ($(OBJSSUBMAKE),1)
 all: $(WARN_TARGETS)
 
-.PHONY: warning_tf warning_clips warning_cpp11
+.PHONY: warning_tf warning_ctemplate warning_cpp11
 warning_mongodb:
-	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting clips-robot-memory plugin$(TNORMAL) (mongodb not available)"
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting pddl-robot-memory plugin$(TNORMAL) (mongodb not available)"
 warning_cpp11:
-	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Cannot build clips-robot-memory plugin$(TNORMAL) (C++11 not supported)"
-
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Cannot build pddl-robot-memory plugin$(TNORMAL) (C++11 not supported)"
+warning_ctemplate:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Cannot build pddl-robot-memory plugin$(TNORMAL) (ctemplate-devel not installed)"
 endif
 
 include $(BUILDSYSDIR)/base.mk
\ No newline at end of file
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
index 8edfd10..b93b35f 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
@@ -24,6 +24,7 @@
 #include "pddl_robot_memory_thread.h"
 #include <fstream>
 #include <utils/misc/string_conversions.h>
+#include <ctemplate/template.h>
 
 using namespace fawkes;
 
@@ -62,7 +63,11 @@ PddlRobotMemoryThread::init()
   }
 
   //TODO: expand template
-  std::string output = input;
+  ctemplate::StringToTemplateCache("tpl-cache", input, ctemplate::DO_NOT_STRIP);
+  ctemplate::TemplateDictionary dict("pddl-rm");
+  dict.SetValue("TEST", "EXPANDED TEST");
+  std::string output;
+  ctemplate::ExpandTemplate("tpl-cache", ctemplate::DO_NOT_STRIP, &dict, &output);
 
   //generate output
   logger->log_info(name(), "Output:\n%s", output.c_str());

- *commit* 2c98f1d7156bf1b584978ca8a0a6b449efd5741c - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Oct 14 00:16:52 2016 +0200
Subject: pddl-robot-memory: generic templates to query robot memory and fill

 .../pddl-robot-memory/pddl_robot_memory_thread.cpp |  109 +++++++++++++++++++-
 .../pddl-robot-memory/pddl_robot_memory_thread.h   |    4 +
 2 files changed, 108 insertions(+), 5 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
index b93b35f..3b11cbe 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
@@ -24,12 +24,31 @@
 #include "pddl_robot_memory_thread.h"
 #include <fstream>
 #include <utils/misc/string_conversions.h>
-#include <ctemplate/template.h>
 
 using namespace fawkes;
+using namespace mongo;
 
 /** @class PddlRobotMemoryThread 'pddl_robot_memory_thread.h' 
  * Generate PDDL files from the robot memory
+ *
+ * This plugin uses the template engine ctemplate to generate a pddl
+ * from a template file and the robot memory.
+ *
+ * The template file can use the following templates to generate some output
+ * for each document returned by a query:
+ *
+ * Example: <<#ONTABLE|{relation:'on-table'}>> (on-table <<object>>) <</ONTABLE>>
+ * Yields: (on-table a) (on-table b)
+ * When these documents are in the database:
+ *  {relation:'on-table', object:'a'}, {relation:'on-table', object:'b'}
+ *
+ * The selection template <<#UNIQUENAME|query>> something <</UNIQUENAME>>
+ *  queries the robot memory and inserts 'something' for each returned document.
+ *
+ * Variable templates <<key>> inside the selection are substituted by the values
+ *  of that key in the document returned by the query. You can also access subdocuments
+ *  (e.g. <<position.orientation.yaw>> )
+ *
  * @author Frederik Zwilling
  */
 
@@ -61,17 +80,56 @@ PddlRobotMemoryThread::init()
   {
     logger->log_error(name(), "Could not open %s", input_path.c_str());
   }
+  //set template delimeters to << >>
+  input = "{{=<< >>=}}" +  input;
 
-  //TODO: expand template
-  ctemplate::StringToTemplateCache("tpl-cache", input, ctemplate::DO_NOT_STRIP);
+  //Dictionary how to fill the templates
   ctemplate::TemplateDictionary dict("pddl-rm");
-  dict.SetValue("TEST", "EXPANDED TEST");
+
+  //find queries in template
+  size_t cur_pos = 0;
+  while(input.find("<<#", cur_pos) != std::string::npos)
+  {
+    cur_pos = input.find("<<#", cur_pos) + 3;
+    size_t tpl_end_pos =  input.find(">>", cur_pos);
+    //is a query in the template? (indicated by '|')
+    size_t q_del_pos = input.find("|", cur_pos);
+    if(q_del_pos == std::string::npos || q_del_pos > tpl_end_pos)
+      continue; //no query to execute
+    //parse: template name | query
+    std::string template_name = input.substr(cur_pos, q_del_pos - cur_pos);
+    std::string query_str =  input.substr(q_del_pos + 1, tpl_end_pos - (q_del_pos + 1));
+    //remove query stuff from input (its not part of the ctemplate features)
+    input.erase(q_del_pos, tpl_end_pos - q_del_pos);
+
+    //fill dictionary to expand query template:
+    QResCursor cursor = robot_memory->query(fromjson(query_str), collection);
+    while(cursor->more())
+    {
+      BSONObj obj = cursor->next();
+      //dictionary for one entry
+      ctemplate::TemplateDictionary *entry_dict = dict.AddSectionDictionary(template_name);
+      fill_dict_from_document(entry_dict, obj);
+    }
+  }
+
+  //prepare template expanding
+  ctemplate::StringToTemplateCache("tpl-cache", input, ctemplate::DO_NOT_STRIP);
+  if(!ctemplate::TemplateNamelist::IsAllSyntaxOkay(ctemplate::DO_NOT_STRIP))
+  {
+    logger->log_error(name(), "Syntax error in template %s:", input_path.c_str());
+    std::vector<std::string> error_list = ctemplate::TemplateNamelist::GetBadSyntaxList(false, ctemplate::DO_NOT_STRIP);
+    for(std::string error : error_list)
+    {
+      logger->log_error(name(), "", error.c_str());
+    }
+  }
+  //Let ctemplate expand the input
   std::string output;
   ctemplate::ExpandTemplate("tpl-cache", ctemplate::DO_NOT_STRIP, &dict, &output);
 
   //generate output
   logger->log_info(name(), "Output:\n%s", output.c_str());
-  logger->log_info(name(), "opening: %s", input_path.c_str());
   std::ofstream ostream(output_path);
   if(ostream.is_open())
   {
@@ -96,3 +154,44 @@ PddlRobotMemoryThread::finalize()
 {
 }
 
+/**
+ * Fills a dictionary with key value pairs from a document. Recursive to handle subdocuments
+ * @param dict Dictionary to fill
+ * @param obj Document
+ * @param prefix Prefix of previous super-documents keys
+ */
+void PddlRobotMemoryThread::fill_dict_from_document(ctemplate::TemplateDictionary *dict, mongo::BSONObj obj, std::string prefix)
+{
+  for(BSONObjIterator it = obj.begin(); it.more();)
+  {
+    BSONElement elem = it.next();
+    switch (elem.type()) {
+      case mongo::NumberDouble:
+        dict->SetValue(prefix + elem.fieldName(), std::to_string(elem.Double()));
+        break;
+      case mongo::String:
+        dict->SetValue(prefix + elem.fieldName(), elem.String());
+        break;
+      case mongo::Bool:
+        dict->SetValue(prefix + elem.fieldName(), std::to_string(elem.Bool()));
+        break;
+      case mongo::NumberInt:
+        dict->SetIntValue(prefix + elem.fieldName(), elem.Int());
+        break;
+      case mongo::NumberLong:
+        dict->SetValue(prefix + elem.fieldName(), std::to_string(elem.Long()));
+        break;
+      case mongo::Object:
+        fill_dict_from_document(dict, elem.Obj(), prefix + elem.fieldName() + ".");
+        break;
+      case 7: //ObjectId
+      dict->SetValue(prefix + elem.fieldName(), elem.OID().toString());
+      break;
+      //TODO: array
+
+      default:
+        dict->SetValue(prefix + elem.fieldName(), "INVALID_VALUE_TYPE");
+    }
+  }
+}
+
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h
index 53b0dad..a04bc8a 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h
@@ -33,6 +33,8 @@
 
 #include <string>
 
+#include <ctemplate/template.h>
+
 namespace fawkes {
 }
 
@@ -60,6 +62,8 @@ class PddlRobotMemoryThread
   std::string input_path;
   std::string output_path;
 
+  void fill_dict_from_document(ctemplate::TemplateDictionary *dict, mongo::BSONObj obj, std::string prefix = "");
+
 };
 
 

- *commit* a187e9436902f4615b86c80e6b0bda1be6069732 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Oct 14 13:12:41 2016 +0200
Subject: pddl-robot-memory: changed delimiter to access subdocuments to '_'

 .../pddl-robot-memory/pddl_robot_memory_thread.cpp |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
index 3b11cbe..fdd2560 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
@@ -182,7 +182,7 @@ void PddlRobotMemoryThread::fill_dict_from_document(ctemplate::TemplateDictionar
         dict->SetValue(prefix + elem.fieldName(), std::to_string(elem.Long()));
         break;
       case mongo::Object:
-        fill_dict_from_document(dict, elem.Obj(), prefix + elem.fieldName() + ".");
+        fill_dict_from_document(dict, elem.Obj(), prefix + elem.fieldName() + "_");
         break;
       case 7: //ObjectId
       dict->SetValue(prefix + elem.fieldName(), elem.OID().toString());

- *commit* 0392e9ea56be48a5376b8803d27ff778d362ca36 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Oct 14 13:40:23 2016 +0200
Subject: pddl-robot-memory: allow accessing arrays in templates

 .../pddl-robot-memory/pddl_robot_memory_thread.cpp |   23 ++++++++++++++-----
 1 files changed, 17 insertions(+), 6 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
index fdd2560..93499f1 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
@@ -47,7 +47,8 @@ using namespace mongo;
  *
  * Variable templates <<key>> inside the selection are substituted by the values
  *  of that key in the document returned by the query. You can also access subdocuments
- *  (e.g. <<position.orientation.yaw>> )
+ *  and arrays as follows:
+ *  (e.g. <<position_translation_0>> for a document {position:{translation:[0,1,2], orientation:[0,1,2]}})
  *
  * @author Frederik Zwilling
  */
@@ -160,7 +161,7 @@ PddlRobotMemoryThread::finalize()
  * @param obj Document
  * @param prefix Prefix of previous super-documents keys
  */
-void PddlRobotMemoryThread::fill_dict_from_document(ctemplate::TemplateDictionary *dict, mongo::BSONObj obj, std::string prefix)
+void PddlRobotMemoryThread::fill_dict_from_document(ctemplate::TemplateDictionary *dict, BSONObj obj, std::string prefix)
 {
   for(BSONObjIterator it = obj.begin(); it.more();)
   {
@@ -185,10 +186,20 @@ void PddlRobotMemoryThread::fill_dict_from_document(ctemplate::TemplateDictionar
         fill_dict_from_document(dict, elem.Obj(), prefix + elem.fieldName() + "_");
         break;
       case 7: //ObjectId
-      dict->SetValue(prefix + elem.fieldName(), elem.OID().toString());
-      break;
-      //TODO: array
-
+        dict->SetValue(prefix + elem.fieldName(), elem.OID().toString());
+        break;
+      case mongo::Array:
+      {
+        // access array elements as if they were a subdocument with key-value pairs
+        // using the indices as keys
+        BSONObjBuilder b;
+        for(size_t i = 0; i < elem.Array().size(); i++)
+        {
+          b.append(elem.Array()[i]);
+        }
+        fill_dict_from_document(dict, b.obj(), prefix + elem.fieldName() + "_");
+        break;
+      }
       default:
         dict->SetValue(prefix + elem.fieldName(), "INVALID_VALUE_TYPE");
     }

- *commit* 739faeb8bfd503319df9a84a0958a7b4ad989e89 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Oct 14 16:26:49 2016 +0200
Subject: pddl-robot-memory: generate pddl on interface message

 src/plugins/pddl-robot-memory/Makefile             |    5 ++-
 .../interfaces/Makefile                            |    0
 .../interfaces/PddlGenInterface.xml                |   21 +++++++++++
 .../pddl-robot-memory/pddl_robot_memory_thread.cpp |   38 +++++++++++++++++--
 .../pddl-robot-memory/pddl_robot_memory_thread.h   |   12 +++++--
 5 files changed, 68 insertions(+), 8 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/pddl-robot-memory/Makefile b/src/plugins/pddl-robot-memory/Makefile
index fcc15df..1cc05f9 100644
--- a/src/plugins/pddl-robot-memory/Makefile
+++ b/src/plugins/pddl-robot-memory/Makefile
@@ -19,8 +19,11 @@ include $(BASEDIR)/etc/buildsys/config.mk
 include $(BASEDIR)/src/plugins/mongodb/mongodb.mk
 include $(BASEDIR)/src/plugins/pddl-robot-memory/ctemplate.mk
 
+PRESUBDIRS = interfaces
+
 LIBS_pddl_robot_memory = m fawkescore fawkesutils fawkesaspects fawkesbaseapp \
-                      fawkesblackboard fawkesinterface fawkesrobotmemory
+                      fawkesblackboard fawkesinterface fawkesrobotmemory \
+                      PddlGenInterface
 
 OBJS_pddl_robot_memory = pddl_robot_memory_plugin.o pddl_robot_memory_thread.o
 
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
index 93499f1..300c448 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
@@ -55,7 +55,7 @@ using namespace mongo;
 
 PddlRobotMemoryThread::PddlRobotMemoryThread()
  : Thread("PddlRobotMemoryThread", Thread::OPMODE_WAITFORWAKEUP),
-             BlockedTimingAspect(BlockedTimingAspect::WAKEUP_HOOK_SKILL) 
+   BlackBoardInterfaceListener("NavGraphGeneratorThread")
 {
 }
 
@@ -69,6 +69,23 @@ PddlRobotMemoryThread::init()
   output_path = StringConversions::resolve_path("@BASEDIR@/src/agents/" +
     config->get_string("plugins/pddl-robot-memory/output-problem-description"));
 
+  //setup interface
+  gen_if = blackboard->open_for_writing<PddlGenInterface>(config->get_string("plugins/pddl-robot-memory/interface-name").c_str());
+  gen_if->set_msg_id(0);
+  gen_if->set_final(false);
+  gen_if->write();
+
+  //setup interface listener
+  bbil_add_message_interface(gen_if);
+  blackboard->register_listener(this, BlackBoard::BBIL_FLAG_MESSAGES);
+}
+
+/**
+ * Thread is only waked up if there is a new interface message to generate a pddl
+ */
+void
+PddlRobotMemoryThread::loop()
+{
   //read input template of problem description
   std::string input;
   std::ifstream istream(input_path);
@@ -143,16 +160,29 @@ PddlRobotMemoryThread::init()
   }
 
   logger->log_info(name(), "Generation of PDDL problem description finished");
+  gen_if->set_final(true);
+  gen_if->write();
 }
 
 void
-PddlRobotMemoryThread::loop()
+PddlRobotMemoryThread::finalize()
 {
+  blackboard->close(gen_if);
 }
 
-void
-PddlRobotMemoryThread::finalize()
+bool
+PddlRobotMemoryThread::bb_interface_message_received(Interface *interface, fawkes::Message *message) throw()
 {
+  if (message->is_of_type<PddlGenInterface::GenerateMessage>()) {
+      gen_if->set_msg_id(message->id());
+      gen_if->set_final(false);
+      gen_if->write();
+      wakeup(); //activates loop where the generation is done
+    } else {
+      logger->log_error(name(), "Received unknown message of type %s, ignoring",
+            message->type());
+    }
+  return false;
 }
 
 /**
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h
index a04bc8a..6c17ee1 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.h
@@ -25,26 +25,27 @@
 #define __PLUGINS_PDDL_ROBOT_MEMORYTHREAD_H_
 
 #include <core/threading/thread.h>
-#include <aspect/blocked_timing.h>
 #include <aspect/logging.h>
 #include <aspect/blackboard.h>
 #include <aspect/configurable.h>
 #include <plugins/robot-memory/aspect/robot_memory_aspect.h>
+#include <blackboard/interface_listener.h>
 
 #include <string>
 
 #include <ctemplate/template.h>
+#include "interfaces/PddlGenInterface.h"
 
 namespace fawkes {
 }
 
 class PddlRobotMemoryThread 
 : public fawkes::Thread,
-  public fawkes::BlockedTimingAspect,
   public fawkes::LoggingAspect,
   public fawkes::ConfigurableAspect,
   public fawkes::BlackBoardAspect,
-  public fawkes::RobotMemoryAspect
+  public fawkes::RobotMemoryAspect,
+  public fawkes::BlackBoardInterfaceListener
 {
 
  public:
@@ -58,12 +59,17 @@ class PddlRobotMemoryThread
   protected: virtual void run() { Thread::run(); }
 
  private:
+  fawkes::PddlGenInterface *gen_if;
+
   std::string collection;
   std::string input_path;
   std::string output_path;
 
   void fill_dict_from_document(ctemplate::TemplateDictionary *dict, mongo::BSONObj obj, std::string prefix = "");
+  void generate();
 
+  virtual bool bb_interface_message_received(fawkes::Interface *interface,
+                                             fawkes::Message *message) throw();
 };
 
 

- *commit* b51bde4fa296db3f89748792b68d9a8a7538d606 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Oct 14 16:33:58 2016 +0200
Subject: pddl-robot-memory: config to generate pddl on init

 .../pddl-robot-memory/pddl_robot_memory_thread.cpp |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
index 300c448..d95248d 100644
--- a/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
+++ b/src/plugins/pddl-robot-memory/pddl_robot_memory_thread.cpp
@@ -78,6 +78,11 @@ PddlRobotMemoryThread::init()
   //setup interface listener
   bbil_add_message_interface(gen_if);
   blackboard->register_listener(this, BlackBoard::BBIL_FLAG_MESSAGES);
+
+  if(config->get_bool("plugins/pddl-robot-memory/generate-on-init"))
+  {
+    wakeup(); //activates loop where the generation is done
+  }
 }
 
 /**

- *commit* b62ac089bc9b1e4776d5c2ef72c56cb92d826cb3 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Oct 18 18:25:35 2016 +0200
Subject: robot-memory: improved documentation

 .../clips-robot-memory/clips_rm_trigger.cpp        |    5 +-
 src/plugins/robot-memory/event_trigger_manager.h   |    9 ++-
 src/plugins/robot-memory/robot_memory.cpp          |   78 ++++++++++++++++++++
 src/plugins/robot-memory/robot_memory.h            |    3 -
 4 files changed, 88 insertions(+), 7 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/clips_rm_trigger.cpp b/src/plugins/clips-robot-memory/clips_rm_trigger.cpp
index ad8aba5..fb635c5 100644
--- a/src/plugins/clips-robot-memory/clips_rm_trigger.cpp
+++ b/src/plugins/clips-robot-memory/clips_rm_trigger.cpp
@@ -49,6 +49,7 @@ void ClipsRmTrigger::set_trigger(EventTrigger *trigger)
 
 /**
  * Callback function for the trigger. Asserts a fact about the update with the assert_name and updated object.
+ * When you retract the fact about the update, also call bson-destroy on the included pointer to avoid memory leaks.
  * @param update updated object
  */
 void ClipsRmTrigger::callback(mongo::BSONObj update)
@@ -70,9 +71,7 @@ void ClipsRmTrigger::callback(mongo::BSONObj update)
     fact->set_slot("ptr", CLIPS::Value(ptr));
     CLIPS::Fact::pointer new_fact = clips->assert_fact(fact);
 
-    if (new_fact) {
-      //TODO: msg_facts_[new_fact->index()] = new_fact;
-    } else {
+    if (!new_fact) {
       logger->log_warn("CLIPS-RobotMemory", "Asserting robmem-trigger fact failed");
       delete static_cast<BSONObjBuilder *>(ptr);
     }
diff --git a/src/plugins/robot-memory/event_trigger_manager.h b/src/plugins/robot-memory/event_trigger_manager.h
index f25253d..6b872c5 100644
--- a/src/plugins/robot-memory/event_trigger_manager.h
+++ b/src/plugins/robot-memory/event_trigger_manager.h
@@ -45,6 +45,14 @@ class EventTriggerManager
     EventTriggerManager(fawkes::Logger* logger, fawkes::Configuration* config);
     virtual ~EventTriggerManager();
 
+    /**
+     * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
+     * @param query Query the updated document has to match
+     * @param collection db.collection to use
+     * @param callback Callback function (e.g. &Class::callback)
+     * @param _obj Pointer to class the callback is a function of (usaually this)
+     * @return Trigger object pointer, save it to remove the trigger later
+     */
     template<typename T>
     EventTrigger* register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *obj)
     {
@@ -80,7 +88,6 @@ class EventTriggerManager
       return trigger;
     }
 
-
     void remove_trigger(EventTrigger* trigger);
 
   private:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index e48d09a..9646e11 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -35,6 +35,23 @@
 using namespace mongo;
 using namespace fawkes;
 
+/** @class RobotMemory "robot_memory.h"
+ * Access to the robot memory based on mongodb.
+ * Using this class, you can query/insert/remove/update information in the robot memory.
+ * Furthermore, you can register trigger to get notified when something was changed in the robot memory matching your query
+ * and you can access computables, which are on demand computed information, by registering the computables
+ * and then querying as if the information would already be in the database.
+ * @author Frederik Zwilling
+ */
+
+/**
+ * Robot Memory Constructor
+ * @param config Fawkes config
+ * @param logger Fawkes logger
+ * @param clock Fawkes clock
+ * @param mongodb_client Fawkes mongo client from the mongo aspect
+ * @param blackboard Fawkes blackboard
+ */
 RobotMemory::RobotMemory(fawkes::Configuration* config, fawkes::Logger* logger,
    fawkes::Clock* clock, mongo::DBClientBase* mongodb_client,
    fawkes::BlackBoard* blackboard)
@@ -88,6 +105,12 @@ void RobotMemory::loop()
   trigger_manager_->check_events();
 }
 
+/**
+ * Query information from the robot memory.
+ * @param query The query returned documents have to match (essentially a BSONObj)
+ * @param collection The database and collection to query as string (e.g. robmem.worldmodel)
+ * @return Cursor to get the documents from, NULL for invalid query
+ */
 QResCursor RobotMemory::query(Query query, std::string collection)
 {
   check_collection_name(collection);
@@ -129,6 +152,12 @@ QResCursor RobotMemory::query(Query query, std::string collection)
   return cursor;
 }
 
+/**
+ * Inserts a document into the robot memory
+ * @param obj The document as BSONObj
+ * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
+ * @return 1: Success 0: Error
+ */
 int RobotMemory::insert(BSONObj obj, std::string collection)
 {
   check_collection_name(collection);
@@ -151,11 +180,25 @@ int RobotMemory::insert(BSONObj obj, std::string collection)
   return 1;
 }
 
+/**
+ * Inserts a document into the robot memory
+ * @param obj_str The document as json string
+ * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
+ * @return 1: Success 0: Error
+ */
 int RobotMemory::insert(std::string obj_str, std::string collection)
 {
   return insert(fromjson(obj_str), collection);
 }
 
+/**
+ * Updates documents in the robot memory
+ * @param query The query defining which documents to update
+ * @param update What to change in these documents
+ * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
+ * @param upsert Should the update document be inserted if the query returns no documents?
+ * @return 1: Success 0: Error
+ */
 int RobotMemory::update(Query query, BSONObj update, std::string collection, bool upsert)
 {
   check_collection_name(collection);
@@ -175,11 +218,25 @@ int RobotMemory::update(Query query, BSONObj update, std::string collection, boo
   return 1;
 }
 
+/**
+ * Updates documents in the robot memory
+ * @param query The query defining which documents to update
+ * @param update_str What to change in these documents as json string
+ * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
+ * @param upsert Should the update document be inserted if the query returns no documents?
+ * @return 1: Success 0: Error
+ */
 int RobotMemory::update(Query query, std::string update_str, std::string collection, bool upsert)
 {
   return update(query, fromjson(update_str), collection, upsert);
 }
 
+/**
+ * Remove documents from the robot memory
+ * @param query Which documents to remove
+ * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
+ * @return 1: Success 0: Error
+ */
 int RobotMemory::remove(Query query, std::string collection)
 {
   check_collection_name(collection);
@@ -199,12 +256,21 @@ int RobotMemory::remove(Query query, std::string collection)
   return 1;
 }
 
+/**
+ * Drop (= remove) a whole collection and all documents inside it
+ * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
+ * @return 1: Success 0: Error
+ */
 int RobotMemory::drop_collection(std::string collection)
 {
   log_deb("Clearing whole robot memory");
   return remove("{}", collection);
 }
 
+/**
+ * Remove the whole database of the robot memory and all documents inside
+ * @return 1: Success 0: Error
+ */
 int RobotMemory::clear_memory()
 {
   log_deb("Clearing whole robot memory");
@@ -212,6 +278,12 @@ int RobotMemory::clear_memory()
   return 1;
 }
 
+/**
+ * Restore a previously dumped collection from a directory
+ * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
+ * @param directory Directory of the dump
+ * @return 1: Success 0: Error
+ */
 int RobotMemory::restore_collection(std::string collection, std::string directory)
 {
   drop_collection(collection);
@@ -258,6 +330,12 @@ int RobotMemory::restore_collection(std::string collection, std::string director
   return 1;
 }
 
+/**
+ * Dump (= save) a collection to the filesystem to restore it later
+ * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
+ * @param directory Directory to dump the collection to
+ * @return 1: Success 0: Error
+ */
 int RobotMemory::dump_collection(std::string collection, std::string directory)
 {
   //resolve path to dump to
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index f3046b5..ac271d3 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -39,9 +39,6 @@ namespace fawkes {
 ///typedef for shorter type description
 typedef std::unique_ptr<mongo::DBClientCursor> QResCursor;
 
-/**
- *
- */
 class RobotMemory
 {
   friend class RobotMemoryThread;

- *commit* 55ccedd5c700cfd6aa1c8bbb6f92459770eeb954 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Oct 21 21:37:29 2016 +0200
Subject: robot-memory: class and api skeleton for computables

 .../robot-memory/computable.cpp}                   |   27 +++++---
 .../plugin.h => robot-memory/computable.h}         |   24 +++----
 ...t_memory_aspect.cpp => computables_manager.cpp} |   44 ++++++-------
 src/plugins/robot-memory/computables_manager.h     |   65 ++++++++++++++++++++
 src/plugins/robot-memory/robot_memory.cpp          |   12 +++-
 src/plugins/robot-memory/robot_memory.h            |   18 +++++-
 .../robot-memory/test-plugin/robot_memory_test.cpp |    8 +++
 .../robot-memory/test-plugin/robot_memory_test.h   |   15 +++++
 8 files changed, 164 insertions(+), 49 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 9646e11..123028c 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -94,8 +94,9 @@ void RobotMemory::init()
   rm_if_->set_result("");
   rm_if_->write();
 
-  //Setup event trigger manager
+  //Setup event trigger and computables manager
   trigger_manager_ = new EventTriggerManager(logger_, config_);
+  computables_manager_ = new ComputablesManager(logger_, config_, mongodb_client_, clock_);
 
   log_deb("Initialized RobotMemory");
 }
@@ -504,3 +505,12 @@ void RobotMemory::remove_trigger(EventTrigger* trigger)
 {
   trigger_manager_->remove_trigger(trigger);
 }
+
+/**
+ * Remove previously registered computable
+ * @param computable The computable to remove
+ */
+void RobotMemory::remove_computable(Computable* computable)
+{
+  computables_manager_->remove_computable(computable);
+}
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index ac271d3..3c6cfe5 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -30,6 +30,7 @@
 #include <mongo/client/dbclient.h>
 #include "interfaces/RobotMemoryInterface.h"
 #include "event_trigger_manager.h"
+#include "computables_manager.h"
 
 namespace fawkes {
   class Mutex;
@@ -87,9 +88,23 @@ class RobotMemory
     {
       return register_trigger(mongo::fromjson(query_str), collection, callback);
     }
-
     void remove_trigger(EventTrigger* trigger);
 
+    /**
+     * Registers a Computable which provides information in the robot memory that is computed on demand.
+     *
+     * @param identifyer BSONObj describing what the function computes. Yor computable is called when an new query matches the key value fields in the identifiyer.
+     * @param compute_func Callback function that computes the information
+     * @param obj Pointer to class the callback is a function of (usaually this)
+     * @return Computable Object pointer used for removing it
+     */
+    template<typename T>
+    Computable* register_computable(mongo::BSONObj identifyer, void(T::*compute_func)(mongo::BSONObj), T *obj)
+    {
+      return computables_manager_->register_computable(identifyer, compute_func, obj);
+    }
+    void remove_computable(Computable* computable);
+
   private:
     mongo::DBClientBase* mongodb_client_;
     fawkes::Configuration* config_;
@@ -104,6 +119,7 @@ class RobotMemory
     fawkes::Mutex *mutex_;
     fawkes::RobotMemoryInterface* rm_if_;
     EventTriggerManager* trigger_manager_;
+    ComputablesManager* computables_manager_;
 
     void init();
     void loop();
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index 9714625..3ea632a 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -224,3 +224,11 @@ TEST_F(RobotMemoryTest, EventTriggerReplica)
   }
   return ::testing::AssertionSuccess();
 }
+
+
+TEST_F(RobotMemoryTest, ComputableRegisterRemove)
+{
+  TestComputable* tc = new TestComputable();
+  Computable* comp = robot_memory->register_computable(fromjson("{somekey:'value'}"), &TestComputable::compute, tc);
+  robot_memory->remove_computable(comp);
+}
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.h b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
index 665b1c1..cd2b173 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
@@ -73,5 +73,20 @@ class RobotMemoryCallback
    }
 };
 
+/**
+ * Class providing a computable function
+ */
+class TestComputable
+{
+  public:
+    TestComputable()
+  {
+  };
+   ~TestComputable(){};
+   void compute(mongo::BSONObj query)
+   {
+   }
+};
+
 
 #endif

- *commit* c81310b8157eb0226bec32a96d82789d152f7c47 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 27 19:39:23 2016 +0200
Subject: robot-memory: registering, checking, and executing computables

 src/plugins/robot-memory/computable.cpp            |   49 ++++++++++++++-
 src/plugins/robot-memory/computable.h              |   14 ++++-
 src/plugins/robot-memory/computables_manager.cpp   |   67 ++++++++++++++++++++
 src/plugins/robot-memory/computables_manager.h     |   20 ++++--
 src/plugins/robot-memory/robot_memory.cpp          |   19 +-----
 src/plugins/robot-memory/robot_memory.h            |    9 ++-
 .../robot-memory/test-plugin/robot_memory_test.cpp |   13 ++++-
 .../robot-memory/test-plugin/robot_memory_test.h   |    6 ++-
 8 files changed, 167 insertions(+), 30 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/computable.cpp b/src/plugins/robot-memory/computable.cpp
index ddf48e5..1b9e60b 100644
--- a/src/plugins/robot-memory/computable.cpp
+++ b/src/plugins/robot-memory/computable.cpp
@@ -21,17 +21,64 @@
 
 #include "computable.h"
 
+using namespace mongo;
+
 /** @class Computable  computable.h
  * Class holding information for a single computable
  * @author Frederik Zwilling
  */
 
-Computable::Computable()
+Computable::Computable(Query query_to_compute, std::string collection, const boost::function<std::list<BSONObj> (BSONObj)> &compute_function)
 {
+  this->compute_function = compute_function;
+  this->query_to_compute = query_to_compute;
+  this->collection = collection;
 }
 
 Computable::~Computable()
 {
 }
 
+/**
+ * Compute demanded information and insert it into the robot memory
+ * @param query The query demanding the computable information
+ * @param mongodb_client Client to use to insert computed documents
+ * @return Documents to insert extended with computable meta information (e.g. caching time)
+ */
+std::list<BSONObj> Computable::compute(BSONObj query)
+{
+  // use provided function to compute demanded documents
+  std::list<BSONObj> docs = compute_function(query);
+  //add metainformation for each document
+  for(BSONObj &obj : docs)
+  {
+    BSONObjBuilder info_b;
+    info_b.append("computed", true);
+    BSONObjBuilder obj_b;
+    obj_b.appendElements(obj);
+    obj_b.append("_robmem_info", info_b.obj());
+    //override
+    obj = obj_b.obj();
+  }
+  return docs;
+}
+
+/**
+ * Gets the query that defines what information is computed by the Computable
+ * @return The query
+ */
+mongo::Query Computable::get_query()
+{
+  return query_to_compute;
+}
+
+/**
+ * Gets the collection the computable adds information to
+ * @return The query
+ */
+std::string Computable::get_collection()
+{
+  return collection;
+}
+
 
diff --git a/src/plugins/robot-memory/computable.h b/src/plugins/robot-memory/computable.h
index 41e33dd..5232b69 100644
--- a/src/plugins/robot-memory/computable.h
+++ b/src/plugins/robot-memory/computable.h
@@ -22,11 +22,23 @@
 #ifndef FAWKES_SRC_PLUGINS_ROBOT_MEMORY_COMPUTABLE_H_
 #define FAWKES_SRC_PLUGINS_ROBOT_MEMORY_COMPUTABLE_H_
 
+#include <mongo/client/dbclient.h>
+#include <boost/function.hpp>
+
 class Computable
 {
   public:
-    Computable();
+    Computable(mongo::Query query_to_compute, std::string collection, const boost::function<std::list<mongo::BSONObj> (mongo::BSONObj)> &compute_function);
     virtual ~Computable();
+
+    std::list<mongo::BSONObj> compute(mongo::BSONObj query);
+    mongo::Query get_query();
+    std::string get_collection();
+
+  private:
+    boost::function<std::list<mongo::BSONObj> (mongo::BSONObj)> compute_function;
+    mongo::Query query_to_compute;
+    std::string collection;
 };
 
 #endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_COMPUTABLE_H_ */
diff --git a/src/plugins/robot-memory/computables_manager.cpp b/src/plugins/robot-memory/computables_manager.cpp
index b976fe1..da8189c 100644
--- a/src/plugins/robot-memory/computables_manager.cpp
+++ b/src/plugins/robot-memory/computables_manager.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "computables_manager.h"
+#include <core/exception.h>
 
 /** @class ComputablesManager  computables_manager.h
  *  This class manages registering computables and can check
@@ -27,6 +28,9 @@
  * @author Frederik Zwilling
  */
 
+using namespace fawkes;
+using namespace mongo;
+
 ComputablesManager::ComputablesManager(fawkes::Logger* logger, fawkes::Configuration* config,
   mongo::DBClientBase* mongodb_client, fawkes::Clock* clock)
 {
@@ -34,6 +38,11 @@ ComputablesManager::ComputablesManager(fawkes::Logger* logger, fawkes::Configura
   config_ = config;
   mongodb_client_ = mongodb_client;
   clock_ = clock;
+
+  matching_test_collection_ = "robmem.computables_matching";
+  try {
+    matching_test_collection_ = config_->get_string("/plugins/robot-memory/database") + ".computables_matching";
+  } catch (Exception &e) {}
 }
 
 ComputablesManager::~ComputablesManager()
@@ -47,5 +56,63 @@ ComputablesManager::~ComputablesManager()
  */
 void ComputablesManager::remove_computable(Computable* computable)
 {
+  for(std::list<Computable*>::iterator it = computables.begin(); it != computables.end(); it++)
+  {
+    if((*it) == computable)
+    {
+      Computable* comp = *it;
+      computables.erase(it);
+      delete comp;
+      return;
+    }
+  }
+}
+
+
+/**
+ * Checks if computable knowledge is queried and calls the compute functions in this case
+ * @param query The query that might ask for computable knowledge
+ * @param collection The collection that is querried
+ * @return Were computed documents added?
+ */
+bool ComputablesManager::check_and_compute(mongo::Query query, std::string collection)
+{
+  //logger_->log_info(name.c_str(), "checking query: %s", query.toString().c_str());
+  bool added_computed_docs = false;
+  //check if the query is matched by the computable identifyer
+  //to do that we just insert the query as if it would be a document and query for it with the computable identifiers
+  mongodb_client_->dropCollection(matching_test_collection_);
+  mongodb_client_->insert(matching_test_collection_, query.obj);
+  for(std::list<Computable*>::iterator it = computables.begin(); it != computables.end(); it++)
+  {
+    if(collection == (*it)->get_collection() &&  mongodb_client_->query(matching_test_collection_, (*it)->get_query())->more())
+    {
+      std::list<BSONObj> computed_docs_list = (*it)->compute(query.obj);
+      if(computed_docs_list.size() > 0)
+      {
+        //move list into vector
+        std::vector<BSONObj> computed_docs_vector{ std::make_move_iterator(std::begin(computed_docs_list)),
+          std::make_move_iterator(std::end(computed_docs_list))};
+        mongodb_client_->insert((*it)->get_collection(), computed_docs_vector);
+        added_computed_docs = true;
+      }
+    }
+  }
+  if(added_computed_docs)
+  {
+    collections_to_cleanup.push_back(collection);
+  }
+  return added_computed_docs;
+}
 
+/**
+ * Clean up all collections containing documents computed on demand
+ */
+void ComputablesManager::cleanup_computed_docs()
+{
+  for(std::string collection : collections_to_cleanup)
+  {
+    mongodb_client_->remove(collection, fromjson("{'_robmem_info.computed':true}"));
+  }
+  collections_to_cleanup.clear();
 }
diff --git a/src/plugins/robot-memory/computables_manager.h b/src/plugins/robot-memory/computables_manager.h
index a98d34b..0c3a9da 100644
--- a/src/plugins/robot-memory/computables_manager.h
+++ b/src/plugins/robot-memory/computables_manager.h
@@ -27,6 +27,8 @@
 #include <aspect/configurable.h>
 #include <aspect/clock.h>
 #include "computable.h"
+#include <boost/bind.hpp>
+#include <utility>
 
 class ComputablesManager
 {
@@ -35,21 +37,25 @@ class ComputablesManager
       mongo::DBClientBase* mongodb_client, fawkes::Clock* clock);
     virtual ~ComputablesManager();
 
-    void check_and_compute(mongo::Query query);
+    bool check_and_compute(mongo::Query query, std::string collection);
     void remove_computable(Computable* computable);
+    void cleanup_computed_docs();
 
     /**
      * Registers a Computable which provides information in the robot memory that is computed on demand.
      *
-     * @param identifyer BSONObj describing what the function computes. Yor computable is called when an new query matches the key value fields in the identifiyer.
-     * @param compute_func Callback function that computes the information
+     * @param query_to_compute Query describing what the function computes. Yor computable is called when an new query matches query_to_compute.
+     * @param collection db.collection to fill with computed information
+     * @param compute_func Callback function that computes the information and retruns a list of computed documents
      * @param obj Pointer to class the callback is a function of (usaually this)
      * @return Computable Object pointer used for removing it
      */
     template<typename T>
-    Computable* register_computable(mongo::BSONObj identifyer, void(T::*compute_func)(mongo::BSONObj), T *obj)
+    Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj), T *obj)
     {
-      return NULL;
+      Computable* comp = new Computable(query_to_compute, collection, boost::bind(compute_func, obj, _1));
+      computables.push_back(comp);
+      return comp;
     }
 
   private:
@@ -59,7 +65,9 @@ class ComputablesManager
     mongo::DBClientBase* mongodb_client_;
     fawkes::Clock* clock_;
 
-    std::map<mongo::BSONObj, Computable*> computables;
+    std::list<Computable*> computables;
+    std::string matching_test_collection_;
+    std::list<std::string> collections_to_cleanup;
 };
 
 #endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_COMPUTABLES_COMPUTABLES_MANAGER_H_ */
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 123028c..bdeff5b 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -104,6 +104,7 @@ void RobotMemory::init()
 void RobotMemory::loop()
 {
   trigger_manager_->check_events();
+  computables_manager_->cleanup_computed_docs();
 }
 
 /**
@@ -120,22 +121,8 @@ QResCursor RobotMemory::query(Query query, std::string collection)
   //only one query at a time
   MutexLocker lock(mutex_);
 
-//  //introspect query
-//  log(query, "executing query:");
-
-//  //TODO: computation on demand
-//  //check if virtual knowledge is queried
-//  //rename field in query
-//  if(query.getFilter().hasField("class")){
-//    set_fields(query, std::string("{type:\"") +
-//               query.getFilter()["class"].String() + "\"}");
-//    remove_field(query, "class");
-//  }
-//
-//  if(query.getFilter().hasField("bbinterface")){
-//    collection = config->get_string("plugins/robot-memory/blackboard-collection");
-//    gen_blackboard_data(query.getFilter()["bbinterface"].String());
-//  }
+  //check if computation on demand is necessary and execute Computables
+  computables_manager_->check_and_compute(query, collection);
 
   //set read preference of query to nearest to read from the local replica set member first
   query.readPref(ReadPreference_Nearest, BSONArray());
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 3c6cfe5..163a788 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -93,15 +93,16 @@ class RobotMemory
     /**
      * Registers a Computable which provides information in the robot memory that is computed on demand.
      *
-     * @param identifyer BSONObj describing what the function computes. Yor computable is called when an new query matches the key value fields in the identifiyer.
-     * @param compute_func Callback function that computes the information
+     * @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.
+     * @param collection db.collection to fill with computed information
+     * @param compute_func Callback function that computes the information and retruns a list of computed documents
      * @param obj Pointer to class the callback is a function of (usaually this)
      * @return Computable Object pointer used for removing it
      */
     template<typename T>
-    Computable* register_computable(mongo::BSONObj identifyer, void(T::*compute_func)(mongo::BSONObj), T *obj)
+    Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj), T *obj)
     {
-      return computables_manager_->register_computable(identifyer, compute_func, obj);
+      return computables_manager_->register_computable(query_to_compute, collection, compute_func, obj);
     }
     void remove_computable(Computable* computable);
 
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index 3ea632a..c7ac7d7 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -229,6 +229,17 @@ TEST_F(RobotMemoryTest, EventTriggerReplica)
 TEST_F(RobotMemoryTest, ComputableRegisterRemove)
 {
   TestComputable* tc = new TestComputable();
-  Computable* comp = robot_memory->register_computable(fromjson("{somekey:'value'}"), &TestComputable::compute, tc);
+  Computable* comp = robot_memory->register_computable(fromjson("{somekey:'value'}"), "robmem.test", &TestComputable::compute, tc);
+  robot_memory->remove_computable(comp);
+}
+
+
+TEST_F(RobotMemoryTest, ComputableCall)
+{
+  TestComputable* tc = new TestComputable();
+  Computable* comp = robot_memory->register_computable(fromjson("{computed:true}"), "robmem.test", &TestComputable::compute, tc);
+  QResCursor qres = robot_memory->query(fromjson("{computed:true}"), "robmem.test");
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{result:'this is computed'}")));
   robot_memory->remove_computable(comp);
 }
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.h b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
index cd2b173..17a89ab 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
@@ -24,6 +24,7 @@
 
 #include <gtest/gtest.h>
 #include "plugins/robot-memory/robot_memory.h"
+#include <stdio.h>
 
 
 /** Environment for running Tests of the RobotMemory
@@ -83,8 +84,11 @@ class TestComputable
   {
   };
    ~TestComputable(){};
-   void compute(mongo::BSONObj query)
+   std::list<mongo::BSONObj> compute(mongo::BSONObj query)
    {
+     std::list<mongo::BSONObj> res;
+     res.push_back(mongo::fromjson("{computed:true, result:'this is computed'}"));
+     return res;
    }
 };
 

- *commit* 69b423a6c6f85f9448658d4643eaa855c96f2fe9 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 27 20:05:54 2016 +0200
Subject: robot-memory: computable unit test: addition and adding multiple docs

 .../robot-memory/test-plugin/robot_memory_test.cpp |   37 ++++++++++++++++++++
 .../robot-memory/test-plugin/robot_memory_test.h   |   21 +++++++++++
 2 files changed, 58 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index c7ac7d7..cfd0e3b 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -243,3 +243,40 @@ TEST_F(RobotMemoryTest, ComputableCall)
   ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{result:'this is computed'}")));
   robot_memory->remove_computable(comp);
 }
+
+
+TEST_F(RobotMemoryTest, ComputableCallAddition)
+{
+  TestComputable* tc = new TestComputable();
+  Computable* comp = robot_memory->register_computable(fromjson(
+      "{compute:'sum',x:{$exists:true},y:{$exists:true}}"), "robmem.test", &TestComputable::compute_sum, tc);
+  QResCursor qres = robot_memory->query(fromjson("{compute:'sum',x:15,y:4}"), "robmem.test");
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{sum:19}")));
+  robot_memory->remove_computable(comp);
+}
+
+
+TEST_F(RobotMemoryTest, ComputableMultiple)
+{
+  TestComputable* tc = new TestComputable();
+  Computable* comp = robot_memory->register_computable(fromjson(
+      "{compute:'multiple'}"), "robmem.test", &TestComputable::compute_multiple, tc);
+  QResCursor qres = robot_memory->query(fromjson("{compute:'multiple'}"), "robmem.test");
+  std::list<int> values = {3, 2, 1};
+  ASSERT_TRUE(qres->more());
+  int got = qres->next().getField("count").Int();
+  ASSERT_TRUE(std::find(values.begin(), values.end(), got) != values.end());
+  values.remove(got);
+  ASSERT_TRUE(qres->more());
+  got = qres->next().getField("count").Int();
+  ASSERT_TRUE(std::find(values.begin(), values.end(), got) != values.end());
+  values.remove(got);
+  ASSERT_TRUE(qres->more());
+  got = qres->next().getField("count").Int();
+  ASSERT_TRUE(std::find(values.begin(), values.end(), got) != values.end());
+  values.remove(got);
+  ASSERT_EQ(0, values.size());
+  ASSERT_FALSE(qres->more());
+  robot_memory->remove_computable(comp);
+}
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.h b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
index 17a89ab..ad596ed 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
@@ -84,12 +84,33 @@ class TestComputable
   {
   };
    ~TestComputable(){};
+   //Different functions for computables:
    std::list<mongo::BSONObj> compute(mongo::BSONObj query)
    {
      std::list<mongo::BSONObj> res;
      res.push_back(mongo::fromjson("{computed:true, result:'this is computed'}"));
      return res;
    }
+   std::list<mongo::BSONObj> compute_sum(mongo::BSONObj query)
+   {
+     std::list<mongo::BSONObj> res;
+     int x = query.getField("x").Int();
+     int y = query.getField("y").Int();
+     int sum = x + y;
+     mongo::BSONObjBuilder b;
+     b << "compute" << "sum" << "x" << x << "y" << y
+         << "sum" << sum;
+     res.push_back(b.obj());
+     return res;
+   }
+   std::list<mongo::BSONObj> compute_multiple(mongo::BSONObj query)
+   {
+     std::list<mongo::BSONObj> res;
+     res.push_back(mongo::fromjson("{compute:'multiple', count:1}"));
+     res.push_back(mongo::fromjson("{compute:'multiple', count:2}"));
+     res.push_back(mongo::fromjson("{compute:'multiple', count:3}"));
+     return res;
+   }
 };
 
 

- *commit* 588035ab1f72c72d0aef77fe536f53d77fdd7635 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Nov 1 13:21:29 2016 +0100
Subject: robot-memory: moved computables in subfolder

 src/plugins/robot-memory/Makefile                  |    1 +
 .../robot-memory/{ => computables}/computable.cpp  |    0
 .../robot-memory/{ => computables}/computable.h    |    0
 .../{ => computables}/computables_manager.cpp      |    0
 .../{ => computables}/computables_manager.h        |    0
 src/plugins/robot-memory/robot_memory.h            |    2 +-
 6 files changed, 2 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/Makefile b/src/plugins/robot-memory/Makefile
index d25debd..ffb656f 100644
--- a/src/plugins/robot-memory/Makefile
+++ b/src/plugins/robot-memory/Makefile
@@ -30,6 +30,7 @@ LIBS_robot_memory = fawkescore fawkesaspects fawkesblackboard fawkesinterface \
 		fawkesutils fawkeslogging fawkesmongodbaspect fvutils \
 		fawkestf RobotMemoryInterface fawkesrobotmemory
 OBJS_robot_memory = $(patsubst %.cpp,%.o,$(patsubst qa/%,,$(subst $(SRCDIR)/,,$(realpath $(wildcard $(SRCDIR)/*.cpp)))))
+OBJS_robot_memory += $(patsubst %.cpp,%.o,$(patsubst qa/%,,$(subst $(SRCDIR)/,,$(realpath $(wildcard $(SRCDIR)/computables/*.cpp)))))
 
 OBJS_all    = $(OBJS_robot_memory)
 
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 163a788..5f032f4 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -30,7 +30,7 @@
 #include <mongo/client/dbclient.h>
 #include "interfaces/RobotMemoryInterface.h"
 #include "event_trigger_manager.h"
-#include "computables_manager.h"
+#include "computables/computables_manager.h"
 
 namespace fawkes {
   class Mutex;

- *commit* f54e58ef881f99db9b95336f74159937af315136 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Nov 1 18:12:02 2016 +0100
Subject: robot-memory: added computable for blackboard interfaces

 .../computables/blackboard_computable.cpp          |  120 ++++++++++++++++++++
 .../computables/blackboard_computable.h            |   50 ++++++++
 src/plugins/robot-memory/robot_memory.cpp          |   11 +-
 src/plugins/robot-memory/robot_memory_thread.cpp   |    4 +
 src/plugins/robot-memory/robot_memory_thread.h     |    2 +
 src/plugins/robot-memory/test-plugin/Makefile      |    3 +-
 .../robot-memory/test-plugin/robot_memory_test.cpp |   25 ++++-
 .../robot-memory/test-plugin/robot_memory_test.h   |    6 +-
 .../test-plugin/robot_memory_test_thread.cpp       |    2 +-
 9 files changed, 213 insertions(+), 10 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index bdeff5b..d02a39b 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -118,7 +118,7 @@ QResCursor RobotMemory::query(Query query, std::string collection)
   check_collection_name(collection);
   log_deb(std::string("Executing Query "+ query.toString() +" on collection "+collection));
 
-  //only one query at a time
+  //lock (mongo_client not thread safe)
   MutexLocker lock(mutex_);
 
   //check if computation on demand is necessary and execute Computables
@@ -152,7 +152,7 @@ int RobotMemory::insert(BSONObj obj, std::string collection)
 
   log_deb(std::string("Executing Query "+ obj.toString() + " on collection " + collection));
 
-  //only one query at a time
+  //lock (mongo_client not thread safe)
   MutexLocker lock(mutex_);
 
   //actually execute insert
@@ -192,7 +192,7 @@ int RobotMemory::update(Query query, BSONObj update, std::string collection, boo
   check_collection_name(collection);
   log_deb(std::string("Executing Update "+update.toString()+" for query "+query.toString()+" on collection "+ collection));
 
-  //only one query at a time
+  //lock (mongo_client not thread safe)
   MutexLocker lock(mutex_);
 
   //actually execute update
@@ -230,7 +230,7 @@ int RobotMemory::remove(Query query, std::string collection)
   check_collection_name(collection);
   log_deb(std::string("Executing Remove "+query.toString()+" on collection "+collection));
 
-  //only one query at a time
+  //lock (mongo_client not thread safe)
   MutexLocker lock(mutex_);
 
   //actually execute remove
@@ -261,6 +261,9 @@ int RobotMemory::drop_collection(std::string collection)
  */
 int RobotMemory::clear_memory()
 {
+  //lock (mongo_client not thread safe)
+  MutexLocker lock(mutex_);
+
   log_deb("Clearing whole robot memory");
   mongodb_client_->dropDatabase(database_name_);
   return 1;
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 5509a14..ba82068 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -58,12 +58,16 @@ RobotMemoryThread::init()
   robot_memory->init();
   //prepare aspect initializer
   robot_memory_inifin_.set_robot_memory(robot_memory);
+
+  //register blackboard computable
+  blackboard_computable = new BlackboardComputable(robot_memory, blackboard, logger);
 }
 
 
 void
 RobotMemoryThread::finalize()
 {
+  delete blackboard_computable;
   robot_memory_inifin_.set_robot_memory(NULL);
   delete robot_memory;
 }
diff --git a/src/plugins/robot-memory/robot_memory_thread.h b/src/plugins/robot-memory/robot_memory_thread.h
index 610252f..23ce0ef 100644
--- a/src/plugins/robot-memory/robot_memory_thread.h
+++ b/src/plugins/robot-memory/robot_memory_thread.h
@@ -34,6 +34,7 @@
 #include <aspect/aspect_provider.h>
 #include "robot_memory.h"
 #include "aspect/robot_memory_inifin.h"
+#include "computables/blackboard_computable.h"
 
 #include <string>
 
@@ -66,6 +67,7 @@ class RobotMemoryThread
  private:
    RobotMemory* robot_memory;
    fawkes::RobotMemoryIniFin robot_memory_inifin_;
+   BlackboardComputable* blackboard_computable;
 };
 
 #endif
diff --git a/src/plugins/robot-memory/test-plugin/Makefile b/src/plugins/robot-memory/test-plugin/Makefile
index 546954c..3406a6b 100644
--- a/src/plugins/robot-memory/test-plugin/Makefile
+++ b/src/plugins/robot-memory/test-plugin/Makefile
@@ -19,7 +19,8 @@ include $(BASEDIR)/etc/buildsys/config.mk
 include $(BASEDIR)/etc/buildsys/gtest.mk
 
 LIBS_robot_memory_test = m fawkescore fawkesutils fawkesaspects fawkesbaseapp \
-                      fawkesblackboard fawkesinterface fawkesrobotmemory
+                      fawkesblackboard fawkesinterface fawkesrobotmemory \
+                      Position3DInterface
 
 OBJS_robot_memory_test = robot_memory_test_plugin.o robot_memory_test_thread.o robot_memory_test.o
 
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index cfd0e3b..d004258 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -20,21 +20,24 @@
  */
 
 #include "robot_memory_test.h"
+#include <interfaces/Position3DInterface.h>
 #include <list>
 #include <algorithm>
 
-//init static variable
-RobotMemory* RobotMemoryTestEnvironment::robot_memory = NULL;
-
 using namespace fawkes;
 using namespace mongo;
 
+//init static variable
+RobotMemory* RobotMemoryTestEnvironment::robot_memory = NULL;
+BlackBoard* RobotMemoryTestEnvironment::blackboard = NULL;
+
 /**
  * Setup for each test
  */
 void RobotMemoryTest::SetUp()
 {
   robot_memory = RobotMemoryTestEnvironment::robot_memory;
+  blackboard = RobotMemoryTestEnvironment::blackboard;
 }
 
 TEST_F(RobotMemoryTest, TestsWorking)
@@ -280,3 +283,19 @@ TEST_F(RobotMemoryTest, ComputableMultiple)
   ASSERT_FALSE(qres->more());
   robot_memory->remove_computable(comp);
 }
+
+
+TEST_F(RobotMemoryTest, BlackboardComputable)
+{
+  Position3DInterface* if3d = blackboard->open_for_writing<Position3DInterface>("test");
+  if3d->set_frame("test_frame");
+  if3d->set_translation(0, 1.1);
+  if3d->set_translation(1, 2.2);
+  if3d->set_translation(2, 3.3);
+  if3d->write();
+  QResCursor qres = robot_memory->query(fromjson("{interface:'Position3DInterface',id:'test'}"), "robmem.blackboard");
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson(
+      "{interface:'Position3DInterface',id:'test',frame:'test_frame',translation:[1.1, 2.2, 3.3]}")));
+  blackboard->close(if3d);
+}
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.h b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
index ad596ed..cb12317 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
@@ -23,6 +23,7 @@
 #define __PLUGINS_ROBOT_MEMORY_TEST_H_
 
 #include <gtest/gtest.h>
+#include <blackboard/blackboard.h>
 #include "plugins/robot-memory/robot_memory.h"
 #include <stdio.h>
 
@@ -33,15 +34,17 @@
 class RobotMemoryTestEnvironment : public ::testing::Environment
 {
  public:
-  RobotMemoryTestEnvironment(RobotMemory* robot_memory)
+  RobotMemoryTestEnvironment(RobotMemory* robot_memory, fawkes::BlackBoard* blackboard)
   {
     this->robot_memory = robot_memory;
+    this->blackboard = blackboard;
   }
   virtual ~RobotMemoryTestEnvironment() {}
   void SetUp() {}
   virtual void TearDown(){}
  public:
   static RobotMemory* robot_memory;
+  static fawkes::BlackBoard* blackboard;
 };
 
 /** Class for Tests of the RobotMemory
@@ -51,6 +54,7 @@ class RobotMemoryTest : public ::testing::Test
  protected:
   virtual void SetUp();
   RobotMemory* robot_memory;
+  fawkes::BlackBoard* blackboard;
 
  protected:
   ::testing::AssertionResult contains_pairs(mongo::BSONObj obj, mongo::BSONObj exp);
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
index 640917b..89d8f54 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
@@ -44,7 +44,7 @@ RobotMemoryTestThread::init()
 {
   //prepare tests
   logger->log_warn(name(), "Preparing tests");
-  test_env_ = new RobotMemoryTestEnvironment(robot_memory);
+  test_env_ = new RobotMemoryTestEnvironment(robot_memory, blackboard);
   ::testing::AddGlobalTestEnvironment((testing::Environment*) test_env_);
 
 }

- *commit* 5677b7279aa5b1565f496a93ec2d4a740fd7809b - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Tue Nov 1 18:31:11 2016 +0100
Subject: robot-memory: fixed syntax in aspect Makefile

 src/plugins/robot-memory/aspect/Makefile |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/aspect/Makefile b/src/plugins/robot-memory/aspect/Makefile
index 693f1be..4d4ee96 100644
--- a/src/plugins/robot-memory/aspect/Makefile
+++ b/src/plugins/robot-memory/aspect/Makefile
@@ -37,8 +37,8 @@ endif
 ifeq ($(OBJSSUBMAKE),1)
 all: $(WARN_TARGETS)
 
-PHONY: warning_mongodb
-.warning_mongodb:
+.PHONY: warning_mongodb
+warning_mongodb:
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting RobotMemoryAspect$(TNORMAL) (mongodb[-devel] not installed)"
 endif
 

- *commit* a5c59ecf418edefed8f5368b865f7ec327e8a9d7 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Nov 3 11:14:24 2016 +0100
Subject: robot-memory: error hint if mongod is running with wrong parameters

 src/plugins/robot-memory/robot_memory_setup.cpp |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index db73a54..9d7f7c3 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -221,8 +221,13 @@ mongo::BSONObj RobotMemorySetup::run_mongo_command(unsigned int port, std::strin
   logger->log_info("RobotMemorySetup", "Executing db command: %s", command.c_str());
   con.runCommand("admin", mongo::fromjson(command), res);
   con.reset();
+
   if(res.getField("ok").type() != mongo::BSONType::NumberDouble || (res.getField("ok").Double() == 0.0 && res.getField("errmsg").String().compare(err_msg_to_ignore) != 0))
+  {
+    if(res.getField("errmsg").String() == "server is not running with --replSet")
+      logger->log_error("RobotMemorySetup", "The mongod instance which is already running is started with the wrong parameters. Stop it to let it start by the robot memory or change the mongod config and restart it.");
     throw PluginLoadException("robot-memory", std::string("Running DB command " + command + " failed: " + res.toString()).c_str());
+  }
   return res;
 }
 

- *commit* f5b1cd3a31fd73da7c0d2444aa7b44743e512326 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Nov 3 11:51:17 2016 +0100
Subject: robot-memory: compute all bb-interfaces when no id is given

 .../computables/blackboard_computable.cpp          |    6 ++++--
 .../robot-memory/test-plugin/robot_memory_test.cpp |   18 ++++++++++++++++++
 2 files changed, 22 insertions(+), 2 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/computables/blackboard_computable.cpp b/src/plugins/robot-memory/computables/blackboard_computable.cpp
index bf6c5c7..aff81c5 100644
--- a/src/plugins/robot-memory/computables/blackboard_computable.cpp
+++ b/src/plugins/robot-memory/computables/blackboard_computable.cpp
@@ -37,7 +37,7 @@ BlackboardComputable::BlackboardComputable(RobotMemory* robot_memory, fawkes::Bl
   logger_ = logger;
 
   //register computable
-  Query query = fromjson("{interface:{$exists:true}, id:{$exists:true}}");
+  Query query = fromjson("{interface:{$exists:true}}");
   computable = robot_memory_->register_computable(query, "robmem.blackboard", &BlackboardComputable::compute_interfaces, this);
 }
 
@@ -50,7 +50,9 @@ std::list<mongo::BSONObj> BlackboardComputable::compute_interfaces(mongo::BSONOb
 {
   std::list<mongo::BSONObj> res;
   std::string type = query.getField("interface").String();
-  std::string id = query.getField("id").String();
+  std::string id = "*";
+  if(query.hasField("id"))
+    id = query.getField("id").String();
   //get all matching interfaces
   for(Interface* interface : blackboard_->open_multiple_for_reading(type.c_str(), id.c_str()))
   {
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index d004258..823abfc 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -299,3 +299,21 @@ TEST_F(RobotMemoryTest, BlackboardComputable)
       "{interface:'Position3DInterface',id:'test',frame:'test_frame',translation:[1.1, 2.2, 3.3]}")));
   blackboard->close(if3d);
 }
+
+
+TEST_F(RobotMemoryTest, BlackboardComputableMultiple)
+{
+  Position3DInterface* if3d = blackboard->open_for_writing<Position3DInterface>("test");
+  if3d->set_frame("test_frame");
+  if3d->write();
+  Position3DInterface* if3d_2 = blackboard->open_for_writing<Position3DInterface>("test_2");
+  if3d_2->set_frame("test_frame");
+  if3d_2->write();
+  QResCursor qres = robot_memory->query(fromjson("{interface:'Position3DInterface',id:'test'}"), "robmem.blackboard");
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{interface:'Position3DInterface'}")));
+  ASSERT_TRUE(qres->more());
+  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{interface:'Position3DInterface'}")));
+  blackboard->close(if3d);
+  blackboard->close(if3d_2);
+}

- *commit* 1436050dd696c7a29d8e3c8f074451df170f7f5e - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Nov 3 13:00:06 2016 +0100
Subject: robot-memory: require collection in interface msgs for testing

 .../interfaces/RobotMemoryInterface.h}             |   24 +++-
 .../interfaces/RobotMemoryInterface.cpp            |  146 +++++++++++++++++++-
 .../interfaces/RobotMemoryInterface.h_ext          |   24 +++-
 .../interfaces/RobotMemoryInterface.tolua          |   20 ++-
 .../interfaces/RobotMemoryInterface.xml            |    6 +-
 src/plugins/robot-memory/robot_memory_thread.cpp   |   18 ++-
 6 files changed, 216 insertions(+), 22 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp
index a60da8d..afacc39 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.cpp
@@ -56,7 +56,7 @@ RobotMemoryInterface::RobotMemoryInterface() : Interface()
   add_messageinfo("InsertMessage");
   add_messageinfo("UpdateMessage");
   add_messageinfo("RemoveMessage");
-  unsigned char tmp_hash[] = {0x57, 0x8, 0x55, 0x6b, 0x61, 0x8, 0xc9, 0x16, 0xf7, 0x68, 0xcc, 0x7e, 0xae, 0xe2, 0x42, 0xe};
+  unsigned char tmp_hash[] = {0x46, 0x15, 0x7a, 0xda, 0x53, 0x5, 0x42, 0x51, 0xa6, 0xd5, 0x3c, 0x1d, 0x56, 0xfa, 0x61, 0xba};
   set_hash(tmp_hash);
 }
 
@@ -177,8 +177,9 @@ RobotMemoryInterface::enum_tostring(const char *enumtype, int val) const
 
 /** Constructor with initial values.
  * @param ini_query initial value for query
+ * @param ini_collection initial value for collection
  */
-RobotMemoryInterface::QueryMessage::QueryMessage(const char * ini_query) : Message("QueryMessage")
+RobotMemoryInterface::QueryMessage::QueryMessage(const char * ini_query, const char * ini_collection) : Message("QueryMessage")
 {
   data_size = sizeof(QueryMessage_data_t);
   data_ptr  = malloc(data_size);
@@ -186,7 +187,9 @@ RobotMemoryInterface::QueryMessage::QueryMessage(const char * ini_query) : Messa
   data      = (QueryMessage_data_t *)data_ptr;
   data_ts   = (message_data_ts_t *)data_ptr;
   strncpy(data->query, ini_query, 1024);
+  strncpy(data->collection, ini_collection, 1024);
   add_fieldinfo(IFT_STRING, "query", 1024, data->query);
+  add_fieldinfo(IFT_STRING, "collection", 1024, data->collection);
 }
 /** Constructor */
 RobotMemoryInterface::QueryMessage::QueryMessage() : Message("QueryMessage")
@@ -197,6 +200,7 @@ RobotMemoryInterface::QueryMessage::QueryMessage() : Message("QueryMessage")
   data      = (QueryMessage_data_t *)data_ptr;
   data_ts   = (message_data_ts_t *)data_ptr;
   add_fieldinfo(IFT_STRING, "query", 1024, data->query);
+  add_fieldinfo(IFT_STRING, "collection", 1024, data->collection);
 }
 
 /** Destructor */
@@ -248,6 +252,36 @@ RobotMemoryInterface::QueryMessage::set_query(const char * new_query)
   strncpy(data->query, new_query, sizeof(data->query));
 }
 
+/** Get collection value.
+ * The collection to query
+ * @return collection value
+ */
+char *
+RobotMemoryInterface::QueryMessage::collection() const
+{
+  return data->collection;
+}
+
+/** Get maximum length of collection value.
+ * @return length of collection value, can be length of the array or number of 
+ * maximum number of characters for a string
+ */
+size_t
+RobotMemoryInterface::QueryMessage::maxlenof_collection() const
+{
+  return 1024;
+}
+
+/** Set collection value.
+ * The collection to query
+ * @param new_collection new collection value
+ */
+void
+RobotMemoryInterface::QueryMessage::set_collection(const char * new_collection)
+{
+  strncpy(data->collection, new_collection, sizeof(data->collection));
+}
+
 /** Clone this message.
  * Produces a message of the same type as this message and copies the
  * data to the new message.
@@ -267,8 +301,9 @@ RobotMemoryInterface::QueryMessage::clone() const
 
 /** Constructor with initial values.
  * @param ini_insert initial value for insert
+ * @param ini_collection initial value for collection
  */
-RobotMemoryInterface::InsertMessage::InsertMessage(const char * ini_insert) : Message("InsertMessage")
+RobotMemoryInterface::InsertMessage::InsertMessage(const char * ini_insert, const char * ini_collection) : Message("InsertMessage")
 {
   data_size = sizeof(InsertMessage_data_t);
   data_ptr  = malloc(data_size);
@@ -276,7 +311,9 @@ RobotMemoryInterface::InsertMessage::InsertMessage(const char * ini_insert) : Me
   data      = (InsertMessage_data_t *)data_ptr;
   data_ts   = (message_data_ts_t *)data_ptr;
   strncpy(data->insert, ini_insert, 1024);
+  strncpy(data->collection, ini_collection, 1024);
   add_fieldinfo(IFT_STRING, "insert", 1024, data->insert);
+  add_fieldinfo(IFT_STRING, "collection", 1024, data->collection);
 }
 /** Constructor */
 RobotMemoryInterface::InsertMessage::InsertMessage() : Message("InsertMessage")
@@ -287,6 +324,7 @@ RobotMemoryInterface::InsertMessage::InsertMessage() : Message("InsertMessage")
   data      = (InsertMessage_data_t *)data_ptr;
   data_ts   = (message_data_ts_t *)data_ptr;
   add_fieldinfo(IFT_STRING, "insert", 1024, data->insert);
+  add_fieldinfo(IFT_STRING, "collection", 1024, data->collection);
 }
 
 /** Destructor */
@@ -338,6 +376,36 @@ RobotMemoryInterface::InsertMessage::set_insert(const char * new_insert)
   strncpy(data->insert, new_insert, sizeof(data->insert));
 }
 
+/** Get collection value.
+ * The collection to query
+ * @return collection value
+ */
+char *
+RobotMemoryInterface::InsertMessage::collection() const
+{
+  return data->collection;
+}
+
+/** Get maximum length of collection value.
+ * @return length of collection value, can be length of the array or number of 
+ * maximum number of characters for a string
+ */
+size_t
+RobotMemoryInterface::InsertMessage::maxlenof_collection() const
+{
+  return 1024;
+}
+
+/** Set collection value.
+ * The collection to query
+ * @param new_collection new collection value
+ */
+void
+RobotMemoryInterface::InsertMessage::set_collection(const char * new_collection)
+{
+  strncpy(data->collection, new_collection, sizeof(data->collection));
+}
+
 /** Clone this message.
  * Produces a message of the same type as this message and copies the
  * data to the new message.
@@ -358,8 +426,9 @@ RobotMemoryInterface::InsertMessage::clone() const
 /** Constructor with initial values.
  * @param ini_query initial value for query
  * @param ini_update initial value for update
+ * @param ini_collection initial value for collection
  */
-RobotMemoryInterface::UpdateMessage::UpdateMessage(const char * ini_query, const char * ini_update) : Message("UpdateMessage")
+RobotMemoryInterface::UpdateMessage::UpdateMessage(const char * ini_query, const char * ini_update, const char * ini_collection) : Message("UpdateMessage")
 {
   data_size = sizeof(UpdateMessage_data_t);
   data_ptr  = malloc(data_size);
@@ -368,8 +437,10 @@ RobotMemoryInterface::UpdateMessage::UpdateMessage(const char * ini_query, const
   data_ts   = (message_data_ts_t *)data_ptr;
   strncpy(data->query, ini_query, 1024);
   strncpy(data->update, ini_update, 1024);
+  strncpy(data->collection, ini_collection, 1024);
   add_fieldinfo(IFT_STRING, "query", 1024, data->query);
   add_fieldinfo(IFT_STRING, "update", 1024, data->update);
+  add_fieldinfo(IFT_STRING, "collection", 1024, data->collection);
 }
 /** Constructor */
 RobotMemoryInterface::UpdateMessage::UpdateMessage() : Message("UpdateMessage")
@@ -381,6 +452,7 @@ RobotMemoryInterface::UpdateMessage::UpdateMessage() : Message("UpdateMessage")
   data_ts   = (message_data_ts_t *)data_ptr;
   add_fieldinfo(IFT_STRING, "query", 1024, data->query);
   add_fieldinfo(IFT_STRING, "update", 1024, data->update);
+  add_fieldinfo(IFT_STRING, "collection", 1024, data->collection);
 }
 
 /** Destructor */
@@ -462,6 +534,36 @@ RobotMemoryInterface::UpdateMessage::set_update(const char * new_update)
   strncpy(data->update, new_update, sizeof(data->update));
 }
 
+/** Get collection value.
+ * The collection to query
+ * @return collection value
+ */
+char *
+RobotMemoryInterface::UpdateMessage::collection() const
+{
+  return data->collection;
+}
+
+/** Get maximum length of collection value.
+ * @return length of collection value, can be length of the array or number of 
+ * maximum number of characters for a string
+ */
+size_t
+RobotMemoryInterface::UpdateMessage::maxlenof_collection() const
+{
+  return 1024;
+}
+
+/** Set collection value.
+ * The collection to query
+ * @param new_collection new collection value
+ */
+void
+RobotMemoryInterface::UpdateMessage::set_collection(const char * new_collection)
+{
+  strncpy(data->collection, new_collection, sizeof(data->collection));
+}
+
 /** Clone this message.
  * Produces a message of the same type as this message and copies the
  * data to the new message.
@@ -481,8 +583,9 @@ RobotMemoryInterface::UpdateMessage::clone() const
 
 /** Constructor with initial values.
  * @param ini_query initial value for query
+ * @param ini_collection initial value for collection
  */
-RobotMemoryInterface::RemoveMessage::RemoveMessage(const char * ini_query) : Message("RemoveMessage")
+RobotMemoryInterface::RemoveMessage::RemoveMessage(const char * ini_query, const char * ini_collection) : Message("RemoveMessage")
 {
   data_size = sizeof(RemoveMessage_data_t);
   data_ptr  = malloc(data_size);
@@ -490,7 +593,9 @@ RobotMemoryInterface::RemoveMessage::RemoveMessage(const char * ini_query) : Mes
   data      = (RemoveMessage_data_t *)data_ptr;
   data_ts   = (message_data_ts_t *)data_ptr;
   strncpy(data->query, ini_query, 1024);
+  strncpy(data->collection, ini_collection, 1024);
   add_fieldinfo(IFT_STRING, "query", 1024, data->query);
+  add_fieldinfo(IFT_STRING, "collection", 1024, data->collection);
 }
 /** Constructor */
 RobotMemoryInterface::RemoveMessage::RemoveMessage() : Message("RemoveMessage")
@@ -501,6 +606,7 @@ RobotMemoryInterface::RemoveMessage::RemoveMessage() : Message("RemoveMessage")
   data      = (RemoveMessage_data_t *)data_ptr;
   data_ts   = (message_data_ts_t *)data_ptr;
   add_fieldinfo(IFT_STRING, "query", 1024, data->query);
+  add_fieldinfo(IFT_STRING, "collection", 1024, data->collection);
 }
 
 /** Destructor */
@@ -552,6 +658,36 @@ RobotMemoryInterface::RemoveMessage::set_query(const char * new_query)
   strncpy(data->query, new_query, sizeof(data->query));
 }
 
+/** Get collection value.
+ * The collection to query
+ * @return collection value
+ */
+char *
+RobotMemoryInterface::RemoveMessage::collection() const
+{
+  return data->collection;
+}
+
+/** Get maximum length of collection value.
+ * @return length of collection value, can be length of the array or number of 
+ * maximum number of characters for a string
+ */
+size_t
+RobotMemoryInterface::RemoveMessage::maxlenof_collection() const
+{
+  return 1024;
+}
+
+/** Set collection value.
+ * The collection to query
+ * @param new_collection new collection value
+ */
+void
+RobotMemoryInterface::RemoveMessage::set_collection(const char * new_collection)
+{
+  strncpy(data->collection, new_collection, sizeof(data->collection));
+}
+
 /** Clone this message.
  * Produces a message of the same type as this message and copies the
  * data to the new message.
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.h_ext b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.h_ext
index ddd2d0b..4be2a8c 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.h_ext
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.h_ext
@@ -62,13 +62,14 @@ class RobotMemoryInterface : public Interface
       int64_t timestamp_sec;  /**< Interface Unix timestamp, seconds */
       int64_t timestamp_usec; /**< Interface Unix timestamp, micro-seconds */
       char query[1024]; /**< Query as JSON string */
+      char collection[1024]; /**< The collection to query */
     } QueryMessage_data_t;
 #pragma pack(pop)
 
     QueryMessage_data_t *data;
 
    public:
-    QueryMessage(const char * ini_query);
+    QueryMessage(const char * ini_query, const char * ini_collection);
     QueryMessage();
     ~QueryMessage();
 
@@ -77,6 +78,9 @@ class RobotMemoryInterface : public Interface
     char * query() const;
     void set_query(const char * new_query);
     size_t maxlenof_query() const;
+    char * collection() const;
+    void set_collection(const char * new_collection);
+    size_t maxlenof_collection() const;
     virtual Message * clone() const;
   };
 
@@ -89,13 +93,14 @@ class RobotMemoryInterface : public Interface
       int64_t timestamp_sec;  /**< Interface Unix timestamp, seconds */
       int64_t timestamp_usec; /**< Interface Unix timestamp, micro-seconds */
       char insert[1024]; /**< Document to insert as JSON string */
+      char collection[1024]; /**< The collection to query */
     } InsertMessage_data_t;
 #pragma pack(pop)
 
     InsertMessage_data_t *data;
 
    public:
-    InsertMessage(const char * ini_insert);
+    InsertMessage(const char * ini_insert, const char * ini_collection);
     InsertMessage();
     ~InsertMessage();
 
@@ -104,6 +109,9 @@ class RobotMemoryInterface : public Interface
     char * insert() const;
     void set_insert(const char * new_insert);
     size_t maxlenof_insert() const;
+    char * collection() const;
+    void set_collection(const char * new_collection);
+    size_t maxlenof_collection() const;
     virtual Message * clone() const;
   };
 
@@ -117,13 +125,14 @@ class RobotMemoryInterface : public Interface
       int64_t timestamp_usec; /**< Interface Unix timestamp, micro-seconds */
       char query[1024]; /**< Query as JSON string */
       char update[1024]; /**< Update as JSON string */
+      char collection[1024]; /**< The collection to query */
     } UpdateMessage_data_t;
 #pragma pack(pop)
 
     UpdateMessage_data_t *data;
 
    public:
-    UpdateMessage(const char * ini_query, const char * ini_update);
+    UpdateMessage(const char * ini_query, const char * ini_update, const char * ini_collection);
     UpdateMessage();
     ~UpdateMessage();
 
@@ -135,6 +144,9 @@ class RobotMemoryInterface : public Interface
     char * update() const;
     void set_update(const char * new_update);
     size_t maxlenof_update() const;
+    char * collection() const;
+    void set_collection(const char * new_collection);
+    size_t maxlenof_collection() const;
     virtual Message * clone() const;
   };
 
@@ -147,13 +159,14 @@ class RobotMemoryInterface : public Interface
       int64_t timestamp_sec;  /**< Interface Unix timestamp, seconds */
       int64_t timestamp_usec; /**< Interface Unix timestamp, micro-seconds */
       char query[1024]; /**< Query as JSON string */
+      char collection[1024]; /**< The collection to query */
     } RemoveMessage_data_t;
 #pragma pack(pop)
 
     RemoveMessage_data_t *data;
 
    public:
-    RemoveMessage(const char * ini_query);
+    RemoveMessage(const char * ini_query, const char * ini_collection);
     RemoveMessage();
     ~RemoveMessage();
 
@@ -162,6 +175,9 @@ class RobotMemoryInterface : public Interface
     char * query() const;
     void set_query(const char * new_query);
     size_t maxlenof_query() const;
+    char * collection() const;
+    void set_collection(const char * new_collection);
+    size_t maxlenof_collection() const;
     virtual Message * clone() const;
   };
 
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.tolua b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.tolua
index 67095b2..65f4672 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.tolua
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.tolua
@@ -8,7 +8,7 @@ class RobotMemoryInterface : public Interface
 
   class QueryMessage : public Message
   {
-    QueryMessage(char * ini_query);
+    QueryMessage(char * ini_query, char * ini_collection);
     QueryMessage();
     ~QueryMessage();
 
@@ -32,11 +32,14 @@ class RobotMemoryInterface : public Interface
     char * query();
     void set_query(const char * new_query);
     int maxlenof_query() const;
+    char * collection();
+    void set_collection(const char * new_collection);
+    int maxlenof_collection() const;
   };
 
   class InsertMessage : public Message
   {
-    InsertMessage(char * ini_insert);
+    InsertMessage(char * ini_insert, char * ini_collection);
     InsertMessage();
     ~InsertMessage();
 
@@ -60,11 +63,14 @@ class RobotMemoryInterface : public Interface
     char * insert();
     void set_insert(const char * new_insert);
     int maxlenof_insert() const;
+    char * collection();
+    void set_collection(const char * new_collection);
+    int maxlenof_collection() const;
   };
 
   class UpdateMessage : public Message
   {
-    UpdateMessage(char * ini_query, char * ini_update);
+    UpdateMessage(char * ini_query, char * ini_update, char * ini_collection);
     UpdateMessage();
     ~UpdateMessage();
 
@@ -91,11 +97,14 @@ class RobotMemoryInterface : public Interface
     char * update();
     void set_update(const char * new_update);
     int maxlenof_update() const;
+    char * collection();
+    void set_collection(const char * new_collection);
+    int maxlenof_collection() const;
   };
 
   class RemoveMessage : public Message
   {
-    RemoveMessage(char * ini_query);
+    RemoveMessage(char * ini_query, char * ini_collection);
     RemoveMessage();
     ~RemoveMessage();
 
@@ -119,6 +128,9 @@ class RobotMemoryInterface : public Interface
     char * query();
     void set_query(const char * new_query);
     int maxlenof_query() const;
+    char * collection();
+    void set_collection(const char * new_collection);
+    int maxlenof_collection() const;
   };
 
   char * error();
diff --git a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml
index 498cda9..5058910 100644
--- a/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml
+++ b/src/plugins/robot-memory/interfaces/RobotMemoryInterface.xml
@@ -14,13 +14,15 @@
     <comment>
       Query to execute.
     </comment>
-    <field type="string"  length="1024" name="query">Query as JSON string</field>
+    <field type="string" length="1024" name="query">Query as JSON string</field>
+    <field type="string" length="1024" name="collection">The collection to query</field>
   </message>
   <message name="Insert">
     <comment>
       Message to insert a document into the database.
     </comment>
     <field type="string"  length="1024" name="insert">Document to insert as JSON string</field>
+    <field type="string" length="1024" name="collection">The collection to query</field>
   </message>
   <message name="Update">
     <comment>
@@ -28,12 +30,14 @@
     </comment>
     <field type="string"  length="1024" name="query">Query as JSON string</field>
     <field type="string"  length="1024" name="update">Update as JSON string</field>
+    <field type="string" length="1024" name="collection">The collection to query</field>
   </message>
   <message name="Remove">
     <comment>
       Message to remove documents matching the query.
     </comment>
     <field type="string"  length="1024" name="query">Query as JSON string</field>
+    <field type="string" length="1024" name="collection">The collection to query</field>
   </message>
 
 </interface>
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index ba82068..5cf279e 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -80,16 +80,26 @@ RobotMemoryThread::loop()
   while (! robot_memory->rm_if_->msgq_empty() ) {
     if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::QueryMessage>()) {
 	    RobotMemoryInterface::QueryMessage* msg = (RobotMemoryInterface::QueryMessage*) robot_memory->rm_if_->msgq_first();
-	    robot_memory->query(msg->query());
+	    QResCursor res = robot_memory->query(msg->query(), msg->collection());
+	    //output result
+	    std::string query = msg->query();
+	    std::string result = "Result of query " + query + ":\n";
+	    while(res->more())
+	    {
+	      mongo::BSONObj doc = res->next();
+	      result += doc.toString() + "\n";
+	    }
+	    logger->log_info(name(), result.c_str());
+	    robot_memory->rm_if_->set_result(result.c_str());
     } else if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::InsertMessage>()) {
 	    RobotMemoryInterface::InsertMessage* msg = (RobotMemoryInterface::InsertMessage*) robot_memory->rm_if_->msgq_first();
-	    robot_memory->insert(msg->insert());
+	    robot_memory->insert(msg->insert()), msg->collection();
     } else if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::UpdateMessage>()) {
 	    RobotMemoryInterface::UpdateMessage* msg = (RobotMemoryInterface::UpdateMessage*) robot_memory->rm_if_->msgq_first();
-	    robot_memory->update(msg->query(), msg->update());
+	    robot_memory->update(msg->query(), msg->update(), msg->collection());
     } else if (robot_memory->rm_if_->msgq_first_is<RobotMemoryInterface::RemoveMessage>()) {
 	    RobotMemoryInterface::RemoveMessage* msg = (RobotMemoryInterface::RemoveMessage*) robot_memory->rm_if_->msgq_first();
-	    robot_memory->remove(msg->query());
+	    robot_memory->remove(msg->query(), msg->collection());
     } else {
       logger->log_warn(name(), "Unknown message received");
     }

- *commit* e1b93bbc9a8d16145e710fae998e679c4e3c0080 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Nov 9 18:20:05 2016 +0100
Subject: robot-memory: use config of  local database path

 src/plugins/robot-memory/robot_memory_setup.cpp |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index 9d7f7c3..ee3582d 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -50,8 +50,11 @@ void RobotMemorySetup::setup_mongods()
   std::string local_db_name = config->get_string("plugins/robot-memory/database");
   std::string local_repl_name = config->get_string("plugins/robot-memory/setup/local/replica-set-name");
   std::string local_port_str = std::to_string(local_port);
+  std::string local_db_path = StringConversions::resolve_path(config->get_string("plugins/robot-memory/setup/local/db-path").c_str());
+  prepare_mongo_db_path(local_db_path);
   const char *local_argv[] = {"mongod", "--port", local_port_str.c_str(),
-      "--replSet", local_repl_name.c_str(), NULL}; //local replica set just to enable the oplog
+			      "--replSet", local_repl_name.c_str(),
+      "--dbpath", local_db_path.c_str(), NULL}; //local replica set just to enable the oplog
   start_mongo_process("mongod-local", local_port, local_argv);
   std::string local_config = "{_id: '" + local_repl_name + "', members:[{_id:1,host:'localhost:" + local_port_str + "'}]}";
   run_mongo_command(local_port, std::string("{replSetInitiate:" + local_config + "}"), "already initialized");

- *commit* a8073ccbe9d74344e773731dfc70b3b6df19ef94 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Nov 10 18:09:10 2016 +0100
Subject: robot-memory: fixed initial creation of dbs to be able to move them

 src/plugins/robot-memory/robot_memory_setup.cpp |    7 ++-----
 src/plugins/robot-memory/robot_memory_setup.h   |    2 ++
 2 files changed, 4 insertions(+), 5 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index ee3582d..01e444f 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -60,7 +60,6 @@ void RobotMemorySetup::setup_mongods()
   run_mongo_command(local_port, std::string("{replSetInitiate:" + local_config + "}"), "already initialized");
   //wait for initialization
   usleep(1000000);
-  create_database(local_port, local_db_name);
 
   //only start other processes when we want to run the robot memory distributed
   if(!config->get_bool("plugins/robot-memory/setup/distributed"))
@@ -74,7 +73,6 @@ void RobotMemorySetup::setup_mongods()
   const char *config_argv[] = {"mongod", "--configsvr", "--port",
       config_port_str.c_str(), "--dbpath", db_path.c_str(), NULL};
   start_mongo_process("mongod-config", config_port, config_argv);
-  create_database(local_port, local_db_name);
 
   //start own part of replica set
   unsigned int distributed_port = config->get_uint("plugins/robot-memory/setup/replicated/port");
@@ -93,7 +91,6 @@ void RobotMemorySetup::setup_mongods()
   run_mongo_command(distributed_port, std::string("{replSetInitiate:" + repl_config + "}"), "already initialized");
   //wait for replica set initialization and election
   usleep(3000000);
-  create_database(distributed_port, distributed_replset);
 
   //start mongos for accessing
   unsigned int mongos_port = config->get_uint("plugins/robot-memory/setup/mongos/port");
@@ -113,6 +110,8 @@ void RobotMemorySetup::setup_mongods()
       "/localhost:" + distributed_port_str + "'}"), "host already used");
   }
   //define which db is in which shard
+  create_database(mongos_port, local_db_name);
+  create_database(mongos_port, distributed_replset);
   run_mongo_command(mongos_port, std::string("{movePrimary: '" + distributed_replset + "', to: '" + distributed_replset + "'}"), "it is already the primary");
   run_mongo_command(mongos_port, std::string("{movePrimary: '" + local_db_name + "', to: '" + local_repl_name + "'}"), "it is already the primary");
 }
@@ -248,6 +247,4 @@ void RobotMemorySetup::create_database(unsigned int port, std::string name)
   mongo::BSONObj first_doc = mongo::fromjson("{initialized:1}");
   con.insert(name + ".config", first_doc);
   con.reset();
-
-
 }
diff --git a/src/plugins/robot-memory/robot_memory_setup.h b/src/plugins/robot-memory/robot_memory_setup.h
index 300e9a7..5919160 100644
--- a/src/plugins/robot-memory/robot_memory_setup.h
+++ b/src/plugins/robot-memory/robot_memory_setup.h
@@ -28,6 +28,8 @@
 #include <utils/misc/string_commands.h>
 #include <mongo/client/dbclient.h>
 
+typedef std::unique_ptr<mongo::DBClientCursor> QResCursor;
+
 /** @class RobotMemorySetup  robot_memory_setup.h
  *
  * @author Frederik Zwilling

- *commit* efda932a96201b57fffa44997c4a91ace64b0d25 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Nov 11 16:23:33 2016 +0100
Subject: clips-robot-memory: fixed getting symbol multifields from documents

 src/plugins/clips-robot-memory/robot-memory.clp |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/robot-memory.clp b/src/plugins/clips-robot-memory/robot-memory.clp
index 2cb9f9f..7a0ff95 100644
--- a/src/plugins/clips-robot-memory/robot-memory.clp
+++ b/src/plugins/clips-robot-memory/robot-memory.clp
@@ -64,8 +64,13 @@
     (progn$ (?slot ?keys)
       (if (deftemplate-slot-existp ?relation (sym-cat ?slot)) then
         (if (deftemplate-slot-multip ?relation (sym-cat ?slot))
-          then
-          (bind ?values (str-cat ?values "(" ?slot " " (implode$ (bson-get-array ?doc ?slot)) ")"))
+	  then
+	  (bind ?arr-str (bson-get-array ?doc ?slot))
+	  (bind ?arr (create$))
+	  (progn$ (?i ?arr-str)
+	    (bind ?arr (create$ ?arr (sym-cat ?i)))
+	  )
+          (bind ?values (str-cat ?values "(" ?slot " " (implode$ ?arr) ")"))
           else
           (bind ?values (str-cat ?values "(" ?slot " " (bson-get ?doc ?slot) ")"))
         )
@@ -76,7 +81,7 @@
       (bind ?values (str-cat ?values "(" ?relation " " (implode$ (bson-get-array ?doc "values")) ")"))
     )
   )
-
+  ;(printout t "Asserting:" (str-cat "(" ?relation " " ?values ")") crlf)
   (assert-string (str-cat "(" ?relation " " ?values ")"))
 )
 

- *commit* 535e28fbbebf1b712d723acd165a90281266ccc7 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Nov 11 17:25:30 2016 +0100
Subject: clips-robot-memory: better distinction of string and symbol values

 .../clips_robot_memory_thread.cpp                  |    5 +++--
 src/plugins/clips-robot-memory/robot-memory.clp    |    4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
index ec8043f..3b9e4f9 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
@@ -169,11 +169,12 @@ ClipsRobotMemoryThread::clips_bson_append(void *bson, std::string field_name, CL
       break;
 
     case CLIPS::TYPE_SYMBOL:
-    case CLIPS::TYPE_STRING:
     case CLIPS::TYPE_INSTANCE_NAME:
       b->append(field_name, value.as_string());
       break;
-
+    case CLIPS::TYPE_STRING:
+      b->append(field_name, std::string("\"") + value.as_string() + std::string("\""));
+      break;
     case CLIPS::TYPE_EXTERNAL_ADDRESS:
       {
   mongo::BSONObjBuilder *subb = static_cast<mongo::BSONObjBuilder *>(value.as_address());
diff --git a/src/plugins/clips-robot-memory/robot-memory.clp b/src/plugins/clips-robot-memory/robot-memory.clp
index 7a0ff95..291f92a 100644
--- a/src/plugins/clips-robot-memory/robot-memory.clp
+++ b/src/plugins/clips-robot-memory/robot-memory.clp
@@ -19,7 +19,7 @@
 (deffunction rm-structured-fact-to-bson (?fact)
   (bind ?doc (bson-create))
   (bind ?templ (fact-relation ?fact))
-  (bson-append ?doc "relation" (str-cat ?templ))
+  (bson-append ?doc "relation" (sym-cat ?templ))
   ;append kv-pair for each field
   (progn$ (?slot (fact-slot-names ?fact))
     (if (deftemplate-slot-multip ?templ ?slot)
@@ -40,7 +40,7 @@
 (deffunction rm-ordered-fact-to-bson (?fact)
   (bind ?doc (bson-create))
   (bind ?templ (fact-relation ?fact))
-  (bson-append ?doc "relation" (str-cat ?templ))
+  (bson-append ?doc "relation" (sym-cat ?templ))
   ;append values as array
   (bson-append-array ?doc "values" (fact-slot-value ?fact implied))
   (return ?doc)

- *commit* 15acf2aa495aa39b5e2d92f238aafea573d3d9c1 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Fri Nov 18 16:30:19 2016 +0100
Subject: robot-memory: fixed trigger-manager in non-replicated case

 src/plugins/robot-memory/event_trigger_manager.cpp |   28 +++++++++++++++-----
 src/plugins/robot-memory/event_trigger_manager.h   |    6 +++-
 2 files changed, 25 insertions(+), 9 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/event_trigger_manager.cpp b/src/plugins/robot-memory/event_trigger_manager.cpp
index 8262815..684ce51 100644
--- a/src/plugins/robot-memory/event_trigger_manager.cpp
+++ b/src/plugins/robot-memory/event_trigger_manager.cpp
@@ -31,6 +31,7 @@ EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
 {
   logger_ = logger;
   config_ = config;
+  distributed_ = config_->get_bool("plugins/robot-memory/setup/distributed");
 
   // create connections to running mongod instances because only there
   con_local_ = new mongo::DBClientConnection();
@@ -41,14 +42,16 @@ EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
     std::string err_msg = "Could not connect to mongod process: "+ errmsg;
     throw PluginLoadException("robot-memory", err_msg.c_str());
   }
-  repl_set = config_->get_string("plugins/robot-memory/setup/replicated/replica-set-name");
-  con_replica_ = new mongo::DBClientConnection();
-  if(!con_replica_->connect("localhost:" + std::to_string(config_->get_uint("plugins/robot-memory/setup/replicated/port")), errmsg))
+  if(distributed_)
   {
-    std::string err_msg = "Could not connect to replica set: "+ errmsg;
-    throw PluginLoadException("robot-memory", err_msg.c_str());
+    repl_set = config_->get_string("plugins/robot-memory/setup/replicated/replica-set-name");
+    con_replica_ = new mongo::DBClientConnection();
+    if(!con_replica_->connect("localhost:" + std::to_string(config_->get_uint("plugins/robot-memory/setup/replicated/port")), errmsg))
+    {
+      std::string err_msg = "Could not connect to replica set: "+ errmsg;
+      throw PluginLoadException("robot-memory", err_msg.c_str());
+    }
   }
-
   logger_->log_debug(name.c_str(), "Initialized");
 }
 
@@ -74,7 +77,18 @@ void EventTriggerManager::check_events()
     if(trigger->oplog_cursor->isDead())
     {
       logger_->log_debug(name.c_str(), "Tailable Cursor is dead, requerying");
-      trigger->oplog_cursor = create_oplog_cursor(con_replica_, "local.oplog.rs", trigger->oplog_query);
+      //check if collection is local or replicated
+      mongo::DBClientConnection* con;
+      if(trigger->oplog_collection.find(repl_set) == 0)
+      {
+        con = con_replica_;
+      }
+      else
+      {
+        con = con_local_;
+      }
+
+      trigger->oplog_cursor = create_oplog_cursor(con, "local.oplog.rs", trigger->oplog_query);
     }
   }
 }
diff --git a/src/plugins/robot-memory/event_trigger_manager.h b/src/plugins/robot-memory/event_trigger_manager.h
index 6b872c5..06362e8 100644
--- a/src/plugins/robot-memory/event_trigger_manager.h
+++ b/src/plugins/robot-memory/event_trigger_manager.h
@@ -71,15 +71,16 @@ class EventTriggerManager
       //check if collection is local or replicated
       mongo::DBClientConnection* con;
       std::string oplog;
+      oplog = "local.oplog.rs";
       if(collection.find(repl_set) == 0)
       {
         con = con_replica_;
-        oplog = "local.oplog.rs";
+        if(!distributed_)
+          logger_->log_error(name.c_str(), "Can not add trigger for %s, if the robot memory is not configured to be distributed", collection.c_str());
       }
       else
       {
         con = con_local_;
-        oplog = "local.oplog.rs";
       }
 
       EventTrigger *trigger = new EventTrigger(oplog_query, collection, boost::bind(callback, obj, _1));
@@ -103,6 +104,7 @@ class EventTriggerManager
     mongo::DBClientConnection* con_replica_;
 
     std::string repl_set, local_db;
+    bool distributed_;
 
     std::list<EventTrigger*> triggers;
 };

- *commit* eddbbf495bad39a4dca4a26046317f3efaa59aba - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Mon Nov 21 18:07:35 2016 +0100
Subject: robot-memory: give collection in computable function

 .../computables/blackboard_computable.cpp          |    4 ++--
 .../computables/blackboard_computable.h            |    2 +-
 .../robot-memory/computables/computable.cpp        |    4 ++--
 src/plugins/robot-memory/computables/computable.h  |    4 ++--
 .../robot-memory/computables/computables_manager.h |    4 ++--
 src/plugins/robot-memory/robot_memory.h            |    2 +-
 .../robot-memory/test-plugin/robot_memory_test.h   |    6 +++---
 7 files changed, 13 insertions(+), 13 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/computables/blackboard_computable.cpp b/src/plugins/robot-memory/computables/blackboard_computable.cpp
index aff81c5..528f80f 100644
--- a/src/plugins/robot-memory/computables/blackboard_computable.cpp
+++ b/src/plugins/robot-memory/computables/blackboard_computable.cpp
@@ -23,7 +23,7 @@
 
 /** @class BlackboardComputable  blackboard_computable.h
  * Computable providing access to blackboard interfaces.
- * The Query has to match
+ * The Query has to match {interface:{$exists:true}} on the blackboard collection
  * @author Frederik Zwilling
  */
 
@@ -46,7 +46,7 @@ BlackboardComputable::~BlackboardComputable()
   robot_memory_->remove_computable(computable);
 }
 
-std::list<mongo::BSONObj> BlackboardComputable::compute_interfaces(mongo::BSONObj query)
+std::list<mongo::BSONObj> BlackboardComputable::compute_interfaces(mongo::BSONObj query, std::string collection)
 {
   std::list<mongo::BSONObj> res;
   std::string type = query.getField("interface").String();
diff --git a/src/plugins/robot-memory/computables/blackboard_computable.h b/src/plugins/robot-memory/computables/blackboard_computable.h
index bfee458..6019c20 100644
--- a/src/plugins/robot-memory/computables/blackboard_computable.h
+++ b/src/plugins/robot-memory/computables/blackboard_computable.h
@@ -37,7 +37,7 @@ class BlackboardComputable
     virtual ~BlackboardComputable();
 
   private:
-    std::list<mongo::BSONObj> compute_interfaces(mongo::BSONObj query);
+    std::list<mongo::BSONObj> compute_interfaces(mongo::BSONObj query, std::string collection);
 
     RobotMemory* robot_memory_;
     fawkes::BlackBoard* blackboard_;
diff --git a/src/plugins/robot-memory/computables/computable.cpp b/src/plugins/robot-memory/computables/computable.cpp
index 1b9e60b..592b45d 100644
--- a/src/plugins/robot-memory/computables/computable.cpp
+++ b/src/plugins/robot-memory/computables/computable.cpp
@@ -28,7 +28,7 @@ using namespace mongo;
  * @author Frederik Zwilling
  */
 
-Computable::Computable(Query query_to_compute, std::string collection, const boost::function<std::list<BSONObj> (BSONObj)> &compute_function)
+Computable::Computable(Query query_to_compute, std::string collection, const boost::function<std::list<BSONObj> (BSONObj, std::string)> &compute_function)
 {
   this->compute_function = compute_function;
   this->query_to_compute = query_to_compute;
@@ -48,7 +48,7 @@ Computable::~Computable()
 std::list<BSONObj> Computable::compute(BSONObj query)
 {
   // use provided function to compute demanded documents
-  std::list<BSONObj> docs = compute_function(query);
+  std::list<BSONObj> docs = compute_function(query, collection);
   //add metainformation for each document
   for(BSONObj &obj : docs)
   {
diff --git a/src/plugins/robot-memory/computables/computable.h b/src/plugins/robot-memory/computables/computable.h
index 5232b69..a15f474 100644
--- a/src/plugins/robot-memory/computables/computable.h
+++ b/src/plugins/robot-memory/computables/computable.h
@@ -28,7 +28,7 @@
 class Computable
 {
   public:
-    Computable(mongo::Query query_to_compute, std::string collection, const boost::function<std::list<mongo::BSONObj> (mongo::BSONObj)> &compute_function);
+    Computable(mongo::Query query_to_compute, std::string collection, const boost::function<std::list<mongo::BSONObj> (mongo::BSONObj, std::string)> &compute_function);
     virtual ~Computable();
 
     std::list<mongo::BSONObj> compute(mongo::BSONObj query);
@@ -36,7 +36,7 @@ class Computable
     std::string get_collection();
 
   private:
-    boost::function<std::list<mongo::BSONObj> (mongo::BSONObj)> compute_function;
+    boost::function<std::list<mongo::BSONObj> (mongo::BSONObj, std::string)> compute_function;
     mongo::Query query_to_compute;
     std::string collection;
 };
diff --git a/src/plugins/robot-memory/computables/computables_manager.h b/src/plugins/robot-memory/computables/computables_manager.h
index 0c3a9da..9e73945 100644
--- a/src/plugins/robot-memory/computables/computables_manager.h
+++ b/src/plugins/robot-memory/computables/computables_manager.h
@@ -51,9 +51,9 @@ class ComputablesManager
      * @return Computable Object pointer used for removing it
      */
     template<typename T>
-    Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj), T *obj)
+    Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj, std::string), T *obj)
     {
-      Computable* comp = new Computable(query_to_compute, collection, boost::bind(compute_func, obj, _1));
+      Computable* comp = new Computable(query_to_compute, collection, boost::bind(compute_func, obj, _1, _2));
       computables.push_back(comp);
       return comp;
     }
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 5f032f4..bda35ba 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -100,7 +100,7 @@ class RobotMemory
      * @return Computable Object pointer used for removing it
      */
     template<typename T>
-    Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj), T *obj)
+    Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj, std::string), T *obj)
     {
       return computables_manager_->register_computable(query_to_compute, collection, compute_func, obj);
     }
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.h b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
index cb12317..59413eb 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
@@ -89,13 +89,13 @@ class TestComputable
   };
    ~TestComputable(){};
    //Different functions for computables:
-   std::list<mongo::BSONObj> compute(mongo::BSONObj query)
+   std::list<mongo::BSONObj> compute(mongo::BSONObj query, std::string collection)
    {
      std::list<mongo::BSONObj> res;
      res.push_back(mongo::fromjson("{computed:true, result:'this is computed'}"));
      return res;
    }
-   std::list<mongo::BSONObj> compute_sum(mongo::BSONObj query)
+   std::list<mongo::BSONObj> compute_sum(mongo::BSONObj query, std::string collection)
    {
      std::list<mongo::BSONObj> res;
      int x = query.getField("x").Int();
@@ -107,7 +107,7 @@ class TestComputable
      res.push_back(b.obj());
      return res;
    }
-   std::list<mongo::BSONObj> compute_multiple(mongo::BSONObj query)
+   std::list<mongo::BSONObj> compute_multiple(mongo::BSONObj query, std::string collection)
    {
      std::list<mongo::BSONObj> res;
      res.push_back(mongo::fromjson("{compute:'multiple', count:1}"));

- *commit* a16ff219d8d12d36f252ecd7e45b0b0b742ea92b - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Nov 23 13:39:53 2016 +0100
Subject: robot-memory: added transform computable

 .../computables/transform_computable.cpp           |  112 ++++++++++++++++++++
 ...ckboard_computable.h => transform_computable.h} |   34 +++---
 src/plugins/robot-memory/robot_memory.cpp          |    6 +-
 src/plugins/robot-memory/robot_memory_thread.cpp   |    4 +-
 src/plugins/robot-memory/robot_memory_thread.h     |    4 +
 .../robot-memory/test-plugin/robot_memory_test.cpp |   19 +++-
 src/tools/gtest/gtest_fawkes.cpp                   |    2 +-
 7 files changed, 155 insertions(+), 26 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index d02a39b..62585cc 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -118,12 +118,12 @@ QResCursor RobotMemory::query(Query query, std::string collection)
   check_collection_name(collection);
   log_deb(std::string("Executing Query "+ query.toString() +" on collection "+collection));
 
-  //lock (mongo_client not thread safe)
-  MutexLocker lock(mutex_);
-
   //check if computation on demand is necessary and execute Computables
   computables_manager_->check_and_compute(query, collection);
 
+  //lock (mongo_client not thread safe)
+  MutexLocker lock(mutex_);
+
   //set read preference of query to nearest to read from the local replica set member first
   query.readPref(ReadPreference_Nearest, BSONArray());
 
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 5cf279e..fb2559a 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -59,8 +59,9 @@ RobotMemoryThread::init()
   //prepare aspect initializer
   robot_memory_inifin_.set_robot_memory(robot_memory);
 
-  //register blackboard computable
+  //register computables
   blackboard_computable = new BlackboardComputable(robot_memory, blackboard, logger);
+  transform_computable = new TransformComputable(robot_memory, tf_listener, logger, config);
 }
 
 
@@ -68,6 +69,7 @@ void
 RobotMemoryThread::finalize()
 {
   delete blackboard_computable;
+  delete transform_computable;
   robot_memory_inifin_.set_robot_memory(NULL);
   delete robot_memory;
 }
diff --git a/src/plugins/robot-memory/robot_memory_thread.h b/src/plugins/robot-memory/robot_memory_thread.h
index 23ce0ef..80bb7d2 100644
--- a/src/plugins/robot-memory/robot_memory_thread.h
+++ b/src/plugins/robot-memory/robot_memory_thread.h
@@ -30,11 +30,13 @@
 #include <plugins/mongodb/aspect/mongodb.h>
 #include <aspect/blackboard.h>
 #include <aspect/blocked_timing.h>
+#include <aspect/tf.h>
 #include <mongo/client/dbclient.h>
 #include <aspect/aspect_provider.h>
 #include "robot_memory.h"
 #include "aspect/robot_memory_inifin.h"
 #include "computables/blackboard_computable.h"
+#include "computables/transform_computable.h"
 
 #include <string>
 
@@ -51,6 +53,7 @@ class RobotMemoryThread
   public fawkes::MongoDBAspect,
 	public fawkes::BlockedTimingAspect,
   public fawkes::BlackBoardAspect,
+  public fawkes::TransformAspect,
   public fawkes::AspectProviderAspect
 {
  public:
@@ -68,6 +71,7 @@ class RobotMemoryThread
    RobotMemory* robot_memory;
    fawkes::RobotMemoryIniFin robot_memory_inifin_;
    BlackboardComputable* blackboard_computable;
+   TransformComputable* transform_computable;
 };
 
 #endif
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index 823abfc..ee138f1 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -23,6 +23,7 @@
 #include <interfaces/Position3DInterface.h>
 #include <list>
 #include <algorithm>
+#include <math.h>
 
 using namespace fawkes;
 using namespace mongo;
@@ -287,16 +288,16 @@ TEST_F(RobotMemoryTest, ComputableMultiple)
 
 TEST_F(RobotMemoryTest, BlackboardComputable)
 {
-  Position3DInterface* if3d = blackboard->open_for_writing<Position3DInterface>("test");
+  Position3DInterface* if3d = blackboard->open_for_writing<Position3DInterface>("test1");
   if3d->set_frame("test_frame");
   if3d->set_translation(0, 1.1);
   if3d->set_translation(1, 2.2);
   if3d->set_translation(2, 3.3);
   if3d->write();
-  QResCursor qres = robot_memory->query(fromjson("{interface:'Position3DInterface',id:'test'}"), "robmem.blackboard");
+  QResCursor qres = robot_memory->query(fromjson("{interface:'Position3DInterface',id:'test1'}"), "robmem.blackboard");
   ASSERT_TRUE(qres->more());
   ASSERT_TRUE(contains_pairs(qres->next(), fromjson(
-      "{interface:'Position3DInterface',id:'test',frame:'test_frame',translation:[1.1, 2.2, 3.3]}")));
+      "{interface:'Position3DInterface',id:'test1',frame:'test_frame',translation:[1.1, 2.2, 3.3]}")));
   blackboard->close(if3d);
 }
 
@@ -317,3 +318,15 @@ TEST_F(RobotMemoryTest, BlackboardComputableMultiple)
   blackboard->close(if3d);
   blackboard->close(if3d_2);
 }
+
+
+TEST_F(RobotMemoryTest, TransformComputable)
+{
+  robot_memory->insert("{name:'test pos', frame:'cam_tag', translation:[0.0, 0.0, 0.0], rotation:[0.0, 0.0, 0.0, 1.0]}", "robmem.test");
+  QResCursor qres = robot_memory->query(fromjson("{name:'test pos', frame:'base_link', allow_tf:true}"), "robmem.test");
+  ASSERT_TRUE(qres->more());
+  BSONObj res = qres->next();
+  ASSERT_EQ("base_link", res.getField("frame").String());
+  ASSERT_TRUE(fabs(0.1 - res.getField("translation").Array()[0].Double()) < 0.001);
+  ASSERT_TRUE(fabs(-0.5 - res.getField("rotation").Array()[0].Double()) < 0.001);
+}
diff --git a/src/tools/gtest/gtest_fawkes.cpp b/src/tools/gtest/gtest_fawkes.cpp
index 6c89db3..e601ad5 100644
--- a/src/tools/gtest/gtest_fawkes.cpp
+++ b/src/tools/gtest/gtest_fawkes.cpp
@@ -51,7 +51,7 @@ int main(int argc, char **argv) {
     fawkes_argv[1] = new char[2];
     strcpy(fawkes_argv[1], "-p");
     fawkes_argv[2] = new char[128];
-    strcpy(fawkes_argv[2], "m-robot-memory,robot_memory_test");
+    strcpy(fawkes_argv[2], "static-transforms,m-robot-memory,robot_memory_test");
     fawkes_argv[3] = new char[2];
     strcpy(fawkes_argv[3], "-c");
     fawkes_argv[4] = new char[128];

- *commit* 11aae2c10db961e9f326f13504fa67897f764495 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Nov 23 13:42:02 2016 +0100
Subject: robot-memory: fixed template function for trigger registration

 src/plugins/robot-memory/robot_memory.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index bda35ba..a701b57 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -86,7 +86,7 @@ class RobotMemory
     template<typename T>
     EventTrigger* register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
     {
-      return register_trigger(mongo::fromjson(query_str), collection, callback);
+      return register_trigger(mongo::fromjson(query_str), collection, callback, _obj);
     }
     void remove_trigger(EventTrigger* trigger);
 

- *commit* b97f940169eb4854be8789c89e108f589aba49b1 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Nov 23 15:26:25 2016 +0100
Subject: robot-memory: function to insert vector of documents

 src/plugins/robot-memory/robot_memory.cpp |   37 ++++++++++++++++++++++++++++-
 src/plugins/robot-memory/robot_memory.h   |    2 +
 2 files changed, 38 insertions(+), 1 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 62585cc..ccbfe0c 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -150,7 +150,7 @@ int RobotMemory::insert(BSONObj obj, std::string collection)
 {
   check_collection_name(collection);
 
-  log_deb(std::string("Executing Query "+ obj.toString() + " on collection " + collection));
+  log_deb(std::string("Inserting "+ obj.toString() + " into collection " + collection));
 
   //lock (mongo_client not thread safe)
   MutexLocker lock(mutex_);
@@ -169,6 +169,41 @@ int RobotMemory::insert(BSONObj obj, std::string collection)
 }
 
 /**
+ * Inserts all document of a vector into the robot memory
+ * @param v_obj The vector of BSONObj document
+ * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
+ * @return 1: Success 0: Error
+ */
+int RobotMemory::insert(std::vector<BSONObj> v_obj, std::string collection)
+{
+  check_collection_name(collection);
+
+  std::string insert_string = "[";
+  for(BSONObj obj : v_obj)
+  {
+    insert_string += obj.toString() + ",\n";
+  }
+  insert_string += "]";
+
+  log_deb(std::string("Inserting vector of documents " + insert_string+  " into collection " + collection));
+
+  //lock (mongo_client not thread safe)
+  MutexLocker lock(mutex_);
+
+  //actually execute insert
+  try{
+    mongodb_client_->insert(collection, v_obj);
+  } catch (DBException &e) {
+    std::string error = "Error for insert " + insert_string
+        + "\n Exception: " + e.toString();
+    log_deb(error, "error");
+    return 0;
+  }
+  //return success
+  return 1;
+}
+
+/**
  * Inserts a document into the robot memory
  * @param obj_str The document as json string
  * @param collection The database and collection to use as string (e.g. robmem.worldmodel)
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index a701b57..441ca99 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -26,6 +26,7 @@
 #include <aspect/logging.h>
 #include <aspect/blackboard.h>
 #include <memory>
+#include <vector>
 
 #include <mongo/client/dbclient.h>
 #include "interfaces/RobotMemoryInterface.h"
@@ -53,6 +54,7 @@ class RobotMemory
     //robot memory functions
     QResCursor query(mongo::Query query, std::string collection = "");
     int insert(mongo::BSONObj obj, std::string collection = "");
+    int insert(std::vector<mongo::BSONObj> v_obj, std::string collection = "");
     int insert(std::string obj_str, std::string collection = "");
     int update(mongo::Query query, mongo::BSONObj update, std::string collection = "", bool upsert = false);
     int update(mongo::Query query, std::string update_str, std::string collection = "", bool upsert = false);

- *commit* b78e868f28631d75614a767d2d653d2b6eba2f8d - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Nov 23 15:27:15 2016 +0100
Subject: robot-memory: Use RM instead of mongo client in computable_manager

 .../computables/computables_manager.cpp            |   18 ++++++++++--------
 .../robot-memory/computables/computables_manager.h |    7 +++++--
 src/plugins/robot-memory/robot_memory.cpp          |    2 +-
 3 files changed, 16 insertions(+), 11 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/computables/computables_manager.cpp b/src/plugins/robot-memory/computables/computables_manager.cpp
index da8189c..391ad69 100644
--- a/src/plugins/robot-memory/computables/computables_manager.cpp
+++ b/src/plugins/robot-memory/computables/computables_manager.cpp
@@ -21,6 +21,7 @@
 
 #include "computables_manager.h"
 #include <core/exception.h>
+#include <plugins/robot-memory/robot_memory.h>
 
 /** @class ComputablesManager  computables_manager.h
  *  This class manages registering computables and can check
@@ -32,11 +33,11 @@ using namespace fawkes;
 using namespace mongo;
 
 ComputablesManager::ComputablesManager(fawkes::Logger* logger, fawkes::Configuration* config,
-  mongo::DBClientBase* mongodb_client, fawkes::Clock* clock)
+  RobotMemory* robot_memory, fawkes::Clock* clock)
 {
   logger_ = logger;
   config_ = config;
-  mongodb_client_ = mongodb_client;
+  robot_memory_ = robot_memory;
   clock_ = clock;
 
   matching_test_collection_ = "robmem.computables_matching";
@@ -77,15 +78,16 @@ void ComputablesManager::remove_computable(Computable* computable)
  */
 bool ComputablesManager::check_and_compute(mongo::Query query, std::string collection)
 {
-  //logger_->log_info(name.c_str(), "checking query: %s", query.toString().c_str());
+  if(collection == matching_test_collection_)
+    return false; //not necessary for matching test itself
   bool added_computed_docs = false;
   //check if the query is matched by the computable identifyer
   //to do that we just insert the query as if it would be a document and query for it with the computable identifiers
-  mongodb_client_->dropCollection(matching_test_collection_);
-  mongodb_client_->insert(matching_test_collection_, query.obj);
+  robot_memory_->remove(fromjson("{}"), matching_test_collection_);
+  robot_memory_->insert(query.obj, matching_test_collection_);
   for(std::list<Computable*>::iterator it = computables.begin(); it != computables.end(); it++)
   {
-    if(collection == (*it)->get_collection() &&  mongodb_client_->query(matching_test_collection_, (*it)->get_query())->more())
+    if(collection == (*it)->get_collection() &&  robot_memory_->query((*it)->get_query(), matching_test_collection_)->more())
     {
       std::list<BSONObj> computed_docs_list = (*it)->compute(query.obj);
       if(computed_docs_list.size() > 0)
@@ -93,7 +95,7 @@ bool ComputablesManager::check_and_compute(mongo::Query query, std::string colle
         //move list into vector
         std::vector<BSONObj> computed_docs_vector{ std::make_move_iterator(std::begin(computed_docs_list)),
           std::make_move_iterator(std::end(computed_docs_list))};
-        mongodb_client_->insert((*it)->get_collection(), computed_docs_vector);
+        robot_memory_->insert(computed_docs_vector, (*it)->get_collection());
         added_computed_docs = true;
       }
     }
@@ -112,7 +114,7 @@ void ComputablesManager::cleanup_computed_docs()
 {
   for(std::string collection : collections_to_cleanup)
   {
-    mongodb_client_->remove(collection, fromjson("{'_robmem_info.computed':true}"));
+    robot_memory_->remove(fromjson("{'_robmem_info.computed':true}"), collection);
   }
   collections_to_cleanup.clear();
 }
diff --git a/src/plugins/robot-memory/computables/computables_manager.h b/src/plugins/robot-memory/computables/computables_manager.h
index 9e73945..c741a7c 100644
--- a/src/plugins/robot-memory/computables/computables_manager.h
+++ b/src/plugins/robot-memory/computables/computables_manager.h
@@ -30,11 +30,14 @@
 #include <boost/bind.hpp>
 #include <utility>
 
+//forward declaration
+class RobotMemory;
+
 class ComputablesManager
 {
   public:
     ComputablesManager(fawkes::Logger* logger, fawkes::Configuration* config,
-      mongo::DBClientBase* mongodb_client, fawkes::Clock* clock);
+      RobotMemory* robot_memory, fawkes::Clock* clock);
     virtual ~ComputablesManager();
 
     bool check_and_compute(mongo::Query query, std::string collection);
@@ -62,7 +65,7 @@ class ComputablesManager
     std::string name = "RobotMemory ComputablesManager";
     fawkes::Logger* logger_;
     fawkes::Configuration* config_;
-    mongo::DBClientBase* mongodb_client_;
+    RobotMemory* robot_memory_;
     fawkes::Clock* clock_;
 
     std::list<Computable*> computables;
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index ccbfe0c..d55bc79 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -96,7 +96,7 @@ void RobotMemory::init()
 
   //Setup event trigger and computables manager
   trigger_manager_ = new EventTriggerManager(logger_, config_);
-  computables_manager_ = new ComputablesManager(logger_, config_, mongodb_client_, clock_);
+  computables_manager_ = new ComputablesManager(logger_, config_, this, clock_);
 
   log_deb("Initialized RobotMemory");
 }

- *commit* 003ef75ab2670d818db02a96300dfb3483e67bcf - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Nov 23 21:20:50 2016 +0100
Subject: robot-memory: caching computables

 .../robot-memory/computables/computable.cpp        |   11 +++++-
 src/plugins/robot-memory/computables/computable.h  |    3 +-
 .../computables/computables_manager.cpp            |   38 +++++++++++++++-----
 .../robot-memory/computables/computables_manager.h |    9 +++--
 .../computables/transform_computable.cpp           |   11 ++----
 src/plugins/robot-memory/robot_memory.h            |    4 +-
 6 files changed, 53 insertions(+), 23 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/computables/computable.cpp b/src/plugins/robot-memory/computables/computable.cpp
index 592b45d..b8ac359 100644
--- a/src/plugins/robot-memory/computables/computable.cpp
+++ b/src/plugins/robot-memory/computables/computable.cpp
@@ -20,19 +20,23 @@
  */
 
 #include "computable.h"
+#include <chrono>
 
 using namespace mongo;
 
 /** @class Computable  computable.h
  * Class holding information for a single computable
+ * this class also enhances computed documents by additional information, such as the caching time
  * @author Frederik Zwilling
  */
 
-Computable::Computable(Query query_to_compute, std::string collection, const boost::function<std::list<BSONObj> (BSONObj, std::string)> &compute_function)
+Computable::Computable(Query query_to_compute, std::string collection, const boost::function<std::list<BSONObj> (BSONObj, std::string)> &compute_function, double caching_time)
 {
   this->compute_function = compute_function;
   this->query_to_compute = query_to_compute;
   this->collection = collection;
+  //convert caching time to milliseconds
+  this->caching_time = (int) (caching_time * 1000.0);
 }
 
 Computable::~Computable()
@@ -49,11 +53,16 @@ std::list<BSONObj> Computable::compute(BSONObj query)
 {
   // use provided function to compute demanded documents
   std::list<BSONObj> docs = compute_function(query, collection);
+  long long milliseconds_since_epoch =
+      std::chrono::system_clock::now().time_since_epoch() /
+      std::chrono::milliseconds(1);
+  long long cached_until = milliseconds_since_epoch + caching_time;
   //add metainformation for each document
   for(BSONObj &obj : docs)
   {
     BSONObjBuilder info_b;
     info_b.append("computed", true);
+    info_b.append("cached_until", cached_until);
     BSONObjBuilder obj_b;
     obj_b.appendElements(obj);
     obj_b.append("_robmem_info", info_b.obj());
diff --git a/src/plugins/robot-memory/computables/computable.h b/src/plugins/robot-memory/computables/computable.h
index a15f474..1783367 100644
--- a/src/plugins/robot-memory/computables/computable.h
+++ b/src/plugins/robot-memory/computables/computable.h
@@ -28,7 +28,7 @@
 class Computable
 {
   public:
-    Computable(mongo::Query query_to_compute, std::string collection, const boost::function<std::list<mongo::BSONObj> (mongo::BSONObj, std::string)> &compute_function);
+    Computable(mongo::Query query_to_compute, std::string collection, const boost::function<std::list<mongo::BSONObj> (mongo::BSONObj, std::string)> &compute_function, double caching_time = 0.0);
     virtual ~Computable();
 
     std::list<mongo::BSONObj> compute(mongo::BSONObj query);
@@ -39,6 +39,7 @@ class Computable
     boost::function<std::list<mongo::BSONObj> (mongo::BSONObj, std::string)> compute_function;
     mongo::Query query_to_compute;
     std::string collection;
+    int caching_time; //in milliseconds
 };
 
 #endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_COMPUTABLE_H_ */
diff --git a/src/plugins/robot-memory/computables/computables_manager.cpp b/src/plugins/robot-memory/computables/computables_manager.cpp
index 391ad69..4e2f21e 100644
--- a/src/plugins/robot-memory/computables/computables_manager.cpp
+++ b/src/plugins/robot-memory/computables/computables_manager.cpp
@@ -22,6 +22,7 @@
 #include "computables_manager.h"
 #include <core/exception.h>
 #include <plugins/robot-memory/robot_memory.h>
+#include <chrono>
 
 /** @class ComputablesManager  computables_manager.h
  *  This class manages registering computables and can check
@@ -78,6 +79,16 @@ void ComputablesManager::remove_computable(Computable* computable)
  */
 bool ComputablesManager::check_and_compute(mongo::Query query, std::string collection)
 {
+  //check if computation result of the query is already cached
+  for(std::map<std::tuple<std::string, std::string>, long long>::iterator it = cached_querries_.begin();
+      it != cached_querries_.end(); it++)
+  {
+    if(collection == std::get<0>(it->first) && query.toString() == std::get<1>(it->first))
+    {
+      logger_->log_info(name.c_str(), "Already computed");
+      return false;
+    }
+  }
   if(collection == matching_test_collection_)
     return false; //not necessary for matching test itself
   bool added_computed_docs = false;
@@ -95,15 +106,15 @@ bool ComputablesManager::check_and_compute(mongo::Query query, std::string colle
         //move list into vector
         std::vector<BSONObj> computed_docs_vector{ std::make_move_iterator(std::begin(computed_docs_list)),
           std::make_move_iterator(std::end(computed_docs_list))};
+        //remember how long a query is cached:
+        long long cached_until = computed_docs_vector[0].getField("_robmem_info").Obj().getField("cached_until").Long();
+        cached_querries_[std::make_tuple(collection, query.toString())] = cached_until;
+        //TODO: fix problem: equivalent queries in different order jield unequal strings
         robot_memory_->insert(computed_docs_vector, (*it)->get_collection());
         added_computed_docs = true;
       }
     }
   }
-  if(added_computed_docs)
-  {
-    collections_to_cleanup.push_back(collection);
-  }
   return added_computed_docs;
 }
 
@@ -112,9 +123,18 @@ bool ComputablesManager::check_and_compute(mongo::Query query, std::string colle
  */
 void ComputablesManager::cleanup_computed_docs()
 {
-  for(std::string collection : collections_to_cleanup)
-  {
-    robot_memory_->remove(fromjson("{'_robmem_info.computed':true}"), collection);
-  }
-  collections_to_cleanup.clear();
+  long long current_time_ms =
+          std::chrono::system_clock::now().time_since_epoch() /
+          std::chrono::milliseconds(1);
+  for(std::map<std::tuple<std::string, std::string>, long long>::iterator it = cached_querries_.begin();
+        it != cached_querries_.end(); it++)
+    {
+      if(current_time_ms > it->second)
+      {
+        logger_->log_info(name.c_str(), "Removing cache %s", std::get<0>(it->first).c_str());
+        robot_memory_->remove(BSON("_robmem_info.computed" << true
+            << "_robmem_info.cached_until" << BSON("$lt" << current_time_ms)), std::get<0>(it->first));
+        cached_querries_.erase(it->first);
+      }
+    }
 }
diff --git a/src/plugins/robot-memory/computables/computables_manager.h b/src/plugins/robot-memory/computables/computables_manager.h
index c741a7c..c4edb8b 100644
--- a/src/plugins/robot-memory/computables/computables_manager.h
+++ b/src/plugins/robot-memory/computables/computables_manager.h
@@ -29,6 +29,8 @@
 #include "computable.h"
 #include <boost/bind.hpp>
 #include <utility>
+#include <map>
+#include <tuple>
 
 //forward declaration
 class RobotMemory;
@@ -54,9 +56,9 @@ class ComputablesManager
      * @return Computable Object pointer used for removing it
      */
     template<typename T>
-    Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj, std::string), T *obj)
+    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)
     {
-      Computable* comp = new Computable(query_to_compute, collection, boost::bind(compute_func, obj, _1, _2));
+      Computable* comp = new Computable(query_to_compute, collection, boost::bind(compute_func, obj, _1, _2), caching_time);
       computables.push_back(comp);
       return comp;
     }
@@ -70,7 +72,8 @@ class ComputablesManager
 
     std::list<Computable*> computables;
     std::string matching_test_collection_;
-    std::list<std::string> collections_to_cleanup;
+    //cached querries as ((collection, querry), cached_until)
+    std::map<std::tuple<std::string, std::string>, long long> cached_querries_;
 };
 
 #endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_COMPUTABLES_COMPUTABLES_MANAGER_H_ */
diff --git a/src/plugins/robot-memory/computables/transform_computable.cpp b/src/plugins/robot-memory/computables/transform_computable.cpp
index fdfc907..cb082e1 100644
--- a/src/plugins/robot-memory/computables/transform_computable.cpp
+++ b/src/plugins/robot-memory/computables/transform_computable.cpp
@@ -55,8 +55,6 @@ TransformComputable::~TransformComputable()
 
 std::list<mongo::BSONObj> TransformComputable::compute_transform(mongo::BSONObj query, std::string collection)
 {
-  logger_->log_info(name_, "Tfcomputable: %s", query.toString().c_str());
-
   //get positions in other frames
   BSONObjBuilder query_other_frames;
   query_other_frames.appendElements(query.removeField("frame").removeField("allow_tf"));
@@ -69,7 +67,6 @@ std::list<mongo::BSONObj> TransformComputable::compute_transform(mongo::BSONObj
   while(cur->more())
   {
     BSONObj pos = cur->next();
-    logger_->log_info(name_, "Transforming: %s", pos.toString().c_str());
     if(pos.hasField("frame") && pos.hasField("translation") && pos.hasField("rotation"))
     {
       std::string src_frame = pos.getField("frame").String();
@@ -102,10 +99,10 @@ std::list<mongo::BSONObj> TransformComputable::compute_transform(mongo::BSONObj
 
         res.push_back(res_pos.obj());
       }
-      else
-      {
-        logger_->log_info(name_, "Cant transform %s to %s", src_frame.c_str(), target_frame.c_str());
-      }
+//      else
+//      {
+//        logger_->log_info(name_, "Cant transform %s to %s", src_frame.c_str(), target_frame.c_str());
+//      }
     }
   }
   return res;
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 441ca99..2deb923 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -102,9 +102,9 @@ class RobotMemory
      * @return Computable Object pointer used for removing it
      */
     template<typename T>
-    Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj, std::string), T *obj)
+    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)
     {
-      return computables_manager_->register_computable(query_to_compute, collection, compute_func, obj);
+      return computables_manager_->register_computable(query_to_compute, collection, compute_func, obj, caching_time);
     }
     void remove_computable(Computable* computable);
 

- *commit* 151f6f8779ac6d49df82a8c5df5ee25e01c25a6a - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Nov 24 14:38:14 2016 +0100
Subject: openrave-robot-memory: constructing motion planner scenes from robot memory

 .../interfaces/OpenraveRobotMemoryInterface.cpp    |  199 ++++++++++++++++++++
 ...rInterface.h => OpenraveRobotMemoryInterface.h} |   54 +++---
 ...ce.tolua => OpenraveRobotMemoryInterface.tolua} |   25 +--
 .../interfaces/OpenraveRobotMemoryInterface.xml    |   18 ++
 src/plugins/Makefile                               |    2 +-
 .../aspect => openrave-robot-memory}/Makefile      |   28 ++--
 .../openrave-robot-memory_plugin.cpp}              |   24 +--
 .../openrave-robot-memory_thread.cpp               |   69 +++++++
 .../openrave-robot-memory_thread.h}                |   34 ++--
 9 files changed, 367 insertions(+), 86 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/Makefile b/src/plugins/Makefile
index 791fbaf..91de496 100644
--- a/src/plugins/Makefile
+++ b/src/plugins/Makefile
@@ -18,7 +18,7 @@ include $(BASEDIR)/etc/buildsys/config.mk
 
 # base + hardware drivers + perception + functional + integration
 SUBDIRS	= bbsync bblogger webview ttmainloop rrd rrdweb \
-	  laser imu flite festival joystick openrave \
+	  laser imu flite festival joystick openrave openrave-robot-memory\
 	  katana jaco pantilt roomba nao robotino \
 	  bumblebee2 perception amcl \
 	  skiller luaagent \

- *commit* fa3aa7b81289c559be300f67fcc1f02a88f2eb42 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Nov 24 18:11:13 2016 +0100
Subject: robot-memory: fixed transform computable not keeping fields

 .../computables/transform_computable.cpp           |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/computables/transform_computable.cpp b/src/plugins/robot-memory/computables/transform_computable.cpp
index cb082e1..6e87f18 100644
--- a/src/plugins/robot-memory/computables/transform_computable.cpp
+++ b/src/plugins/robot-memory/computables/transform_computable.cpp
@@ -82,8 +82,9 @@ std::list<mongo::BSONObj> TransformComputable::compute_transform(mongo::BSONObj
         fawkes::tf::Stamped<fawkes::tf::Pose> res_stamped_pose;
         tf_->transform_pose(target_frame.c_str(), src_stamped_pose, res_stamped_pose);
 
-        res_pos.appendElements(query.removeField("frame").removeField("translation").removeField("rotation"));
+        res_pos.appendElements(pos.removeField("frame").removeField("translation").removeField("rotation").removeField("_id"));
         res_pos.append("frame", target_frame);
+        res_pos.append("allow_tf", true);
         BSONArrayBuilder arrb_trans;
         arrb_trans.append(res_stamped_pose.getOrigin().x());
         arrb_trans.append(res_stamped_pose.getOrigin().y());
@@ -95,8 +96,6 @@ std::list<mongo::BSONObj> TransformComputable::compute_transform(mongo::BSONObj
         arrb_rot.append(res_stamped_pose.getRotation().z());
         arrb_rot.append(res_stamped_pose.getRotation().w());
         res_pos.append("rotation", arrb_rot.arr());
-        //logger_->log_info(name_, "Tf res: %s", res_pos.obj().toString().c_str());
-
         res.push_back(res_pos.obj());
       }
 //      else

- *commit* 5545f7e590a413cb24f63c7af58081fb645a8806 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Nov 24 18:12:04 2016 +0100
Subject: robot-memory: multithreading robust checking if query mathes a computable

 .../computables/computables_manager.cpp            |   11 +++++------
 src/plugins/robot-memory/robot_memory.cpp          |    2 +-
 2 files changed, 6 insertions(+), 7 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/computables/computables_manager.cpp b/src/plugins/robot-memory/computables/computables_manager.cpp
index 4e2f21e..655b20f 100644
--- a/src/plugins/robot-memory/computables/computables_manager.cpp
+++ b/src/plugins/robot-memory/computables/computables_manager.cpp
@@ -85,20 +85,19 @@ bool ComputablesManager::check_and_compute(mongo::Query query, std::string colle
   {
     if(collection == std::get<0>(it->first) && query.toString() == std::get<1>(it->first))
     {
-      logger_->log_info(name.c_str(), "Already computed");
       return false;
     }
   }
-  if(collection == matching_test_collection_)
+  if(collection.find(matching_test_collection_) != std::string::npos)
     return false; //not necessary for matching test itself
   bool added_computed_docs = false;
   //check if the query is matched by the computable identifyer
   //to do that we just insert the query as if it would be a document and query for it with the computable identifiers
-  robot_memory_->remove(fromjson("{}"), matching_test_collection_);
-  robot_memory_->insert(query.obj, matching_test_collection_);
+  std::string current_test_collection = matching_test_collection_ + std::to_string(rand());
+  robot_memory_->insert(query.obj, current_test_collection);
   for(std::list<Computable*>::iterator it = computables.begin(); it != computables.end(); it++)
   {
-    if(collection == (*it)->get_collection() &&  robot_memory_->query((*it)->get_query(), matching_test_collection_)->more())
+    if(collection == (*it)->get_collection() &&  robot_memory_->query((*it)->get_query(), current_test_collection)->more())
     {
       std::list<BSONObj> computed_docs_list = (*it)->compute(query.obj);
       if(computed_docs_list.size() > 0)
@@ -115,6 +114,7 @@ bool ComputablesManager::check_and_compute(mongo::Query query, std::string colle
       }
     }
   }
+  robot_memory_->drop_collection(current_test_collection);
   return added_computed_docs;
 }
 
@@ -131,7 +131,6 @@ void ComputablesManager::cleanup_computed_docs()
     {
       if(current_time_ms > it->second)
       {
-        logger_->log_info(name.c_str(), "Removing cache %s", std::get<0>(it->first).c_str());
         robot_memory_->remove(BSON("_robmem_info.computed" << true
             << "_robmem_info.cached_until" << BSON("$lt" << current_time_ms)), std::get<0>(it->first));
         cached_querries_.erase(it->first);
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index d55bc79..d010b3e 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -83,7 +83,7 @@ void RobotMemory::init()
   try {
     debug_ = config_->get_bool("/plugins/robot-memory/more-debug-output");
   } catch (Exception &e) {}
-  database_name_ = "mobmem";
+  database_name_ = "robmem";
   try {
     database_name_ = config_->get_string("/plugins/robot-memory/database");
   } catch (Exception &e) {}

- *commit* 2826e879bdaa81efe345489518360bafda28895e - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Nov 24 18:13:16 2016 +0100
Subject: openrave-robot-memory: add and place block objects in openrave

 src/plugins/openrave-robot-memory/Makefile         |   11 ++++++-
 .../openrave-robot-memory_thread.cpp               |   28 ++++++++++++++++++++
 .../openrave-robot-memory_thread.h                 |    6 ++++
 3 files changed, 43 insertions(+), 2 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/openrave-robot-memory/Makefile b/src/plugins/openrave-robot-memory/Makefile
index 784f101..5c2e504 100644
--- a/src/plugins/openrave-robot-memory/Makefile
+++ b/src/plugins/openrave-robot-memory/Makefile
@@ -26,20 +26,27 @@ OBJS_openrave_robot_memory = openrave-robot-memory_plugin.o openrave-robot-memor
 
 OBJS_all = $(OBJS_openrave-robot-memory)
 
-ifeq ($(HAVE_MONGODB),1)
+ifeq ($(HAVE_CPP11)$(HAVE_MONGODB),11)
+  CFLAGS  += $(CFLAGS_CPP11)
+  
   PLUGINS_all = $(PLUGINDIR)/openrave-robot-memory.$(SOEXT)
 else
   ifneq ($(HAVE_MONGODB),1)
     WARN_TARGETS += warning_mongodb
   endif
+  ifneq ($(HAVE_CLIPS),1)
+    WARN_TARGETS = warning_clips
+  endif
 endif
 
 ifeq ($(OBJSSUBMAKE),1)
 all: $(WARN_TARGETS)
 
-.PHONY: warning_mongodb
+.PHONY: warning_mongodb warning_cpp11
 warning_mongodb:
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting openrave-robot-memory Plugin$(TNORMAL) (mongodb[-devel] not installed)"
+warning_cpp11:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Cannot build clips-robot-memory plugin$(TNORMAL) (C++11 not supported)"
 endif
 
 
diff --git a/src/plugins/openrave-robot-memory/openrave-robot-memory_thread.cpp b/src/plugins/openrave-robot-memory/openrave-robot-memory_thread.cpp
index 545b8d3..3e34936 100644
--- a/src/plugins/openrave-robot-memory/openrave-robot-memory_thread.cpp
+++ b/src/plugins/openrave-robot-memory/openrave-robot-memory_thread.cpp
@@ -22,6 +22,7 @@
 #include "openrave-robot-memory_thread.h"
 
 using namespace fawkes;
+using namespace mongo;
 
 /** @class OpenraveRobotMemoryThread 'openrave-robot-memory_thread.h' 
  * Creates an OpenRave Scene for motion planning from data in the robot memory
@@ -66,4 +67,31 @@ void
 OpenraveRobotMemoryThread::construct_scene()
 {
   logger->log_info(name(), "Constructing Scene");
+
+  //add or move already added objects:
+  QResCursor cur = robot_memory->query(fromjson("{block:{$exists:true},frame:'base_link',allow_tf:true}"), collection_);
+  while(cur->more())
+  {
+    BSONObj block = cur->next();
+    logger->log_info(name(), "Block: %s", block.toString().c_str());
+    std::string block_name = block.getStringField("block");
+    if(std::find(added_objects_.begin(), added_objects_.end(), block_name) == added_objects_.end())
+    {
+      //add new object
+      logger->log_info(name(), "adding %s", block_name.c_str());
+      OpenRaveInterface::AddObjectMessage add_msg;
+      add_msg.set_name(block_name.c_str());
+      add_msg.set_path("../fawkes/res/openrave/cylinder.kinbody.xml");
+      openrave_if_->msgq_enqueue_copy(&add_msg);
+      added_objects_.push_back(block_name);
+    }
+    //move object to right position
+    OpenRaveInterface::MoveObjectMessage move_msg;
+    move_msg.set_name(block_name.c_str());
+    move_msg.set_x(block.getField("translation").Array()[0].Double());
+    move_msg.set_y(block.getField("translation").Array()[1].Double());
+    move_msg.set_z(block.getField("translation").Array()[2].Double());
+    openrave_if_->msgq_enqueue_copy(&move_msg);
+  }
+  logger->log_info(name(), "Finished Constructing Scene");
 }
diff --git a/src/plugins/openrave-robot-memory/openrave-robot-memory_thread.h b/src/plugins/openrave-robot-memory/openrave-robot-memory_thread.h
index e237104..7aba40b 100644
--- a/src/plugins/openrave-robot-memory/openrave-robot-memory_thread.h
+++ b/src/plugins/openrave-robot-memory/openrave-robot-memory_thread.h
@@ -29,6 +29,9 @@
 #include <aspect/configurable.h>
 #include <interfaces/OpenRaveInterface.h>
 #include <interfaces/OpenraveRobotMemoryInterface.h>
+#include <plugins/robot-memory/aspect/robot_memory_aspect.h>
+#include <list>
+#include <algorithm>
 
 namespace fawkes {
   // add forward declarations here, e.g., interfaces
@@ -39,6 +42,7 @@ class OpenraveRobotMemoryThread
   public fawkes::BlockedTimingAspect,
   public fawkes::LoggingAspect,
   public fawkes::ConfigurableAspect,
+  public fawkes::RobotMemoryAspect,
   public fawkes::BlackBoardAspect
 {
 
@@ -56,6 +60,8 @@ class OpenraveRobotMemoryThread
   std::string collection_;
   fawkes::OpenRaveInterface* openrave_if_;
   fawkes::OpenraveRobotMemoryInterface* or_rm_if_;
+  std::list<std::string> added_objects_;
+
   void construct_scene();
 };
 

- *commit* 583d1f64d327d2f3a01f0d68de7083f4bbbae1c7 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Nov 30 15:02:17 2016 +0100
Subject: clips-robot-memory: added function (bson-has-hield ?obj "field")

 .../clips_robot_memory_thread.cpp                  |   18 ++++++++++++++++++
 .../clips-robot-memory/clips_robot_memory_thread.h |    1 +
 2 files changed, 19 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
index 3b9e4f9..187d1fb 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.cpp
@@ -96,6 +96,7 @@ ClipsRobotMemoryThread::clips_context_init(const std::string &env_name,
     );
   clips->add_function("robmem-trigger-destroy", sigc::slot<void, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_robotmemory_destroy_trigger)));
   clips->add_function("bson-field-names", sigc::slot<CLIPS::Values, void *>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_field_names)));
+  clips->add_function("bson-has-field", sigc::slot<CLIPS::Value, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_has_field)));
   clips->add_function("bson-get", sigc::slot<CLIPS::Value, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get)));
   clips->add_function("bson-get-array", sigc::slot<CLIPS::Values, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get_array)));
   clips->add_function("bson-get-time", sigc::slot<CLIPS::Values, void *, std::string>(sigc::mem_fun(*this, &ClipsRobotMemoryThread::clips_bson_get_time)));
@@ -583,6 +584,23 @@ ClipsRobotMemoryThread::clips_bson_get(void *bson, std::string field_name)
   }
 }
 
+CLIPS::Value
+ClipsRobotMemoryThread::clips_bson_has_field(void *bson, std::string field_name)
+{
+  mongo::BSONObjBuilder *b = static_cast<mongo::BSONObjBuilder *>(bson);
+
+  if (! b) {
+    logger->log_error("MongoDB", "mongodb-bson-get: invalid object");
+    return CLIPS::Value("FALSE", CLIPS::TYPE_SYMBOL);
+  }
+
+  mongo::BSONObj o(b->asTempObj());
+
+  if (! o.hasField(field_name)) {
+    return CLIPS::Value("FALSE", CLIPS::TYPE_SYMBOL);
+  }
+  return CLIPS::Value("TRUE", CLIPS::TYPE_SYMBOL);
+}
 
 CLIPS::Values
 ClipsRobotMemoryThread::clips_bson_get_array(void *bson, std::string field_name)
diff --git a/src/plugins/clips-robot-memory/clips_robot_memory_thread.h b/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
index f4fd1f4..54977ae 100644
--- a/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
+++ b/src/plugins/clips-robot-memory/clips_robot_memory_thread.h
@@ -90,6 +90,7 @@ class ClipsRobotMemoryThread
   CLIPS::Value  clips_robotmemory_cursor_next(void *cursor);
   void          clips_robotmemory_cursor_destroy(void *cursor);
   CLIPS::Values clips_bson_field_names(void *bson);
+  CLIPS::Value  clips_bson_has_field(void *bson, std::string field_name);
   CLIPS::Value  clips_bson_get(void *bson, std::string field_name);
   CLIPS::Values clips_bson_get_array(void *bson, std::string field_name);
   CLIPS::Values clips_bson_get_time(void *bson, std::string field_name);

- *commit* b30af5c2df61f2e288f8f094be0110b55b01a604 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Nov 30 15:03:09 2016 +0100
Subject: robot-memory: fixed trigger on local replica set

 src/plugins/robot-memory/event_trigger_manager.cpp |    6 +++---
 src/plugins/robot-memory/event_trigger_manager.h   |   11 +++--------
 2 files changed, 6 insertions(+), 11 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/event_trigger_manager.cpp b/src/plugins/robot-memory/event_trigger_manager.cpp
index 684ce51..73dba88 100644
--- a/src/plugins/robot-memory/event_trigger_manager.cpp
+++ b/src/plugins/robot-memory/event_trigger_manager.cpp
@@ -21,7 +21,6 @@
 
 
 #include "event_trigger_manager.h"
-#include <plugin/loader.h>
 #include <boost/bind.hpp>
 
 using namespace fawkes;
@@ -42,9 +41,10 @@ EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
     std::string err_msg = "Could not connect to mongod process: "+ errmsg;
     throw PluginLoadException("robot-memory", err_msg.c_str());
   }
+  repl_set_dist = config_->get_string("plugins/robot-memory/setup/replicated/replica-set-name");
+  repl_set_local = config_->get_string("plugins/robot-memory/setup/local/replica-set-name");
   if(distributed_)
   {
-    repl_set = config_->get_string("plugins/robot-memory/setup/replicated/replica-set-name");
     con_replica_ = new mongo::DBClientConnection();
     if(!con_replica_->connect("localhost:" + std::to_string(config_->get_uint("plugins/robot-memory/setup/replicated/port")), errmsg))
     {
@@ -79,7 +79,7 @@ void EventTriggerManager::check_events()
       logger_->log_debug(name.c_str(), "Tailable Cursor is dead, requerying");
       //check if collection is local or replicated
       mongo::DBClientConnection* con;
-      if(trigger->oplog_collection.find(repl_set) == 0)
+      if(trigger->oplog_collection.find(repl_set_dist) == 0)
       {
         con = con_replica_;
       }
diff --git a/src/plugins/robot-memory/event_trigger_manager.h b/src/plugins/robot-memory/event_trigger_manager.h
index 06362e8..a28f023 100644
--- a/src/plugins/robot-memory/event_trigger_manager.h
+++ b/src/plugins/robot-memory/event_trigger_manager.h
@@ -28,6 +28,7 @@
 #include <list>
 #include "event_trigger.h"
 #include <boost/bind.hpp>
+#include <plugin/loader.h>
 
 
 ///typedef for shorter type description
@@ -72,16 +73,10 @@ class EventTriggerManager
       mongo::DBClientConnection* con;
       std::string oplog;
       oplog = "local.oplog.rs";
-      if(collection.find(repl_set) == 0)
-      {
+      if(collection.find(repl_set_dist) == 0)
         con = con_replica_;
-        if(!distributed_)
-          logger_->log_error(name.c_str(), "Can not add trigger for %s, if the robot memory is not configured to be distributed", collection.c_str());
-      }
       else
-      {
         con = con_local_;
-      }
 
       EventTrigger *trigger = new EventTrigger(oplog_query, collection, boost::bind(callback, obj, _1));
       trigger->oplog_cursor = create_oplog_cursor(con, oplog, oplog_query);
@@ -103,7 +98,7 @@ class EventTriggerManager
     mongo::DBClientConnection* con_local_;
     mongo::DBClientConnection* con_replica_;
 
-    std::string repl_set, local_db;
+    std::string repl_set_dist, repl_set_local, local_db;
     bool distributed_;
 
     std::list<EventTrigger*> triggers;

- *commit* 2b98b38794db6a0ad71e8e0f210a8f588acf3b3b - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Wed Nov 30 16:51:06 2016 +0100
Subject: pddl-robot-memory: added interface files

 ...veRobotMemoryInterface.h => PddlGenInterface.h} |   46 +++--
 .../interfaces/PddlGenInterface.cpp                |  235 ++++++++++++++++++++
 .../interfaces/PddlGenInterface.h_ext}             |   46 +++--
 .../interfaces/PddlGenInterface.tolua}             |   25 ++-
 4 files changed, 301 insertions(+), 51 deletions(-)





-- 
Fawkes Robotics Framework                 http://www.fawkesrobotics.org


More information about the fawkes-commits mailing list