Permalink
Browse files

Now, tgDataLogger2 can take and manage tgSenseable objects from an ap…

…p. Currently, it just prints out information about them. Next step is to create the sensorInfo objects.
  • Loading branch information...
apsabelhaus committed Jan 6, 2017
1 parent db7e5ce commit e68955f72996726be744250182ffd04784b30929
View
@@ -18,7 +18,7 @@ subdirs(
)
add_definitions(
-Wall
# -Wall
)
# Don't need to edit below this line.
View
@@ -18,6 +18,7 @@ add_library( ${PROJECT_NAME} SHARED
tgUnidirComprSprActuator.cpp
tgWorld.cpp
tgSimulation.cpp
tgSenseable.cpp
tgBulletRenderer.cpp
tgSimView.cpp
tgSimViewGraphics.cpp
View
@@ -183,6 +183,26 @@ std::vector<tgModel*> tgModel::getDescendants() const
return result;
}
/**
* For tgSenseable: just return the results of getDescendants here.
* This should be OK, since a vector of tgModel* is also a vector of
* tgSenseable*.
*/
std::vector<tgSenseable*> tgModel::getSenseableDescendants() const
{
//return getDescendants();
//DEBUGGING: test if this is a type issue...
//return std::vector<tgSenseable*>();
// Seems to work. So, how about we make a new list, populate it
// with tgModels, and return that.
std::vector<tgModel*> myDescendants = getDescendants();
std::vector<tgSenseable*> mySenseableDescendants;
for (size_t i=0; i < myDescendants.size(); i++) {
mySenseableDescendants.push_back(myDescendants[i]);
}
return mySenseableDescendants;
}
const std::vector<abstractMarker>& tgModel::getMarkers() const {
return m_markers;
}
@@ -192,16 +212,10 @@ void tgModel::addMarker(abstractMarker a){
}
/**
* The methods for tgSenseable.
* Note again that these are NOT ever supposed to be called,
* only the childrens' methods should be called.
* For tgSenseable.
*/
std::string tgModel::getDataHeading(){
return "tgModel_BASE_CLASS_NO_DATA";
}
std::string tgModel::getData(){
return "tgModel_BASE_CLASS_NO_DATA";
std::string tgModel::getLabelForSensor(){
return "tgModel";
}
bool tgModel::invariant() const
View
@@ -156,15 +156,17 @@ class tgModel : public tgTaggable, public tgSenseable
void addMarker(abstractMarker a);
/**
* From tgSenseable: must re-implement the data collecting methods.
* However, this function in tgModel should never really be called,
* only the child classes' methods should be called.
* This is because we're always trying to sense something like
* a tgRod or a tgSpringCableActuator, not a base tgModel.
* From tgSenseable: give a label of this type of senseable object.
* Note that child classes (e.g. rods) re-define this.
* This is also why the keyword "virtual" is used here.
*/
virtual std::string getDataHeading();
virtual std::string getData();
virtual std::string getLabelForSensor();
/**
* From tgSenseable: need to return all the children of this class.
* Since tgModels are tgSenseables, just return getDescendants().
*/
virtual std::vector<tgSenseable*> getSenseableDescendants() const;
private:
View
@@ -99,6 +99,7 @@ std::string tgRod::getLabelForSensor(){
return "rod";
}
bool tgRod::invariant() const
{
return
View
@@ -0,0 +1,53 @@
/*
* Copyright © 2012, United States Government, as represented by the
* Administrator of the National Aeronautics and Space Administration.
* All rights reserved.
*
* The NASA Tensegrity Robotics Toolkit (NTRT) v1 platform is licensed
* under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
/**
* @file tgSenseable.h
* @brief Constains the implementation of mixin class tgSenseable.
* @author Drew Sabelhaus
* $Id$
*/
// This module
#include "tgSenseable.h"
// From the C++ standard library:
//#include <iostream> //for strings
//#include <vector> //for lists of descendants
//#include <assert.h> //for assertions
/**
* This function shouldn't ever be called, so output something generic.
*/
std::string tgSenseable::getLabelForSensor(){
return "base_tgSenseable";
}
/**
* Return an empty vector of descendants.
* It's up to child classes to re-implement this.
*/
std::vector<tgSenseable*> tgSenseable::getSenseableDescendants() const{
// For this base class, no descendants are present.
// In fact, this method should never be called, only the subclasses'
// methods should be called!
std::cout << "WARNING! No tgSenseable descendants are present. Are you calling the right function?." << std::endl;
return std::vector<tgSenseable*>();
}
View
@@ -28,7 +28,7 @@
// From the C++ standard library:
#include <iostream> //for strings
//#include <assert.h> //for assertions
#include <vector> //for lists of descendants
/**
* This class is used to abstract away the class of pointers
@@ -37,6 +37,8 @@
*/
class tgSenseable
{
public:
/**
* Ideally, this class would have no member functions.
* However, since C++ requires at least one virtual member function
@@ -47,9 +49,15 @@ class tgSenseable
* or something like that.
* Include a generic output here that really should be redefined later.
*/
virtual std::string getLabelForSensor(){
return "base_tgSenseable";
}
virtual std::string getLabelForSensor();
/**
* In order to create sensors for a whole hierarchy of senseable objects,
* sense-able objects need to have references to thei children.
* This will be used in a tgDataManager's setup and step functions.
* For now, this 'should' be handled by tgModel's getDescendants function.
*/
virtual std::vector<tgSenseable*> getSenseableDescendants() const;
};
@@ -86,6 +86,8 @@ int main(int argc, char** argv)
std::string log_filename = "~/NTRTsim_logs/AppTgBoxAnchorDebugDemo";
// First, create the data manager
tgDataLogger2* myDataLogger = new tgDataLogger2(log_filename);
// Then, add the model to the data logger
myDataLogger->addSenseable(myModel);
// Next, attach it to the simulation
simulation.addDataManager(myDataLogger);
// and everything else should happen automatically.
@@ -34,6 +34,7 @@
#include <stdexcept>
#include <cassert>
#include <iostream>
#include <vector> // for managing descendants of tgSenseables.
/**
* The constructor for this class only assigns the filename prefix.
@@ -77,6 +78,28 @@ void tgDataLogger2::setup()
tgDataManager::setup();
//DEBUGGING
std::cout << "tgDataLogger2 setup." << std::endl;
// First, check that we're getting the tgSenseables that we want.
// Each of the elements in m_senseables may have descendants.
// Note that we do NOT check for duplicates, unlike the descendants management
// in tgModel.
std::vector< std::vector<tgSenseable*> > descendants;
//DEBUGGING
std::cout << "There are the following senseables that were directly attached to this tgDataLogger2: " << std::endl;
for (size_t i=0; i < m_senseables.size(); i++) {
std::cout << m_senseables[i]->getLabelForSensor() << std::endl;
descendants.push_back( m_senseables[i]->getSenseableDescendants());
}
std::cout << "The descendants of each of these sense-ables are: " << std::endl;
for (size_t i=0; i< descendants.size(); i++) {
std::cout << "Senseable number: " << i << " has "
<< descendants[i].size() << " descendants, and they are: "
<< std::endl;
for (size_t j=0; j < descendants[i].size(); j++) {
std::cout << descendants[i][j]->getLabelForSensor() << std::endl;
}
}
// TO-DO: setup everything!
// Postcondition
@@ -41,7 +41,7 @@
tgDataManager::tgDataManager()
{
//DEBUGGING
std::cout << "tgDataManager constructor." << std::endl;
//std::cout << "tgDataManager constructor." << std::endl;
// Postcondition
assert(invariant());
}
@@ -55,7 +55,7 @@ tgDataManager::tgDataManager()
tgDataManager::~tgDataManager()
{
//DEBUGGING
std::cout << "tgDataManager destructor." << std::endl;
//std::cout << "tgDataManager destructor." << std::endl;
// First, delete everything in m_sensors.
const size_t n_Sens = m_sensors.size();
@@ -83,7 +83,7 @@ tgDataManager::~tgDataManager()
void tgDataManager::setup()
{
//DEBUGGING
std::cout << "tgDataManager setup." << std::endl;
//std::cout << "tgDataManager setup." << std::endl;
// TO-DO: Should we create the sensors here in the setup method of the base?
// What's the best way to maximize code re-use?
// Postcondition
@@ -100,7 +100,7 @@ void tgDataManager::setup()
void tgDataManager::teardown()
{
//DEBUGGING
std::cout << "tgDataManager teardown." << std::endl;
//std::cout << "tgDataManager teardown." << std::endl;
// First, delete the sensors.
// Note that it's good practice to set deleted pointers to NULL here.
@@ -117,6 +117,16 @@ void tgDataManager::teardown()
// Next, delete the sensor infos.
// TO-DO: implement this.
// Clear the list of senseable objects.
// Since tgDataManagers don't ever change these objects,
// leave it to other classes to create and delete them.
// Just get rid of the pointers here.
// TO-DO: maybe we don't want to do this? Will this make it so no logs
// are created upon reset???
// TO-DO: could this segfault? Will the pointers in m_senseables be changed
// during reset at all?
//m_senseables.clear();
// Postcondition
assert(invariant());
assert(m_sensors.empty());
@@ -129,7 +139,7 @@ void tgDataManager::teardown()
void tgDataManager::step(double dt)
{
//DEBUGGING
std::cout << "tgDataManager step." << std::endl;
//std::cout << "tgDataManager step." << std::endl;
if (dt <= 0.0)
{
throw std::invalid_argument("dt is not positive");
@@ -170,13 +180,14 @@ void tgDataManager::addSensorInfo(tgSensorInfo* pSensorInfo)
* It takes in a pointer to a sense-able object and pushes it to the
* current list of tgSenseables.
*/
/*
void tgDataManager::addSenseable(tgSensable* pSenseable)
void tgDataManager::addSenseable(tgSenseable* pSenseable)
{
//DEBUGGING
std::cout << "tgDataManager addSenseable." << std::endl;
// Precondition
if (pSenseable == NULL)
{
throw std::invalid_argument("pSenseable is NULL inside tgDataManager::addSensable");
throw std::invalid_argument("pSenseable is NULL inside tgDataManager::addSenseable");
}
m_senseables.push_back(pSenseable);
@@ -185,7 +196,7 @@ void tgDataManager::addSenseable(tgSensable* pSenseable)
assert(invariant());
assert(!m_senseables.empty());
}
*/
/**
* The toString method for data managers should include a list of the number
@@ -30,7 +30,7 @@
//#include "tgCast.h"
//#include "tgTaggable.h"
//#include "tgTagSearch.h"
//#include "core/tgSenseable.h"
#include "core/tgSenseable.h" //not sure why this needs to be included vs. just declared...
// The C++ Standard Library
#include <string>
#include <sstream>
@@ -40,7 +40,7 @@
// Forward declarations
//class tgWorld;
class tgSensor;
class tgSenseable;
//class tgSenseable;
//class tgSensorInfo;
/**
@@ -90,7 +90,7 @@ class tgDataManager
* These objects will be checked via the sensor infos, and sensors will
* be assigned to them if appropriate.
*/
//virtual void addSenseable(tgSenseable* pSenseable);
virtual void addSenseable(tgSenseable* pSenseable);
/**
* Add a sensor info object to the current list of sensor infos.
@@ -128,7 +128,7 @@ class tgDataManager
* A data manager will also have a list of tgSenseable objects
* (really, just tgModels most of the time) that it will collect data from.
*/
//std::vector<tgSenseable*> m_senseables;
std::vector<tgSenseable*> m_senseables;
};

0 comments on commit e68955f

Please sign in to comment.