0% found this document useful (0 votes)
100 views

C++ Learn: Object Oriented Programming

Object oriented programming (OOP) is used in C++ and is based on classes. Classes act as templates that define objects, which contain both data (attributes) and functions (methods). To use a class, it must be defined with the class keyword, specifying attributes and methods. An object is then instantiated from the class, which allocates memory and allows accessing/modifying the object's attributes via its methods. Constructors can also be used to initialize an object's attributes when it is created. Includes allow classes defined in one file to be used in another.

Uploaded by

Harish M
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
100 views

C++ Learn: Object Oriented Programming

Object oriented programming (OOP) is used in C++ and is based on classes. Classes act as templates that define objects, which contain both data (attributes) and functions (methods). To use a class, it must be defined with the class keyword, specifying attributes and methods. An object is then instantiated from the class, which allocates memory and allows accessing/modifying the object's attributes via its methods. Constructors can also be used to initialize an object's attributes when it is created. Includes allow classes defined in one file to be used in another.

Uploaded by

Harish M
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

C++ Learn

The organization method/principle used in C++ is called Object Oriented Programming and it is based on the concept of
C++ classes.

Object Oriented Programming


Object-oriented programming has many advantages:
• OOP is faster and easier to execute
• OOP provides a clear structure for the programs
• OOP makes the code easier to maintain, modify and debug
• OOP makes it possible to create full reusable applications with less development time

Objects are the basic unit of oriented programming. They have both data and functions that operate as one item.

Classes are templates for objects, with its data and functions called class attributes and class methods. Objects will be
instances of a class.

C++ Classes
we've been using objects in the course, every time we needed the class RosbotClass we would create an object rosbot:

RosbotClass rosbot;

Class names - start with Upper case


Objects - all lower case letters

How to define a class in C++


// definition of the class
class Hobbit {

// Access specifiers of the class..here public. Everything indented below public can be accessed anywhere where the object
is visible.
// Other possibilities are private and protected.
// Good practice to declare attributes as private.
public:

// Here we define the attributes of the class


// These attributes exist everytime we create an object of this class, but can have different values.
// Attributes are like global variables -> these attributes can be used by any function that belongs to the class
string name;
float height;
int age;

// Here, we create the Methods of the class

void get_name() {
cout << “This hobbits name is ” << name << endl; // You can see attribute name used here
}

void convert_height_to_cm();
}

How to instanciate a class in C++


