Introduction
What is the Megabot?
The Megabot is a large quadrupedal robot capable of carrying a passenger, primarily designed to be showcased at robotics-related events. It weighs approximately 250 kg, measures around 2.50 m in width, and operates via electric actuators. Its design and construction were carried out by Julien Allali , a lecturer at ENSEIRB-MATMECA, and it is currently housed at the Fablab of Bordeaux INP.

Mission
The primary goal of this project is to refine the robot’s control by improving its kinematic model, meaning revising all algorithms that translate a position command into an actuator elongation command. After that, the aim is to implement a walking algorithm so that the robot can follow a curved trajectory. Finally, to validate the implemented algorithms independently of real-world constraints such as structural deformation due to weight, the Megabot must be modeled and integrated into the PyBullet simulator.
Control
The goal of control is to establish the inverse kinematics of the Megabot, meaning implementing a set of methods to determine the elongations of the 12 actuators needed to achieve a given position. In general, inverse kinematics can be computed using dedicated libraries by providing them with a URDF model of the robot (for example, Pinocchio in Python). However, this approach could not be implemented for the Megabot for two reasons:
-
The URDF format constructs a tree where the nodes represent the robot’s parts and the edges represent the joints between them (slider, pivot, etc.). Since the Megabot’s structure includes geometric loops, this would introduce cycles in the tree, which is not allowed.
-
If we were to model the Megabot as a tree by removing its geometric loops and simulating a robot actuated by motors at its joints, we would then be minimizing the error in our inverse kinematics based on joint angles rather than actuator elongations.
We have therefore decided to clearly redefine the Megabot’s kinematics.
Megabot Kinematics
Establishing the forward kinematic model of a robot means developing a set of computational methods to determine the robot’s position based on given joint values. In our case, this involves creating one or more functions that take valid actuator elongations as input and return the Megabot’s position. This problem can be solved analytically quite easily.
Establishing the inverse kinematic model, however, is the reverse process: we want to determine joint values from a given position. This is significantly more complex than forward kinematics and often cannot be solved analytically, including in the case of the Megabot.
A common approach to solving this problem is to use the Jacobian matrix associated with the forward kinematic model. This matrix consists of the partial derivatives of the forward kinematics and allows for a linear approximation of the relationship between joint values and position values for small variations. Once this Jacobian \(J\) is determined, the inverse kinematics problem can be solved by formulating a quadratic optimization problem:
In this problem, \(\Delta V\) is the vector of actuator elongation variations to be determined, \(J\) is the Jacobian of the forward kinematics, and \(\Delta X\) is the vector of position variations. The goal is to minimize the quadratic error on \(\Delta X\) while constraining \(\Delta V\) with variables \(G\), \(h\), \(A\), \(b\), \(lb\), and \(ub\). These constraint variables are useful for ensuring actuator elongations remain within their physical limits.
Demonstration Details
Demonstration Details
We aim to minimize the quadratic position error. To do this, we consider the actuator elongations and positions known at instant \(k\) and seek to minimize the error at instant \(k+1\). Let’s define:
The quadratic position error is then:
Minimizing the quadratic error thus comes down to minimizing the following expression:
This approach to solving inverse kinematics is an example of applying the least squares method. Solving this quadratic problem can be done using a QP solver such as \(\verb|qpsolvers|\) in Python.
Calculation of the Jacobian for Direct Kinematics
We will now develop the Jacobian matrix associated with the direct kinematics of the Megabot. We will first construct it relative to a single leg in its plane before generalizing it to all legs in the world reference frame.
Direct Kinematics in the Leg Plane
To determine the Jacobian associated with our direct kinematics in the leg plane, it is necessary to formalize our problem. We will successively compute the position deviations of points \(D\), \(E\), \(F\), \(G\), \(H\), \(I\) and \(J\), represented in the following diagram, as a function of the elongation variations \(\Delta v_1\) and \(\Delta v_2\) of the actuators.

These calculations result in obtaining the matrix \(M_J\) such that:
We then notice that this matrix is the Jacobian \(J_2\) associated with our direct kinematic model in the leg plane:
Details of the Deviation Calculations
Details of the Deviation Calculations
For 2 points \(A\) and \(B\) separated by a constant distance, we denote their separation as \(d_{AB}\). The dependency graph of the leg’s joints is as follows:

