I am having some troubles with c++ inheritance and I cannot find the error. I have class that implements a simple unicycle kinematic model.
namespace kinematics{
class Unicycle{
// state variables
geometry_msgs::Pose2D _state; ///< position of the robot
// robot parameters
float _max_linear_vel; ///< maximum linear velocity, saturation
float _b; ///< output point offset
// integration variables
float _int_step; ///< integration step
protected:
void _updateOdometry(float dv, float tr);
void _ioLinearization(float vx, float vy, double &d, double &t);
public:
Unicycle();
Unicycle(float is, float b, float vmax, geometry_msgs::Pose2D initS);
};
}
Since a differential drive kinematic model is an extension to the unicycle I would like to implement using inheritance.
#include "unicycle/Unicycle.h"
class DiffDrive: public kinematics::Unicycle {
//robot parameters
float _wheel_radius; ///< wheel radius
float _wheel_separation; ///< distance between wheels
void _wheelSpeed(float dv, float tr, float &rs, float &ls);
public:
DiffDrive();
DiffDrive(float wr, float ws, geometry_msgs::Pose2D initS,
float ts, float vmax, float b);
};
I wrote the constructor in this way
DiffDrive::DiffDrive(float wr,
float ws,
geometry_msgs::Pose2D initS,
float ts,
float vmax,
float b)
:Unicycle(ts,b,vmax,initS), _wheel_radius{wr}, _wheel_separation{ws}{
}
However when I use the function _wheelSpeed()
void DiffDrive::_wheelSpeed(float dv, float tr, float &rs, float &ls){
ls = dv - _wheel_separation*tr/2.f;
ls = ls/_wheel_radius;
rs = _wheel_separation*tr/_wheel_radius + ls;
std::cout << "PARS: " << _wheel_separation << " - " << _wheel_radius << std::endl;
std::cout << "WHEELS: " << rs << " - " << ls << std::endl;
}
The value of _wheel_separation and _wheel_radius are different from what expected:
PARS: -179014 - 4.58631e-41
Even if the constructor is invoked with the following values:
wheel_radius = 0.02;
wheel_sep = 0.04;
_diff_drive = new DiffDrive(wheel_radius,wheel_sep,update_period,vel_max,offset);
Please help me understand what's wrong with my code.
Check out the differences between inheritance and composition.
Think of it this way:
Is a differential drive a unicycle or is a differential drive a part of a unicycle?
Doesn't inheritance make more sense in this way:
Cycle is a base class
Unicycle is a derived class
Tricycle is another derived class.
Differential drive is something that is a part of a unicycle.
I think if the design is correct, the rest will fall in place automatically. The values you are getting look like either uninitialised values or values of an object that was already destroyed (again uninitialised values.)
I figured out what was wrong. I remember that in Java it was allowed to invoke a constructor from another constructor so to hide some parameters and avoid to rewrite the entire initialization. For example:
constructor1(par 1, par2){
par3 = 0;
constructor2(par1,par2,par3);
}
I am not sure that this is correct, but that is what I thought.
Therefore I implemented my constructor in the following way
DiffDrive::DiffDrive(const float wr,
const float ws,
float ts,
float vmax,
float b):Unicycle(ts,b,vmax){
geometry_msgs::Pose2d initS;
initS.x = 0;
initS.y = 0;
initS.theta = 0;
DiffDrive(wr,ws,initS,ts,vmax,b);
}
Unfortunately this is not legal in C++, that returned the result of the instantiation of the outer constructor ignoring the inner one.
I apologize if I didn't put this constructor in the previous question, but I simply forgot about it. I was my mistake.
thanks for the help and sorry for wasting your time.
Related
I'm trying to create an abstract class for ordinary differential equations, and have its independent variable use a different name in the inheriting classes. How do I go about that?
I don't want to allocate more memory for the renaming of the variable, i.e. create a new variable or a pointer to the base variable, as that's counterproductive. I just want to be able to access it with a different name in my inheriting classes, so that it's easier to know what the independent variable represents.
Mayhap a better question is, does the functionality of variable name overriding even exist in C++?
To give some code:
class ODE {
private:
int numEqns
double* q; // dependent variables
public:
double s; // independent variable
ODE(int numEqns) {
this->numEqns = numEqns;
this->q = new double[numEqns];
}
SetQOfIdxTo(int idx, double val) {
this->q[idx] = val;
}
};
class SpringODE : public ODE {
public:
double mass;
double c; // damping coefficient
double k; // spring constant
double d0; // initial deflection
SpringODE(double mass, double c, double k, double d0) : ODE(2) {
this->mass = mass;
this->c = c;
this->k = k;
this->d0 = d0;
time = 0.0;
SetQOfIdxTo(0, 0.0);
SetQOfIdxTo(1, d0);
}
};
The code is based on the one given in Grant Palmer's book "Physics for Game Programmers". The book in question being why I'm asking this question, as out of nowhere the time variable's Get function returns the base classes' GetS() function, which just returns "s" (albeit the code in the book is written in Java).
I need to calculate the radius of the circle in the code.
#include <iostream>
#include <cmath>
using namespace std;
class Circle {
float radius;
const float PI=3.14;
public:
Circle(float radius){
}
Circle getRadius()
{
return radius;
}
Circle setRadius(float radius)
{
this->radius = radius / PI;
return radius;
}
float Area()
{
return radius*radius*PI;
}
float Perimeter()
{
return 2*radius*PI;
}
int equal()
{
return Area()==Perimeter();
}
};
int main() {
float r;
cin >> r;
Circle c(r);
cout << c.Perimeter() << endl;
cout << c.Area() << endl;
cout << c.equal() <<endl;
return 0;
}
i tried to use pointers but i cannot figure it out.
In
Circle(float radius){
}
a parameter with the same name as a member variable is not that member variable. Instead, it shadows the member variable, effectively replacing it unless you know where to look. Passing a value into a parameter named radius will not change the value of the member variable named radius, and this leaves the member radius uninitialized.
This means that
float Perimeter()
{
return 2*radius*PI;
}
and the other functions, excluding setRadius, operate on an uninitialized variable and the results will be undefined.
A possible solution is to ensure the member radius is initialized to the value of the parameter radius.
You cannot simply
Circle(float radius){
radius = radius;
}
because there is only one radius, the member has been shadowed, so the parameter radius assigns its value to itself. This is legal code so it compiles, but often the compiler will issue a warning.
Instead use
Circle(float radius) : radius(radius) {
}
This makes use of the Member Initializer List, one of the most important (and seemingly least-taught) features of the C++ programming language. It allows you to safely reuse the term radius because the first radius must be the member radius.
You could also
Circle(float radius) {
this->radius = radius;
}
to explicitly use the member radius, but for more complicated members this approach can be inefficient. All member variables and base classes are initialized before entering the body of the constructor. Afterward the best you can do is assign. This means the member will be default-initialized (if a default constructor exists; if it doesn't you must use the member initializer list), then a temporary variable must be constructed and this temporary is then assigned to the member. potentially a lot of extra work for no benefit.
Side note:
Keep an eye on the this->radius = radius / PI; in setRadius. It is unusual and probably a bug.
I have a 2d physics engine that I've been programming in C++ using SFML; I've implemented a rough collision detection system for all SandboxObjects (the base class for every type of physics object), but I have a dilemma.
I plan to have many different derived classes of SandboxObjects, such as Circles, Rects, and so on, but I want a way to check if the roughHitbox of each SandboxObject collides with another.
When the program starts, it allocates memory for, let's say, 10,000 Circles
int circleCount = 0;//the number of active Circles
constexpr int m_maxNumberOfCircles = 10000;//the greatest number of circles able to be set active
Circle* m_circles = new Circle[m_maxNumberOfCircles];//create an array of circles that aren't active by default
like so.
and every time the user 'spawns' a new Circle, the code runs
(m_circles + circleCount)->setActive();`
circleCount++
Circles that aren't alive essentially do not exist at all; they might have positions and radii, but that info will never be used if that Circle is not active.
Given all this, what I want to do is to loop over all the different arrays of derived classes of SandboxObject because SandboxObject is the base class which implements the rough hitbox stuff, but because there will be many different derived classes, I don't know the best way to go about it.
One approach I did try (with little success) was to have a pointer to a SandboxObject
SandboxObject* m_primaryObjectPointer = nullptr;
this pointer would be null unless there were > 1 SandboxObjects active; with it, I tried using increment and decrement functions that checked if it could point to the next SandboxObject, but I couldn't get that to work properly because a base class pointer to a derived class acts funky. :/
I'm not looking for exact code implementations, just a proven method for working with the base class of many different derived classes.
Let me know if there's anything I should edit in this question or if there's any more info I could provide.
Your problems are caused by your desire to use a polymorphic approach on non-polymorphic containers.
The advantage of a SandboxObject* m_primaryObjectPointer is that it allows you to treat your objects polymorphicaly: m_primaryObjectPointer -> roughtHitBox() will work regardless of the object's real type being Circle, Rectangle, or a Decagon.
But iterating using m_primaryObjectPointer++ will not work as you expect: this iteration assumes that you iterate over contiguous objects in an array of SandboxObject elements (i.e. the compiler will use the base type's memory layout to compute the next address).
Instead, you may consider iterating over a vector (or an array if you really want to deal with extra memory management hassle) of pointers.
vector<SandboxObject*> universe;
populate(universe);
for (auto object:unviverse) {
if (object->isActive()) {
auto hb = object -> roughtHitBox();
// do something with that hitbox
}
}
Now managing the objects in the universe can be painful as well. You may therefore consider using smart pointers instead:
vector<shared_ptr<SandboxObject>> universe;
(little demo)
It's hard to answer this without knowing the requirements but you could have sandbox maintain two vectors of active and inactive objects, and use unique_ptrs of the base class for memory management.
Some code below:
#include <vector>
#include <memory>
#include <iostream>
class sandbox_object {
public:
virtual void do_something() = 0;
};
class circle : public sandbox_object {
private:
float x_, y_, radius_;
public:
circle(float x, float y, float r) :
x_(x), y_(y), radius_(r)
{}
void do_something() override {
std::cout << "i'm a circle.\n";
}
};
class triangle : public sandbox_object {
private:
float x1_, y1_, x2_, y2_, x3_, y3_;
public:
triangle( float x1, float y1, float x2, float y2, float x3, float y3) :
x1_(x1), y1_(y1), x2_(x2), y2_(y2), x3_(x3), y3_(y3)
{}
void do_something() override {
std::cout << "i'm a triangle.\n";
}
};
class sandbox {
using sandbox_iterator = std::vector<std::unique_ptr<sandbox_object>>::iterator;
private:
std::vector<std::unique_ptr<sandbox_object>> active_objects_;
std::vector<std::unique_ptr<sandbox_object>> inactive_objects_;
public:
void insert_circle(float x, float y, float r) {
active_objects_.push_back( std::make_unique<circle>(x, y, r) );
}
void insert_triangle(float x1, float y1, float x2, float y2, float x3, float y3) {
active_objects_.push_back( std::make_unique<triangle>(x1,y1,x2,y2,x3,y3));
}
sandbox_iterator active_objs_begin() {
return active_objects_.begin();
}
sandbox_iterator active_objs_end() {
return active_objects_.end();
}
void make_inactive(sandbox_iterator iter) {
std::unique_ptr<sandbox_object> obj = std::move(*iter);
active_objects_.erase(iter);
inactive_objects_.push_back(std::move(obj));
}
};
int main() {
sandbox sb;
sb.insert_circle(10.0f, 10.0f, 2.0f);
sb.insert_triangle(1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 1.0f);
sb.insert_circle(1.0f, 6.0f, 4.0f);
sb.make_inactive(sb.active_objs_begin());
(*sb.active_objs_begin())->do_something(); // this should be the triangle...
return 0;
}
Say I have a C++ function that looks like this:
double myfunction(double a, double b) {
// do something
}
Which I then call like this:
double a = 1.0;
double b = 2.0;
double good_r = myfunction(a, b);
double bad_r = myfunction(b, a); // compiles fine
I would like to make sure that a and b are never provided in the wrong order.
What is the best way to ensure this in C++?
Other languages allow named parameters, like this:
double good_r = myfunction(a=a, b=b);
double bad_r = myfunction(a=b, b=a); // mistake immediately obvious
double bad_r = myfunction(b=b, a=a); // compiles fine
Or perhaps the problem can be partly solved using types, i.e.
double my_type_safe_function(a_type a, b_type b) {
// do something
}
a_type a = 1.0;
b_type b = 2.0;
double good_r = myfunction(a, b);
double bad_r = myfunction(b, a); // compilation error
EDIT: A couple of people have asked what I mean by the "wrong order." What I mean is that, in real code a and b have some significance. For example, the arguments might instead be height and width. The difference between them is very important for the function to return the correct result. However, they are both floats and they both have the same dimensions (i.e. a length). Also, there is no "obvious" order for them. The person writing the function declaration may assume (width, height) and the person using the function may assume (height, width). I would like a way to ensure this doesn't happen by mistake. With two parameters it is easy to be careful with the order, but in a large project and with up to 6 arguments mistakes creep in.
Ideally I would like the checks to be done at compile time, and for there to be no performance hit (i.e. at the end of the day they are treated as plain old floats or whatever).
How about this:
struct typeAB {float a; float b; };
double myfunction(typeAB p) {
// do something
return p.a - p.b;
}
int main()
{
typeAB param;
param.a = 1.0;
param.b = 2.0;
float result = myfunction(param);
return 0;
}
Of course, you can still mess up when you assign your parameter(s) but that risk is hard to avoid :)
A variant is to have one struct per "new" type, and then make them go away in optimized builds using macros.
Something along these lines (only slightly tested, so it could be way off):
#define SAFE 0
#if SAFE
#define NEWTYPE(name, type) \
struct name { \
type x; \
explicit name(type x_) : x(x_) {}\
operator type() const { return x; }\
}
#else
#define NEWTYPE(name, type) typedef type name
#endif
NEWTYPE(Width, double);
NEWTYPE(Height, double);
double area(Width w, Height h)
{
return w * h;
}
int main()
{
cout << area(Width(10), Height(20)) << endl;
// This line says 'Could not convert from Height to Width' in g++ if SAFE is on.
cout << area(Height(10), Width(20)) << endl;
}
I think you already provided the easiest solution, using types.
One alternative could be using a builder class and method chaining.
Like:
class MyfunctionBuilder {
MyFunctionBuilder & paramA(double value);
MyFunctionBuilder & paramB(double value);
double execute();
(...)
}
Which you would use like this:
double good_r = MyFunctionBuilder().paramA(a).paramB(b).execute();
But this is a lot of extra code to write!
What is the "wrong order" actually? In this example of yours
double myfunction(double a, double b) {
// do something
}
double a = 1.0;
double b = 2.0;
double good_r = myfunction(a, b);
double bad_r = myfunction(b, a);
how do you actually want to know if this is the right order? What if the variables would be named "quapr" and "moo" instead of "a" and "b"? Then it would be impossible to guess whether the order is right or wrong just by looking at them.
With this in mind, you can do at least two things. First, is to give meaningfull names to the arguments, e.g.
float getTax( float price, float taxPercentage )
instead of
float getTax( float a, float b )
Second, do the necessary checks inside:
float divide( float dividend, float divisor )
{
if( divisor == 0 )
{
throw "omg!";
}
}
It is possible to do more complex checks, such as making a functor, and setting it's parameters explicitly, but in most of the cases that just complicates things without much benefit.
I have this definition for my structure:
struct localframevelo
{
double ivelo; //i(x) component of velocity
double cvelo; //c(y) component of velocity
double rvelo; //r(z) component of velocity
double speed; //total magnitude of velocity
localframevelo()
{
ivelo = 0;
cvelo = 0;
rvelo = 0;
speed = 0;
}
localframevelo(double init_ivelo, double init_cvelo, double init_rvelo)
{
ivelo = init_ivelo;
cvelo = init_cvelo;
rvelo = init_rvelo;
speed = sqrt(pow(ivelo, 2.0) + pow(cvelo, 2.0) + pow(rvelo, 2.0));
}
};
Here is a class that I am trying to use the default constructor of localframevelo in:
class missionprofile
{
//misison waypoints structure************************
private:
double stdholdtime; // 0.25 second within tolerance radius to "reach" a waypoint
double stdtolrad; // 0.5 meter tolerance radius (error magnitude) to "be at" a waypoint
localframevelo stdvelo;
waypoint missionwaypoints[MAXLISTLENGTH];
int numwaypoints;
public:
missionprofile();
missionprofile(int points, double StdHoldTime, double StdTolRadius, localframevelo StdVelo);
};
Here is the implementation of the default constructor for the class that I am trying to call the localframevelo's default constructor:
missionprofile::missionprofile()
{
numwaypoints = 0;
stdholdtime = 0;
stdtolrad = 0;
stdvelo(); //ERROR
}
I get this error: call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type. I am using the mbed compiler, what is wrong with my code?
You can safely remove this line:
stdvelo();
In the context of a function body, this is interpreted as a call to the operator()() of an instance of localframevelo, not an initialization. The data member will be default constructed anyway without any explicit initialization. But what you should really be doing is to initialize your data members in the constructor's initialization list:
missionprofile::missionprofile()
: numwaypoints(),
stdholdtime(),
stdtolrad(),
stdvelo()
{
}
And similarly for localframevelo's constructors and the other missionprofile constructor.
When you write stdvelo(), the compiler sees stdvelo.operator()() and then complains when no such function exists.
The data member is going to be constructed anyway; you don't need the line at all.
Also, it's marginally faster to use initialization rather than assignment for your starting values (though chances are high that your compiler will optimize away the difference anyway).
So you'd use this, for example, for the second constructor:
localframevelo(double init_ivelo, double init_cvelo, double init_rvelo)
: ivelo(init_velo)
, cvelo(init_cvelo)
, rvelo(init_rvelo)
, speed(sqrt(pow(ivelo, 2.0) + pow(cvelo, 2.0) + pow(rvelo, 2.0)))
{}
For the first, you'd just use 0 instead of init_velo et al.