# turtlelib **Repository Path**: slamcn/turtlelib ## Basic Information - **Project Name**: turtlelib - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-01-22 - **Last Updated**: 2022-01-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Author: zhengqing zhang # Turtlelib Library A library for handling transformations in SE(2) and other turtlebot-related math. # Components - rigid2d - Handles 2D rigid body transformations - frame_main - Perform some rigid body computations based on user input # Conceptual Questions ## 1. We need to be able to ~normalize~ Vector2D objects (i.e., find the unit vector in the direction of a given Vector2D): - Propose three different designs for implementing the ~normalize~ functionality - Discuss the pros and cons of each proposed method, in light of the C++ Core Guidelines. - Which of the methods would you implement and why? answer: 1 ) just an function ``` Vector2D normalize(const Vector2D& a) { Vector2D noraml; if (a.x == 0 && a.y == 0) { noraml.x = 0; noraml.y = 0; } else { noraml.x = a.x / std::sqrt(std::pow(a.x, 2) + std::pow(a.y, 2)); noraml.y = a.y / std::sqrt(std::pow(a.x, 2) + std::pow(a.y, 2)); } return noraml; } ``` 2 ) member function ``` Vector2D Vector2D::normalize() { Vector2D noraml; if (x == 0 && y == 0) { noraml.x = 0; noraml.y = 0; } else { noraml.x = x / std::sqrt(std::pow(x, 2) + std::pow(y, 2)); noraml.y = y / std::sqrt(std::pow(x, 2) + std::pow(y, 2)); } return noraml; } ``` 3) member function ``` void Vector2D::normalize(Vector2D& noraml) { if (a.x == 0 && a.y == 0) { noraml.x = 0; noraml.y = 0; } else { noraml.x = a.x / std::sqrt(std::pow(a.x, 2) + std::pow(a.y, 2)); noraml.y = a.y / std::sqrt(std::pow(a.x, 2) + std::pow(a.y, 2)); } return ; } ``` a. A non-member function always appears outside of a class. b. The member function can appear outside of the class body (for instance, in the implementation file). But, when you do this, the member function must be qualified by the name of its class. This is to identify that that function is a member of a particular class. c. By contrast, a non-member function has no need to be qualified. It does not belong to a class. I will useing method 2), because it is more decoupling and convenient ## 2. What is the difference between a class and a struct in C++? answer: 1 ) The only difference between a struct and class in C++ is the default accessibility of member variables and methods. In a struct they are public; in a class they are private. 2 ) A class can also contain functions [called methods]. 3 ) The member variables and methods are hidden from the outside world, unless their declaration follows a public label. 4 ) There can be a pair of special methods – the constructor and destructor – that are run automatically when an instance of the class [an object] is created and destroyed. 5 ) Operators to work on the new data type can be defined using special methods [member functions]. 6 ) One class can be used as the basis for the definition of another [inheritance]. 7 ) Declaring a variable of the new type [an instance of the class; an object] requires just the name of the class – the keyword class is not required. ## 3. Why is Vector2D a struct and Transform2DClass (refer to at least 2 specific C++ core guidelines in your answer)? answer: 1 ) Organize related data into structures (structs or classes) 2 ) Use class if the class has an invariant; use struct if the data members can vary independently 3 ) Represent the distinction between an interface and an implementation using a class 4 ) Make a function a member only if it needs direct access to the representation of a class 5 ) Use class rather than struct if any member is non-public ## 4. Why are some of the constructors in Transform2D explicit (refer to a specific C++ core guideline in your answer)? answer: A destructor is implicitly invoked at the end of an object’s lifetime. If the default destructor is sufficient, use it. Only define a non-default destructor if a class needs to execute code that is not already part of its members’ destructors. ## 5. Why is Transform2D::inv() declared const while Transform2D::operator*=() is not? - Refer to [[https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#con-constants-and-immutability][C++ Core Guidelines (Constants and Immutability)]] in your answer answer: 1 ) Transform2D::inv() does not change the member variable 2 ) Transform2D::operator*=() will change the member variable # Sample Run of frame_main ``` zhengqingzhang@zhengqingzhang:~/zhengqingzhang/turtlelib/build$ ./frame_main Enter transform T_{a,b}: deg: 90 x: 0 y: 1 Enter transform T_{b,c}: deg: 90 x: 1 y: 0 T_{a,b}:deg: 90 x: 0 y: 1 T_{b,a}:deg: -90 x: -1 y: -6.12323e-17 T_{b,c}: deg: 90 x: 1 y: 0 T_{c,b}:deg: -90 x: -6.12323e-17 y: 1 T_{a,c}:deg: 180 x: 6.12323e-17 y: 2 T_{c,a}:deg: -180 x: -1.83697e-16 y: 2 Enter Vector v_b: 1 1 v_bhat: [0.707107 0.707107] v_a: [-1 2] v_b: [1 1] v_c: [1 6.12323e-17] Enter twist V_b: 1 1 1 V_a [1 0 1] V_b [1 1 1] V_c [1 2 -1] ```