A short introduction to C++ for AI and Robotics:
🌸
🌸 🌸
🌸 c + +
🌸
🌸
🌸
🌸
🌸
NOTES : [ Functions , Standard Template Library (STL), Utilities & Libraries, OpenCV, Math Libraries ]
I am comfortable with c++ build systems and c++ was my first programming language that I used extensively throughout high school. I have an overview note on problem solving with c++:
C++ Iterators: | C++ Enumeration: |
---|---|
Iterators are objects that point to elements within a container. They provide a way to traverse through the elements of a container (like arrays, vectors, lists, etc.). Iterators can be incremented (to move to the next element) or decremented (to move to the previous element). #include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// Using an iterator to traverse the vector
std::vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
} |
Enumeration (enum) is a user-defined data type in C++ that consists of integral constants. Each enum variable is assigned an integer value by default. #include <iostream>
enum Color { RED, GREEN, BLUE };
int main() {
Color c = RED;
if (c == RED) {
std::cout << "The color is red." << std::endl;
}
return 0;
} |
C++ Bitset: | C++ Map: |
The bitset class in C++ is used to store a fixed-size sequence of bits. Each bit can be accessed individually, and bitwise operations can be performed. #include <iostream>
#include <bitset>
int main() {
std::bitset<8> bs1(std::string("1100"));
std::bitset<8> bs2(std::string("1010"));
// Bitwise AND
std::bitset<8> bs_and = bs1 & bs2;
std::cout << "AND: " << bs_and << std::endl;
// Bitwise OR
std::bitset<8> bs_or = bs1 | bs2;
std::cout << "OR: " << bs_or << std::endl;
// Bitwise XOR
std::bitset<8> bs_xor = bs1 ^ bs2;
std::cout << "XOR: " << bs_xor << std::endl;
return 0;
} |
A map is an associative container that stores key-value pairs. Each key is unique, and the values can be accessed using the keys.
#include <iostream>
#include <map>
int main() {
std::map<int, std::string> myMap;
// Inserting elements into the map
myMap[1] = "One";
myMap[2] = "Two";
myMap[3] = "Three";
// Accessing elements
std::cout << "Key 1: " << myMap[1] << std::endl;
// Iterating through the map
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
std::cout << it->first << ": " << it->second << std::endl;
}
return 0;
} |
C++ Multimap: | C++ Templates: |
A multimap is similar to a map, but it allows multiple elements to have the same key.
#include <iostream>
#include <map>
int main() {
std::multimap<int, std::string> myMultimap;
// Inserting elements into the multimap
myMultimap.insert({1, "One"});
myMultimap.insert({1, "Uno"});
myMultimap.insert({2, "Two"});
// Accessing elements
auto range = myMultimap.equal_range(1);
for (auto it = range.first; it != range.second; ++it) {
std::cout << it->first << ": " << it->second << std::endl;
}
return 0;
} |
Templates allow writing generic programs that can work with any data type. They are particularly useful for creating functions and classes that operate on different data types. #include <iostream>
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
std::cout << "Int: " << add<int>(2, 3) << std::endl;
std::cout << "Double: " << add<double>(2.5, 3.5) << std::endl;
return 0;
} |
C++ Files and Streams: | C++ Algorithms: |
C++ provides classes to perform file input and output. The `ifstream` class is used for reading from files, and the `ofstream` class is used for writing to files.
#include <iostream>
#include <fstream>
int main() {
std::ofstream outFile("example.txt");
outFile << "Hello, World!" << std::endl;
outFile.close();
std::ifstream inFile("example.txt");
std::string content;
std::getline(inFile, content);
std::cout << "File content: " << content << std::endl;
inFile.close();
return 0;
} |
The C++ Standard Library provides a collection of algorithms that can be used to perform various operations on containers. #include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector<int> vec = {1, 3, 2, 5, 4};
// Sorting the vector
std::sort(vec.begin(), vec.end());
// Displaying the sorted vector
for (int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
// Finding an element
auto it = std::find(vec.begin(), vec.end(), 3);
if (it != vec.end()) {
std::cout << "Element found: " << *it << std::endl;
} else {
std::cout << "Element not found" << std::endl;
}
return 0;
} |
C++ Namespaces: | C++ Math Functions: |
Namespaces are used to organize code into logical groups and to prevent name collisions. The #include <iostream>
namespace myNamespace {
void myFunction() {
std::cout << "Hello from myNamespace" << std::endl;
}
}
int main() {
myNamespace::myFunction();
return 0;
} |
The C++ Standard Library provides a set of functions to perform mathematical operations, such as #include <iostream>
#include <cmath>
int main() {
double x = 9.0;
std::cout << "Square root of " << x << " is " << sqrt(x) << std::endl;
std::cout << x << " raised to the power 3 is " << pow(x, 3) << std::endl;
std::cout << "Sine of 45 degrees is " << sin(45 * M_PI / 180) << std::endl;
return 0;
} |
resources : [ /cpp competitive ref | [cpp doc] CMake tutorial [How to Properly Setup C++ Projects] [Making and Working with Libraries in C++] [C++]
1 #include <iostream>
2
3 int main () {
4 // cpp 🌸
5 std :: cout << "Hello World!" << std :: endl;
6 return 0;
7 }
$ c++ file.cpp
> $ ./a.out
> $ ./a.out l> stdout.txt
. Use clang_format
to format your code
main()
is a function that returns an error code
- Error code 0 means OK
- Error code can be any number in [1, 255]
1 int main () {
2 return 0; // Program finished without errors.
3 }
1 int main () {
2 return 1; // Program finished with error code 1.
3 }
#include <file>
— system include files ; #include "file"
— local include files
- std::cin — maps to stdin ; std::cout — maps to stdout ; std::cerr — maps to stderr
- cpp keywords : list, cpp types list & cpp expressions : list. Avoid
==
for floating point types. - Use
&
to state that a variable is a reference:float& ref = original_variable;
std::string& hello_ref = hello;
Whatever happens to a reference happens to the variable and vice versa. Yields performance gain as references avoid copying data.
const , auto , friend , false , ... ///< C++ Keywords
// comment type 1
/* comment type 2 */
/* comment type 3
BLOCK COMMENT
*/
"Hello C++ \n"; ///< "\n" is an escape character
3.5f; // value entity
std :: string str1; // object entity
namespace std; // namespace entity
void MyFunc (); // function entity
const int& a = b; // reference entity
enum MyEnum {}; // enum enityty
#define UGLY_MACRO (X) // NOT a C++ entity
float a; // float is the fundamental type of a
bool b; // bool is fundamental
MyType c; // MyType is user defined , incomplete
MyType c{}; // MyType is user defined , complete
std :: vector; // Also , user -defind type
std :: string; // Also , user -defind type
Compilation is translation from text to machine code. Two compilers : { Clang, gcc }
$ c++ -std=c++11 -o hello_world hello_world .cpp
$ ./ hello_world
- Preprocess :
$ clang++ -E main.cpp > main.i
- Compilation :
$ clang++ -S main.i
- Assembly :
$ clang++ -c main.s
- Linking :
$ clang++ main.o -o main
Compilation flags : -std=c++17,
, -Wall
, -Wextra
, -Werror
| Optimization options:
-O0
— no optimizations [default]
-O3
or -Ofast
— full optimizations. Keep debugging symbols: -g
.
Tools: GNU/Linux { filesystem, terminal, standard input/output } ; Text Editor { configuring, terminal, compile, debug } ; Build Systems { headers/sources, libraries, compilation flags, cmake, 3rd paty libraries } ; Git ; gdb ; Web-based tools { Quick Bench, Compiler Explorer, cpp insights, cppreference.com } ; Clang-tools {Clang-format, Clang-tidy, Clangd, Cppcheck} ; Google test, OpenCV. Install llvm-toolchain from here.
Install - git : $ sudo apt install git
, build tools : $ sudo apt install build-essential
, cmake : $ sudo apt install cmake
, cppcheck : $ sudo apt install cppcheck
, clang-tools $ sudo apt install clang-format clang-tidy clangd
.
$ sudo apt update
$ sudo apt install git build-essential cmake cppcheck clang-format clang-tidy clangd
In VS Code for c++ extensions : CTRL + P , then execute ext install ms-vscode.cpptools
and ext install llvm-vs-code-extensions.vscode-clangd
; for CMake extensions : ext install twxs.cmake
, ext install ms-vscode.cmake-tools
and ext install cheshirekow.cmake-format
; for markdown extensions ext install yzhang.markdown-all-in-one
and ext install DavidAnson.vscode-markdownlint
.
MY CODE:
Python | C++ 17 |
---|---|
my_dict = {'a': 27, 'b': 3}
for key , value in my_dict.items ():
print(key , "has value", value) |
std ::map <char , int> my_dict {{'a', 27}, {'b', 3}};
for (const auto& [key , value] : my_dict) {
cout << key << " has value " << value << endl;
} |
Core c++ : control structures (if, for , while) , switch, I/O streams, stringstream, Functions, c++ strings, Pass by value / Pass by reference, Namespaces, Containers, std::tuple, Iterators, try/ catch, enum classes, STL library, STL algorithms, Function Overloading, Operator Overloading, String streams, filesystem
Program input parameters : int main(int argc, char const *argv[]);
, where argc
defines number of input parameters and argv
is an array of string parameters. By default: argc == 1
& argv == "<binary_path>"
.
Modern c++ : Classes, Const Correctness, typedef / using, static variables / methods, Move semantics, Special functions, Singleton pattern, Inheritence, Function Overriding, Abstract classes, Interfaces, Strategy Pattern, Polymorphism, Typecasting, Memory Management, Stack vs Heap, Pointers, new / delete, this pointer, Memory issues, RAII, Smart pointers, Generic programming, Template functions, Template classes, Static code generation, lambdas.
Library: multiple object files that are logically connected. Types of libraries:
- Static: faster, take a lot of space, become part
of the end binary, named:
lib*.a
- Dynamic: slower, can be copied, referenced by a
program, named
lib*.so
.
Create a static library with
$ ar rcs libname.a module.o module.o …
. Static libraries are just archives just like zip/tar/…
.
Header / Source Separation :
Move all declarations to header files (*.hpp
) and Implementation goes to *.cpp
or *.cc
.
1 // some_file.hpp
2 Type SomeFunc (... args ...);
3
4 // some_file.cpp
5 #include "some_file.hpp"
6 Type SomeFunc (... args ...) {} // implementation
7
8 // program.cpp
9 #include "some_file.hpp"
10 int main () {
11 SomeFunc(/* args */);
12 return 0;
13 }
To use a library we need:
-
A header file
library_api.h
-
The compiled library object
libmylibrary.a
folder/ --- tools.hpp --- tools.cpp --- main.cpp
tools.hpp | tools.cpp | main.cpp |
---|---|---|
#pragma once // Ensure file is included only once
void MakeItSunny ();
void MakeItRain ();
|
#include "tools.hpp"
#include <iostream >
void MakeItRain () {
// important weather manipulation code
std :: cout << "Here! Now it rains! Happy?\n";
}
void MakeItSunny () { std :: cerr << "Not available\n"; } |
#include "tools.hpp"
int main () {
MakeItRain ();
MakeItSunny ();
return 0;
} |
Compile modules: $ c++ -std=c++17 -c tools.cpp -o tools.o
Organize modules into libraries: $ ar rcs libtools.a tools.o
Link libraries when building code: $ c++ -std=c++17 main.cpp -L . -ltools -o main
Run the code: $ ./main
Build process : $ cd <project_folder>
> $ . mkdir build
> $ cd build
> $ cmake ..
> $ make
.
The build process is completely defined in CMakeLists.txt
and childrens src/CMakeLists.txt
, etc.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.1) # Mandatory.
project( first_project ) # Mandatory.
set( CMAKE_CXX_STANDARD 17) # Use c++17.
# tell cmake where to look for *.hpp, *.h files
include_directories(include /)
# create library "libtools"
add_library(tools src/tools.cpp) # creates libtools.a
# add executable main
add_executable(main src/tools_main.cpp) # main.o
# tell the linker to bind these objects together
target_link_libraries(main tools) # ./main
Automatically detects changes and after doing changes: $ . cd <project_folder>/build
and $ make
.
project structure: | CMake compilation options |
---|---|
|-- project_name /
| |-- CMakeLists .txt
| |-- build/ # All generated build files
| |-- results/ # Executable artifacts
| | |-- bin/
| | |-- tools_demo
| | |-- lib/
| | |-- libtools.a
| |-- include/ # API of the project
| | |-- project_name
| | |-- library_api .hpp
| |-- src/
| | |-- CMakeLists .txt
| | |-- project_name
| | |-- CMakeLists .txt
| | |-- tools.hpp
| | |-- tools.cpp
| | |-- tools_demo .cpp
| |-- tests/ # Tests for your code
| | |-- test_tools .cpp
| | |-- CMakeLists .txt
| |-- README.md # How to use your code
|
set( CMAKE_CXX_STANDARD 17)
# Set build type if not set.
if(NOT CMAKE_BUILD_TYPE )
set( CMAKE_BUILD_TYPE Debug)
endif ()
# Set additional flags.
set( CMAKE_CXX_FLAGS "-Wall -Wextra ")
set( CMAKE_CXX_FLAGS_DEBUG "-g -O0")
Useful commands in CMake: Set variables with In |
Use pre-compiled library: find_package
calls multiple find_path
and find_library
functions. To use find_package(<pkg>)
CMake must
have a file Find<pkg>.cmake
in CMAKE_MODULE_PATH
folders. Find<pkg>.cmake
defines which libraries and headers belong to package <pkg>
.
CMakeLists.txt | cmake_modules/Findsome_pkg.cmake |
---|---|
cmake_minimum_required(VERSION 3.1)
project( first_project )
# CMake will search here for Find <pkg >.cmake files
SET( CMAKE_MODULE_PATH
${PROJECT_SOURCE_DIR}/ cmake_modules )
# Search for Findsome_pkg.cmake file and load it
find_package(some_pkg )
# Add the include folders from some_pkg
include_directories(${some_pkg_INCLUDE_DIRS})
# Add the executable "main"
add_executable(main small_main .cpp)
# Tell the linker to bind these binary objects
target_link_libraries(main ${some_pkg_LIBRARIES})
|
# Find the headers that we will need
find_path( some_pkg_INCLUDE_DIRS include/some_lib.hpp < FOLDER_WHERE_TO_SEARCH >)
message(STATUS "headers: ${some_pkg_INCLUDE_DIRS}")
# Find the corresponding libraries
find_library( some_pkg_LIBRARIES
NAMES some_lib_name
PATHS <FOLDER_WHERE_TO_SEARCH >)
message(STATUS "libs: ${some_pkg_LIBRARIES}") |
resources: mathematical optimizations with google or-tool, SNOPT, IPOPT, Conic Bundle, Computer Vision and OpenCV in c++, Computer Vision Projects - C++, Modern c++, google code styling guide - c++, The C++ Programming Language (4th Edition), cppreference, " Give me 15 minutes & I'll change your view of GDB", cpp tutorial, cpp core guidelines, Learn Robotics with C++ in 1 Hour , Advice for getting a PhD in robotics | Boris Sofman and Lex Fridman, Programming a Wireless Robotic Arm, Practical Polymorphism C++, Path Planning #2 Wave Propagation, Potential Fields & Modern(ish) C++.