Using the C++ client library

Description: How to use the C++ client library to talk to the warehouse

Tutorial Level: BEGINNER

Contents

The mongo_ros package provides a C++ ROS client library to the DB. For now, we just have an example of use. Note that this requires the db server to be running, as described in the previous tutorial.

https://kforge.ros.org/warehousewg/warehouse-hg/raw-file/tip/mongo_ros/test/test_mongo_ros.cpp

   1 #include "test_mongo_helpers.h"
   2 #include <mongo_ros/message_collection.h>
   3 #include <mongo_ros/exceptions.h>
   4 #include <ros/ros.h>
   5 #include <boost/foreach.hpp>
   6 #include <gtest/gtest.h>
   7 
   8 namespace mr=mongo_ros;
   9 namespace gm=geometry_msgs;
  10 using std::vector;
  11 using std::string;
  12 
  13 typedef mr::MessageWithMetadata<gm::Pose> PoseWithMetadata;
  14 typedef PoseWithMetadata::ConstPtr PoseMetaPtr;
  15 
  16 // Helper function that creates metadata for a message.
  17 // Here we'll use the x and y position, as well as a 'name'
  18 // field that isn't part of the original message.
  19 mr::Metadata makeMetadata (const gm::Pose& p, const string& v)
  20 {
  21   return mr::Metadata("x", p.position.x, "y", p.position.y, "name", v);
  22 }
  23 
  24 TEST(MongoRos, MongoRos)
  25 {
  26   // Symbols used in queries to denote binary predicates for < and >
  27   // Note that equality is the default, so we don't need a symbol for it
  28   using mr::LT;
  29   using mr::GT;
  30 
  31   // Clear existing data if any
  32   mr::dropDatabase("my_db");
  33 
  34   // Set up db
  35   mr::MessageCollection<gm::Pose> coll("my_db", "poses");
  36 
  37   // Arrange to index on metadata fields 'x' and 'name'
  38   coll.ensureIndex("name");
  39   coll.ensureIndex("x");
  40 
  41   // Add some poses and metadata
  42   const gm::Pose p1 = makePose(24, 42, 0);
  43   const gm::Pose p2 = makePose(10, 532, 3);
  44   const gm::Pose p3 = makePose(53, 22, 5);
  45   const gm::Pose p4 = makePose(22, -5, 33);
  46   coll.insert(p1, makeMetadata(p1, "bar"));
  47   coll.insert(p2, makeMetadata(p2, "baz"));
  48   coll.insert(p3, makeMetadata(p3, "qux"));
  49   coll.insert(p1, makeMetadata(p1, "oof"));
  50   coll.insert(p4, makeMetadata(p4, "ooof"));
  51   EXPECT_EQ(5u, coll.count());
  52 
  53   // Simple query: find the pose with name 'qux' and return just its metadata
  54   // Since we're doing an equality check, we don't explicitly specify a predicate
  55   vector<PoseMetaPtr> res = coll.pullAllResults(mr::Query("name", "qux"), true);
  56   EXPECT_EQ(1u, res.size());
  57   EXPECT_EQ("qux", res[0]->lookupString("name"));
  58   EXPECT_DOUBLE_EQ(53, res[0]->lookupDouble("x"));
  59   
  60   // Set up query: position.x < 40 and position.y > 0.  Reverse order
  61   // by the "name" metadata field.  Also, here we pull the message itself, not
  62   // just the metadata.  Finally, we can't use the simplified construction
  63   // syntax here because it's too long
  64   mr::Query q = mr::Query().append("x", mr::LT, 40).append("y", mr::GT, 0);
  65   vector<PoseMetaPtr> poses = coll.pullAllResults(q, false, "name", false);
  66   
  67   // Verify poses. 
  68   EXPECT_EQ(3u, poses.size());
  69   EXPECT_EQ(p1, *poses[0]);
  70   EXPECT_EQ(p2, *poses[1]);
  71   EXPECT_EQ(p1, *poses[2]);
  72 
  73   EXPECT_EQ("oof", poses[0]->lookupString("name"));
  74   EXPECT_EQ("baz", poses[1]->lookupString("name"));
  75   EXPECT_EQ("bar", poses[2]->lookupString("name"));
  76 
  77   // Set up query to delete some poses.
  78   mr::Query q2 ("y", mr::LT, 30);
  79 
  80   EXPECT_EQ(5u, coll.count());
  81   EXPECT_EQ(2u, coll.removeMessages(q2));
  82   EXPECT_EQ(3u, coll.count());
  83 
  84   // Test findOne
  85   mr::Query q4("name", "bar");
  86   EXPECT_EQ(p1, *coll.findOne(q4, false));
  87   EXPECT_DOUBLE_EQ(24, coll.findOne(q4, true)->lookupDouble("x"));
  88 
  89   mr::Query q5("name", "barbar");
  90   EXPECT_THROW(coll.findOne(q5, true), mr::NoMatchingMessageException);
  91   EXPECT_THROW(coll.findOne(q5, false), mr::NoMatchingMessageException);
  92   
  93   // Test update
  94   coll.modifyMetadata(q4, mr::Metadata("name", "barbar"));
  95   EXPECT_EQ(3u, coll.count());
  96   EXPECT_THROW(coll.findOne(q4, false), mr::NoMatchingMessageException);
  97   ROS_INFO("here");
  98   EXPECT_EQ(p1, *coll.findOne(q5, false));
  99 
 100   // Check stored metadata
 101   boost::shared_ptr<mongo::DBClientConnection> conn =
 102     mr::makeDbConnection(ros::NodeHandle());
 103   EXPECT_EQ("geometry_msgs/Pose", mr::messageType(*conn, "my_db", "poses"));
 104 }
 105 
 106 
 107 int main (int argc, char** argv)
 108 {
 109   ros::init(argc, argv, "client_test");
 110   ros::NodeHandle nh;
 111   testing::InitGoogleTest(&argc, argv);
 112   return RUN_ALL_TESTS();
 113 }
 114  

Wiki: warehousewg/Tutorials/Using the C++ client library (last edited 2011-06-23 00:20:13 by BhaskaraMarthi)