UCSD-Quadcopter / SLAM-ROS-Node

Contains code for the SLAM Node Cluster
BSD 3-Clause "New" or "Revised" License
1 stars 0 forks source link

Write Sensor Template Class #5

Closed nickwn closed 5 years ago

nickwn commented 5 years ago

Directions

Write a class in C++ that contains much of the needed sensor functionality. The class should allow easy extension to read data from multiple different sensor types and publish the data in a unified format. To accommodate this, sensors will output to two topics (not just one, yes I changed it): "sensors/<sensor>/data", which will contain standard data readings from the sensor; and "sensors/<sensor>/meta", which will contain a sensor matrix that stores the matrix to translate the system state into the sensor reading state format. This will be published once at the beginning of the program. The matrices will be published in ros as type Float32MultiArray, and it should work with matrices of any size. Here is the general class outline:

class isensor
{
public:
    // ctors - already implemented by default, wanted to be explicit
    isensor(std::string topic) : topic_(topic) {}

    // interface funcions

    // implemented by subclass to return sensor-specific matrix
    // which converts sensor reading data to object state
    template<std::size_t r_, std::size_t c_>
    virtual matf<r_, c_> get_sensor_mat() {}

    // implemented by subclass to get sensor data from arduino, etc
    template<std::size_t r_, std::size_t c_>
    virtual matf<r_, c_> get_sensor_data() {}

    // implemented functions

    // initialization, ex start ros, etc
    void start() {}

    // sensor loop that continually checks for new sensor readings and outputs data to topic
    void update_loop() {}

    // -- any helper methods --
    // ex to publish to specified topic

private:

    std::string topic_;
    // -- instance vars needed --
};

This relies on the following mat definition:

template<typename Tp_, std::size_t r_, std::size_t c_>
struct mat 
{ 
    constexpr mat(Tp_* d) : data_(d) {}
    constexpr Tp_* data() { return data_; } 
    constexpr std::size_t rows() { return r_; }
    constexpr std::size_t cols() { return c_; }
    Tp_* data_;
};

template<std::size_t r_, std::size_t c_>
using matf = mat<float, r_, c_>;

Mat can be used like so:

float d[] = { 1.0f, 2.0f, 3.0f, 4.0f };
matf<2, 2> m = d;

A main method isn't necessary, put this definition at the top of the ISensor file and put SENSOR_NODE_MAIN(<Sensor class>, "<topic>"); after every sub class definition.

#define SENSOR_NODE_MAIN(Sensor, topic) \
    int main() \
    { \
        Sensor s(topic); \
        s.start(); \
        s.update_loop(); \
    }
trulyronak commented 5 years ago

http://docs.ros.org/jade/api/std_msgs/html/msg/Float32MultiArray.html

trulyronak commented 5 years ago

Made some modifications from the original specs provided, so I'll try to explain my thought process below.

  1. Rethought out main function A main method is actually essential for Ros nodes to function, and following some research (aka googling), I came across this forum question, and noted how they implemented the main function and have it interface with the class. This is also why I renamed update_loop() to be pulse()

  2. Renamed update_loop() to be pulse() In the main method, I run pulse() once per "spin", and so pulse should no longer actually loop, but instead think of itself as the method that runs once per loop, and should return the value to publish (a Float32MultiArray).

  3. Moved certain methods to be private

Specifically, I moved

template<std::size_t r_, std::size_t c_>
virtual matf<r_, c_> get_sensor_mat() {}
template<std::size_t r_, std::size_t c_>
virtual matf<r_, c_> get_sensor_data() {}

to become private methods. This is because none of these methods will be used in the way the code works (see 1)

  1. Changed Visibility of topic and added name Really just a design decision, see my main for why this makes sense