int main() {
// create an instance or object of the class

Hobbit first_hobbit;

first_hobbit.name = “Frodo”;
first_hobbit.age = 28;
first_hobbit.get_name();

Defining object's attributes


Once the object has all its attributes initialized, they can have the values we want. That's why we choose 'Frodo' as a
name, 28 as its age and 1.15 as its height in meters :
first_hobbit.name = "Frodo"; first_hobbit.age = 28; first_hobbit.height = 1.15;

1/6
Call object's functions
If we need to check the name of the hobbit we just set, we can use the class function get_name(). To call a method of a
class we just need to use again a dot and its name:
first_hobbit.get_name();

SCOPE OPERATOR ::
Once the class is defined, everytime we need to make use of some of its attributes or functions, we can call them as we
did with namespaces, using the scope operator ::

void Hobbit::convert_height_to_cm() {
height = height * 100;
cout << “Height of hobbit is ” << height << “centimeters” << endl;
}

first_hobbit.convert_height_to_cm();

How to create a class constructor in C++


What would have happen in the previous example if we called the member function get_name() before having set the
value of name? An undetermined result.

In order to avoid that, a class can include a special function called its constructor, which is automatically called whenever
a new object of this class is created, allowing the class to initialize its attributes.

The constructor will have the exact same name as the class, and will be called below the public statement:

class Hobbit {
public:
Hobbit(); // Constructor declaration

Using constructor, we can pass parameters into it, as it is automatically called whenever a new object is created. We can
use it to directly set the values of the attributes.

class Hobbit {

public:

// Constructor declaration

Hobbit(string a, float b, int c) {


name = a;
height = b;
age = c;

//defining the attributes


string name;
float height;
int age;

// defining the methods

void get_name() {

cout << “hobbit name: ” << name << endl;

void converttocm();

Constructor works like passing parameters to a function!

int main() {
Hobbit first_hobbit("Frodo", 1.15, 28);

2/6
Hobbit second_hobbit("Sam", 1.26, 31);

We just created two objects of type Hobbit, with all their attributes set in just one line of code!! This is just powerful and
very clean!!!!!

Including C++ Classes in other scripts


how to import a class that is developed in a package called rosbot_control in a file called rosbot_class.h
#include “rosbot_control/rosbot_class.h”

ROSBOT CLASS
In this case we have separated the initialization of the class in another file, with all its attributes and methods. This file is
called a header file, with extension .h:
rosbot_class.h

Header file

#ifndef ROSBOT_CLASS_H
#define ROSBOT_CLASS_H
#include "geometry_msgs/Twist.h"
#include "nav_msgs/Odometry.h"
#include "sensor_msgs/LaserScan.h"
#include <list>
#include <ros/ros.h>
#include <string>

using namespace std;

class RosbotClass {
private:
// Communicate with nodes
ros::NodeHandle n;
// Laser data
ros::Subscriber laser_sub;
std::vector<float> laser_range;
std::string laser_topic;
// Velocity data
ros::Publisher vel_pub;
geometry_msgs::Twist vel_msg;
std::string vel_topic;
// Odometry data
ros::Subscriber odom_sub;
std::string odom_topic;
float x_pos;
float y_pos;
float z_pos;

void laser_callback(const sensor_msgs::LaserScan::ConstPtr &laser_msg);


void odom_callback(const nav_msgs::Odometry::ConstPtr &odom_msg);

public:
RosbotClass();
void move();
void move_forward(int n_secs);
void move_backwards(int n_secs);
void turn(string clock, int n_secs);
void stop_moving();
float get_position(int param);
std::list<float> get_position_full();
double get_time();
float get_laser(int index);
float *get_laser_full();
};

----- Rosbotclass.cpp

#include "rosbot_control/rosbot_class.h"
#include "geometry_msgs/Twist.h"

3/6
#include "nav_msgs/Odometry.h"
#include "sensor_msgs/LaserScan.h"
#include "std_msgs/Float32.h"
#include "std_msgs/Int16.h"
#include "unistd.h"
#include <ros/ros.h>

#include <list>
#include <string>

using namespace std;

// RosbotClass constructor
RosbotClass::RosbotClass() {
n = ros::NodeHandle("~");
laser_topic = "/scan";
laser_sub = n.subscribe(laser_topic, 10, &RosbotClass::laser_callback, this);
vel_topic = "/cmd_vel";
vel_pub = n.advertise<geometry_msgs::Twist>(n.resolveName(vel_topic), 1);
odom_topic = "/odom";
odom_sub = n.subscribe(odom_topic, 10, &RosbotClass::odom_callback, this);
ROS_INFO("Initializing node .................................");
usleep(2000000);
}

void RosbotClass::laser_callback(
const sensor_msgs::LaserScan::ConstPtr &laser_msg) {
laser_range = laser_msg->ranges;
// ROS_INFO("Laser value: %f", laser_range);
}
void RosbotClass::odom_callback(const nav_msgs::Odometry::ConstPtr &odom_msg) {
x_pos = odom_msg->pose.pose.position.x;
y_pos = odom_msg->pose.pose.position.y;
z_pos = odom_msg->pose.pose.position.z;
// ROS_INFO_STREAM("Odometry: x=" << x_pos << " y=" << y_pos << " z=" <<
// z_pos);
}
void RosbotClass::move() {
// Rate of publishing
ros::Rate rate(10);

ros::Time start_time = ros::Time::now();


ros::Duration timeout(2.0); // Timeout of 2 seconds
while (ros::Time::now() - start_time < timeout) {
ros::spinOnce();
vel_msg.linear.x = +0.5;
vel_msg.angular.z = 0.0;
vel_pub.publish(vel_msg);
rate.sleep();
}
vel_msg.linear.x = 0.0;
vel_msg.angular.z = 0.0;
vel_pub.publish(vel_msg);
}

void RosbotClass::move_forward(int time) {


// Rate of publishing
ros::Rate rate(10);

ros::Time start_time = ros::Time::now();


ros::Duration timeout(time);
while (ros::Time::now() - start_time < timeout) {
ROS_INFO_STREAM("Moving forward ........... ");
ros::spinOnce();
vel_msg.linear.x = 0.4;
vel_msg.angular.z = 0.0;
vel_pub.publish(vel_msg);
rate.sleep();
}
vel_msg.linear.x = 0.0;
vel_msg.angular.z = 0.0;
vel_pub.publish(vel_msg);
}

void RosbotClass::move_backwards(int time) {


// Rate of publishing

4/6
ros::Rate rate(10);

ros::Time start_time = ros::Time::now();


ros::Duration timeout(time);
while (ros::Time::now() - start_time < timeout) {
ROS_INFO_STREAM("Moving backwards ........... ");
ros::spinOnce();
vel_msg.linear.x = 0.5;
vel_msg.angular.z = 0.0;
vel_pub.publish(vel_msg);
rate.sleep();
}
vel_msg.linear.x = 0.0;
vel_msg.angular.z = 0.0;
vel_pub.publish(vel_msg);
}

void RosbotClass::turn(string clock, int n_secs) {


ros::Rate rate(10);
ros::Time start_time = ros::Time::now();
ros::Duration timeout(n_secs);

double WZ = 0.0;
if (clock == "clockwise") {
ROS_INFO_STREAM("Turning clockwise..............");
WZ = -2.5;
} else if (clock == "counterclockwise") {
ROS_INFO_STREAM("Turning counterclockwiseeee ........... ");
WZ = 2.5;
}

while (ros::Time::now() - start_time < timeout) {


ros::spinOnce();
vel_msg.linear.x = 0.5;
vel_msg.angular.z = WZ;
vel_pub.publish(vel_msg);
rate.sleep();
}
vel_msg.linear.x = 0.0;
vel_msg.angular.z = 0.0;
vel_pub.publish(vel_msg);
}

void RosbotClass::stop_moving() {
ROS_INFO_STREAM("Stopping the robot ........... ");
vel_msg.linear.x = 0.0;
vel_msg.angular.z = 0.0;
vel_pub.publish(vel_msg);
}

float RosbotClass::get_position(int param) {


if (param == 1) {
return this->x_pos;
} else if (param == 2) {
return this->y_pos;
} else if (param == 3) {
return this->z_pos;
}
return 0;
}

list<float> RosbotClass::get_position_full() {
list<float> coordinates({this->x_pos, this->y_pos, this->z_pos});
return coordinates;
}

double RosbotClass::get_time() {
double secs = ros::Time::now().toSec();
return secs;
}

float RosbotClass::get_laser(int index) { return laser_range[index]; }

float *RosbotClass::get_laser_full() {
float *laser_range_pointer = laser_range.data();
return laser_range_pointer;

5/6
}

int main(int argc, char **argv) {


ros::init(argc, argv, "rosbot_class_node");

RosbotClass rosbot;

rosbot.move();

float coordinate = rosbot.get_position(1);

ROS_INFO_STREAM(coordinate);

return 0;
}

6/6

You might also like