First, we seek to determine the deviation at \(D\). For this, we consider the triangle \(ADC\), where the elongation \(v_1\) of segment \(CD\) and the position of point \(D\) are variable. We obtain the following system \(S_{1}\):
After differentiation with respect to \(x_{D}\), \(y_{D}\) and \(v_1\), and assuming that \(A\), \(D\) and \(C\) are not collinear (which is always verified due to the leg structure), system \(S_{1}\) gives us the following matrix relation:
Since the points \(A\), \(D\) and \(E\) are collinear, the position deviation at \(E\) can be determined from the deviation at \(D\) by applying a simple proportionality factor.
We now calculate the displacement at \(F\) by considering the triangle \(EBF\), where the positions of points \(E\) and \(F\) are variable. We obtain the following system \(S_2\):
We differentiate it with respect to \(x_{F}\), \(y_{F}\), \(x_{E}\) and \(y_{E}\), and under the condition that \(B\), \(E\) and \(F\) are not collinear (which is always verified due to the leg’s structure), we obtain:
The points \(E\), \(F\) and \(G\) on one hand, and \(B\), \(F\) and \(H\) on the other hand, are collinear. Therefore, the position changes in \(G\) and \(H\) can be derived from the change in \(F\) :
We can now calculate the deviation at \(I\) by considering the triangle \(GHI\), where the positions of points \(G\) and \(H\), as well aw the elongation \(v_2\) of the segment \(HI\), are variable. We obtain the following system \(S_3\):
We differentiate it with respect to \(x_{I}\), \(y_{I}\), \(x_{G}\), \(y_{G}\), \(x_{H}\), \(y_{H}\) and \(v_{2}\) to obtain the following Jacobian:
We then have the following relation that links the displacement at \(I\) to \(\Delta v_1\) and \(\Delta v_2\), under the condition that \(I\), \(G\) and \(H\) are not aligned (which is always verified due to the structure of the leg):
Finally, because \(G\), \(I\) and \(J\) are aligned, we obtain the displacement at \(J\):
Direct Kinematics in the Leg’s Space
The goal now is to bring our model into space by adding the influence of the actuator \(v_3\) to our direct kinematics. The target reference frame is the frame \((\overrightarrow{x}, \overrightarrow{y}, \overrightarrow{z})\), represented in the following figure. It is worth noting that the vector \(\overrightarrow{Y}\), used in the previous part, has become the vector \(\overrightarrow{Z}\) in this modeling for the sake of convention.

Let \((X, Z)\) be the coordinates of the foot’s tip \(J\) in its plane. First, we need to express the angle \(\alpha\) of the leg relative to the chassis as a function of the elongation of the actuator \(v_3\). This will allow us to derive expressions for the variations of \(X\), \(Z\) and \(\alpha\) as functions of the variations \(v_1\), \(v_2\) and \(v_3\).
Once this relationship is explicit, we need to translate the rotation by an angle \(\alpha\) around the axis \(\overrightarrow Z\) into a matrix form in order to transform into the reference frame \((\overrightarrow x, \overrightarrow y, \overrightarrow z)\). We then obtain the following relationship:
From the matrices \(A\) and \(B\), it becomes possible to construct \(J_3\), the matrix that relates \((\Delta x, \Delta y, \Delta z)\) to \((\Delta v_1, \Delta v_2, \Delta v_3)\):
Details of the coordinate frame change
Details of the coordinate frame change
First, we aim to express the angle \(\alpha\) First, we aim to express the angle \(v_3\). To do this, we place ourselves in the triangle \(KLO\).

Using the law of cosines, we obtain the following relation:
We then build the associated Jacobian, which allows us to obtain the following matrix relation:
Since \(\Delta \alpha\) is equal to \(\Delta \gamma\), we finally obtain the following relation:
The derivation of the relation between \(\Delta \alpha\) and \(\Delta v_3\) allows us to obtain the matrix linking \(( \Delta X, \Delta Z, \Delta\alpha )\) to \((\Delta v_1, \Delta v_2, \Delta v_3)\). To do this, we reuse \(J_2\) obtained during the direct kinematics resolution in the plane of the leg:
The second step to obtain our Jacobian in the \((\overrightarrow{x}, \overrightarrow{y}, \overrightarrow{z})\) reference frame is to obtain the matrix relating \((\Delta x, \Delta y, \Delta z)\) to \((\Delta X, \Delta Z, \Delta \alpha)\). For this, we need to study the rotation by angle \(\alpha\) separating \((\overrightarrow{X}, \overrightarrow{Y}, \overrightarrow{Z})\) and \((\overrightarrow{x}, \overrightarrow{y}, \overrightarrow{z})\).

