Digital-Humans-23 / a1

7 stars 0 forks source link

[Announcement] Frequently asked questions and answers #1

Open eastskykang opened 1 year ago

eastskykang commented 1 year ago

Table of contents

QnA

Q: Is it okay to hard code length of the links for the exercises? A: No. Your implementation should be general for ANY kinematic tree.


Q: The feet of the robot are under the ground when I play the app.

image

A: Once you complete the IK solver, the robot's base and feet will follow the position target.


Q: Do we need to use analytical Jacobian for IK solver? A: No. Let's stick to numerical Jacobian for IK solver.


Q: Can I increase the number of IK iteration? A: Yes. But if you use Gauss-Newton method, 10 will be enough.


Q: (Ex.5) Do I need to generate trajectory considering the terrain height? A: No. Adding offset (ground height) to IK target is just enough. Either way, if your robot walk on the terrain without any problem, we consider it as a successful implementation.


Q: Should I always use hint, or is it just okay to ignore it. A: Of course it's totally fine to ignore hints we provided. But please remember, if your implementation causes some side effects (e.g. some state changes of the robot that was not expected or not intended) although your implementation seemingly do the right thing, you may lose some points. So I strongly recommend you to stick to hints and our guides as much as possible.


Q: Often the knee of the robot snap to the other way as the following image

image

A: We don't take into account joint limit in our IK, so it's very normal. Specifically, if a leg is in near singularity condition (due to too high forward speed command etc.) this can happen. But, if this happens too often, you should do a double check if something wrong in your implementation.


Q: My code crashes. I want to know on which line the code crashes. A: If you build your code in Debug mode and run a debugger, the debugger will let you know on which line the code crashes.

grafik


Q: App is extremely slow... A: Make sure you build and run your code in Release mode.


Q: How does test-a1 work (exercise 4)? A: test-a1 compares the value of each entry of analytic Jacobian and numerical Jacobian (the one computed by the finite difference) for a given robot configuration. If the difference is less than a tolerance, the test code decides the test is passed. Here, we assume your numerical Jacobian (you implemented in Ex.2) is correct. If that's not the case, the test code may fail although your analytic Jacobian is correct. Please note, this is not comprehensive test cases. Passing test-a1 does not necessarily mean you get full point from this exercise.


Q: What is quaternion? and how do we use it? A: We will revisit more details of unit quaternion in the following lectures very soon.

TL;DR:

Please note you don't have to know the details of unit quaternion for this assignment. However, if you are not familiar with the notion of quaternion, you may want to learn the definition, and basics of unit quaternion, since this is a fundamental notion that you have to know if you want to study further (or research) computer graphics or robotics domain.

In short, the unit quaternion is one way of representing 3D rotational transformation (or 3D orientation of a coordinate system). Its real part is cos (0.5 * theta) and its imaginary part is sin(0.5 * theta) * v where (theta, v) is an angle of rotation and an axis of rotation (in a unit vector) respectively; for the axis vector [x, y, z], we define v := xi + yj + zk.

For instance, let's say you rotate some vector around x-axis by 1 rad. The corresponding quaternion is q = [cos(0.5), sin(0.5), 0, 0, 0] or more specifically, cos(0.5) + sin(0.5) i + 0 j + 0 k

Then you can use this quaternion q to rotate a 3D vector v around x-axis by 1 rad with some special mathematical operation (option 1 is to use matrix operation, option 2 is to use complex number multiplication. see one of the references below.)

If you want some materials to learn more about quaternion. I recommend these amazing videos from 3brown1blue:

Other references are here

For now, in our code base, you can just use quaternion as the same way you use a rotation matrix.

For instance, let's say Eigen quaternion qAB is equivalent to a rotational matrix R_{A}{B} wherev_A = R_{A}{B} v_B; v_A denotes a 3D vector v expressed in frame A, and v_B denotes v expressed in frame B .

Then, in cpp code, you can use quaternion as follows.

V3D v_A = qAB * v_B

Please note that this is not just a simple matrix-vector or vector-vector multiplication but rather a special operation for rotating a vector with a unit quaternion that is already implemented and overloaded by cpp * operator in Eigen library.

By the way, you can use getRotationQuaternion function as follows to convert heading angle into quaternion as I already left in the code.

Quaternion heading = getRotationQuaternion(headingAngle, V3D(0, 1, 0));

Q: What the hell are P3D and V3D? A: This is indeed very confusing if you are new to our code base.

In our code base, P3D and V3D both have 3 real numbers. However, they have different meanings.

V3D represents a 3D vector. A vector has direction and magnitude. The V3D always has the same magnitude regardless of the coordinate system that is expressed in.

Meantime, P3D represents a 3D point i.e. its three numbers are x, y, z coordinates of a specific point. Thus, it's magnitude changes as the coordinate system changes which of the point's coordinates is expressed in.

There's the following relationship between P3D and V3D.

// example 
P3D startingpoint(0.1, 0.2, 0.3);
V3D vector_from_startingpoint_to_endpoint(0.5, 0.6, 0.7)
P3D endpoint = startingpoint + vector_from_startingpoint_to_endpoint; // endpoint is now (0.6, 0.8, 1.0)
// example 
P3D startingpoint(0.1, 0.2, 0.3);
P3D endpoint(0.3, 0.2, 0.1);
V3D vector_from_startingpoint_to_endpoint(startingpoint, endpoint); // vector_from_startingpoint_to_endpoint is now (0.2, 0, -0.2)

In short, if you call the function getWorldCoordinates(P3D p), it will give you the coordinates expressed in world frame that is pos + orientation * V3D(pLocal) where pos is the world position of the origin of the body frame (in RB case, it's the global position of CoM) and orientation is the orientation of the frame. (see this)

For V3D, getWorldCoordinates(P3D p) just gives you orientation * vLocal (see this)

p.s. this is a bit confusing, but it is often useful to distinguish 3D coordinates with a 3D vector to prevent potential errors.

zcsun52 commented 1 year ago

Are we allowed to use getWorldCoordinates(V3D v) to get rotationAxis of a joint in world frame?