We first note that the inequality \(0<\alpha<\dfrac{\pi}{2}\) is always verified due to the structure of the chassis. Therefore, we allow the expression of the rotation by an angle of \(\dfrac{\pi}{2} - \alpha\) without questioning the sign of the rotation angle.
By differentiating this relation with respect to \(\alpha\), we obtain the following relation:
We know that \(Y\) and \(\Delta Y\) are constant in our model and are equal to \(Y = 0\) and \(\Delta Y = 0\). As a result, we can simplify the previous relationship as follows:
Or, alternatively, formulated as:
Generalization
We have expressed \(J_3\), the Jacobian associated with the direct kinematic model of a Megabot leg in its reference frame. In order to apply simultaneous control on all the legs, it is necessary to generalize our kinematic model to the entire robot.

From now on, we will denote \(\Delta V\) as the variations in elongation of the 12 actuators, and \(\Delta X\) as the variations in position of the foot ends in the robot’s reference frame \((\overrightarrow{x}, \overrightarrow{y}, \overrightarrow{z})\). The new transformation matrix between these vectors will be called \(J_{12}\):
We can then observe that using rotation matrices, it is easy to express \(J_{12}\) from \(J_3\) which was computed in the previous section:
The Jacobians \(J_2\), \(J_3\) and \(J_{12}\) computed allow us to develop control algorithms for a single leg in its plane, a leg in its reference frame, and all the legs in the Megabot’s reference frame using a QP solver. Nevertheless, the important issue of managing the center of gravity can also be addressed during the control phase, which is why we will incorporate it into our equations.
Center of Gravity Management
Indeed, an important issue that we aim to solve is maintaining the projection of the robot’s center of gravity inside its support polygon, which is the convex polygon formed by the contact points between the ground and the robot. If the center of gravity of the Megabot were to move outside this area, it would tip over, which would modify its legs on the ground and distort any movement planning.
We have implemented two main control modes, each with its advantages and disadvantages. The first simply constrains the center of gravity to remain above the support polygon by adding constraints in the QP solver. The second allows us to input not only a trajectory for the robot’s legs but also for its center of gravity.
In both cases, it is necessary to develop the Jacobian associated with the displacement of the Megabot’s center of gravity. By knowing the weight of each part of the Megabot, it is possible to determine the variations \(\Delta C\) of the center of gravity from \(\Delta V\) and the Jacobians of the direct kinematic model. In fact, the position of the center of gravity is just a linear combination of the positions of each of the robot’s joints. We thus obtain a relationship of the type:
Center of Gravity Constraint
Once the Jacobian \(J_C\) has been ewpressed, it becomes possible to use the variables \(G\) and \(h\) of the QP solver to constrain the center of gravity. By setting \(G = J_C\) and choosing \(h\) according to the constraints to be applied to the center of gravity, the solver will then ensure that:
Note that here each row of \(G\) and \(h\) corresponds to a constraint on a coordinate of the center of gravity. In practice, we want to constrain the projection of the center of gravity within the support polygon, so \(G\) must be constructed such that each of its rows is a linear combination of the rows of \(J_{C}\), while \(h\) would contain the corresponding constraint values. If we need \(n\) constraints on the coordinates of the center of gravity to keep it within the support polygon, \(G\) and \(h\) would then consists of \(n\) rows.
This solution provides a form of safety while giving the center of gravity some freedom. It seems suitable for a robot with a constant support area during its movement because, in this case, it allows us to constrain the center of gravity to this area and no longer worry about it during the planning phase.
Unfortunately, this is not the case for the Megabot, which is why we opted for the second solution that offers exact control of the center of gravity but, in return, requires its inclusion in the planning phase.
Center of Gravity Control
To control the position of the center of gravity, we need to integrate it into the inputs of the QP solver. We then obtain the following relationship using the previous notations:
The newly constructed Jacobian \(J_{15:12}\) allows us to account for the position of the center of gravity in our forward kinematics. However, the matrix \(J_{15:12}\) cannot be directly used by the QP solver because the matrix \(J_{15:12}\hspace{0.15cm}^TJ_{15:12}\) is singular (see the proof provided at the beginning of the section). One solution to circumvent the singularity of this matrix is to add a regularization term to our minimization.
Details of the addition of a regularization term
Details of the addition of a regularization term
We aim to add a Tikhonov regularization with coefficient \(r\) to our quadratic optimization. Using the notations from the proof at the beginning of the section, our new minimization becomes:
We denote:
The objective to minimize then becomes:
Thus, we transform the singular matrix \(J_{15:12}\hspace{0.15cm}^TJ_{15:12}\) from our previous quadratic optimization into the matrix \(J_{15:12}\hspace{0.15cm}^TJ_{15:12} + r Id_{12}\). This ensures its non-singularity because there is no longer any dependence between the rows of the matrix. This regularization also homogenizes the actuator variations, with the homogenization becoming stronger as the chosen value for \(r\) increases.
Planning
The planning phase involves developing the movement independently of the control-related considerations. It is about knowing what the robot will do and not how it will do it, and this is translated into the implementation of algorithms providing successive positions for the robot’s legs and center of gravity.
Trajectory Development
Our goal was to allow the Megabot to move in a curve. Therefore, we first sought to translate a directional input (2 dimensions) and a rotational input (1 dimension) into a trajectory for the Megabot. This modeling aims to control the robot using a controller with two joysticks.
The direction defines the vector \(\overrightarrow{d}\) represented in the following diagram, while the rotation value defines the position of the center of rotation \(R\) along the axis perpendicular to the direction: the closer the value is to 0, the less pronounced the curve is, and the farther \(R\) is, with positive rotation placing \(R\) to the right and negative rotation placing it to the left. The trajectories of the 4 legs are then determined by tracing the circles centered at \(R\) passing through their ends.

In the case of a zero direction and rotation, \(R\) is placed at the center of the Megabot. In the case of zero rotation and a direction, the trajectories of the legs are simply straight lines parallel to the direction axis.
Once the trajectories of the 4 legs were determined, we considered the management of the robot’s center of gravity. The chosen solution to ensure that the center of gravity remains constantly above the support triangle was to have it follow a circular trajectory around the intersection of the diagonals of the polygon formed by the ends of the 4 legs \(P_0\), \(P_1\), \(P_2\) and \(P_3\) during their movement. We will refer to this point as \(C\) in the subsequent explanations. This choice led us to break down the walking motion into 4 phases, preceded by an initialization phase:

Walking Algorithm
Once the trajectories of the 4 leg ends and the center of gravity were established, we discretized the paths of the legs and the center of gravity for each of the phases outlined in the previous figure. The point \(C\) is updated at each step of this discretization, ensuring that the center of gravity remains above the support polygon.
During the initialization phase, the 4 legs are fixed on the ground, and the center of gravity is moved to the rear of the Megabot. Then, during each of the following phases, one leg is lifted, moved along its trajectory, and then lowered while the center of gravity completes a quarter turn around \(C\). This strategy involves moving the legs one by one in a counterclockwise direction. The control algorithm implemented in the Control section translates this command into actuator elongations to perform the walking motion.
Simulation
In order to verify our walking algorithm, it is necessary to perform a simulation of the Megabot. Indeed, although we carried out unit and integration tests of our functions during development, testing the walking directly on the real Megabot would be premature, as if we observed discrepancies between the result and the expected behavior, there would be no guarantee that the error would originate from our algorithmic part and not from our electronics or mechanics.
To simulate the physics during the Megabot’s walking tests, we chose to use PyBullet. This choice required the creation of an URDF file containing a model of the Megabot.
The URDF format represents robots as a tree of parts connected by joints (pivot, slider, etc.). This common modeling approach is suitable for robots with actuated joints, but it prevents the formation of cycles and thus any geometric closure within the robot’s structure. Since all of the Megabot’s movements rely on kinematic loops at the actuator level, it was necessary to find a way to bypass this issue. The solution was to create an incomplete kinematic model and add constraints to close the loops in PyBullet afterwards.
The first step was modeling the Megabot in OnShape, including as many details as possible and specifying the weight and inertial matrices for each part. All the connections between parts were created in an assembly, except for those leading to geometric closures, and the OnShape model was then converted to URDF using the \(\verb|onshape-to-robot|\) tool.

Once the URDF was generated, the geometric closure constraints were built using PyBullet, and the walking simulation was performed.