Skip to content

Commit 5ddef7d

Browse files
author
chenchangshuo
committed
Add gamepad control, lie down state, and RBS buffer I/O
1 parent 0cb61ab commit 5ddef7d

22 files changed

Lines changed: 1049 additions & 96 deletions

Contributors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ This is the official list of Deep Robotics SDK Project developers and contributo
1111

1212
* [Bo Peng](https://www.linkedin.com/in/bo-peng-647068272/)
1313
* [Haokai Dai](https://github.com/HaoKa1)
14-
* Changshuo Chen
14+
* [Changshuo Chen](https://github.com/CcShuo)
1515
* Zhichao Feng

src/M20_sdk_deploy/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ include_directories(
3434
include/utils
3535
interface/robot
3636
interface/user_command
37+
interface/network
3738
state_machine
3839
run_policy
3940
${THIRD_PARTY}/eigen/

src/M20_sdk_deploy/README.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ python3 src/M20_sdk_deploy/interface/robot/simulation/mujoco_simulation_ros2.py
107107
108108

109109
# Sim-to-Real
110-
This process is almost identical to simulation-simulation. You only need to add the step of connecting to Wi-Fi to transfer data, and then modify the compilation instructions. The default control mode is currently set to keyboard mode. We will be adding controller support in future updates. Stay tuned.
110+
This process is almost identical to simulation-simulation. You only need to add the step of connecting to Wi-Fi to transfer data, and then modify the compilation instructions.Real-robot control is divided into keyboard mode and gamepad control mode. You need to modify the RemoteCommandType parameter in the main function to select the desired mode.
111111

112112

113113
Please first use the OTA upgrade function in the handle settings to upgrade the hardware to version 1.1.7.
@@ -139,11 +139,22 @@ ros2 run m20_sdk_deploy rl_deploy
139139

140140
# exit sdk mode:
141141
ros2 service call /SDK_MODE drdds/srv/StdSrvInt32 command:\ 0
142+
```
142143

143-
# keyboard control
144-
Note: When the robot dog stands up, it may become stuck due to self-collision in the simulation. This is not a bug; please try again.
144+
### ⌨️ Keyboard Control
145+
*(Note: When the robot dog stands up, it may become stuck due to self-collision in the simulation. This is not a bug; please try again.)*
145146
- z: default position
146147
- c: rl control default position
148+
- x: lie down
147149
- wasd:forward/leftward/backward/rightward
148150
- qe:clockwise/counter clockwise
149-
```
151+
152+
### 🎮 Gamepad Control
153+
*(Note: When using the gamepad control function, please ensure that the Gamepad APP version is V1.5.11 or higher.)*
154+
- L1: default position
155+
- L2: rl control default position
156+
- R1: lie down
157+
- R2: joint damping
158+
- Left joystick:forward/leftward/backward/rightward
159+
- Right joystick:clockwise/counter clockwise
160+

src/M20_sdk_deploy/include/types/common_types.h

Lines changed: 77 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -29,58 +29,89 @@
2929

3030

3131
namespace types {
32-
using Vec3f = Eigen::Vector3f;
33-
using Vec3d = Eigen::Vector3d;
34-
using Vec4f = Eigen::Vector4f;
35-
using Vec4d = Eigen::Vector4d;
36-
using VecXf = Eigen::VectorXf;
37-
using VecXd = Eigen::VectorXd;
32+
using Vec3f = Eigen::Vector3f;
33+
using Vec3d = Eigen::Vector3d;
34+
using Vec4f = Eigen::Vector4f;
35+
using Vec4d = Eigen::Vector4d;
36+
using VecXf = Eigen::VectorXf;
37+
using VecXd = Eigen::VectorXd;
3838

39-
using Mat3f = Eigen::Matrix3f;
40-
using Mat3d = Eigen::Matrix3d;
41-
using MatXf = Eigen::MatrixXf;
42-
using MatXd = Eigen::MatrixXd;
39+
using Mat3f = Eigen::Matrix3f;
40+
using Mat3d = Eigen::Matrix3d;
41+
using MatXf = Eigen::MatrixXf;
42+
using MatXd = Eigen::MatrixXd;
4343

44-
const float gravity = 9.815;
44+
const float gravity = 9.815;
4545

46-
struct RobotBasicState {
47-
Vec3f base_rpy;
48-
Vec4f base_quat;
49-
Mat3f base_rot_mat;
50-
Vec3f base_omega;
51-
Vec3f base_acc;
52-
MatXf flt_base_acc_mat;
53-
VecXf joint_pos;
54-
VecXf joint_vel;
55-
VecXf joint_tau;
56-
};
46+
struct RobotBasicState {
47+
Vec3f base_rpy;
48+
Vec4f base_quat;
49+
Mat3f base_rot_mat;
50+
Vec3f base_omega;
51+
Vec3f base_acc;
52+
MatXf flt_base_acc_mat;
53+
VecXf joint_pos;
54+
VecXf joint_vel;
55+
VecXf joint_tau;
5756

58-
struct RobotAction {
59-
VecXf goal_joint_pos;
60-
VecXf goal_joint_vel;
61-
VecXf kp;
62-
VecXf kd;
63-
VecXf tau_ff;
57+
RobotBasicState(int dof = 16) {
58+
base_rpy.setZero();
59+
base_quat.setZero();
60+
base_rot_mat.setIdentity();
61+
base_omega.setZero();
62+
base_acc.setZero();
63+
flt_base_acc_mat = Eigen::MatrixXf::Zero(20, 3);
64+
joint_pos = VecXf::Zero(dof);
65+
joint_vel = VecXf::Zero(dof);
66+
joint_tau = VecXf::Zero(dof);
67+
}
68+
};
69+
70+
struct RobotAction {
71+
VecXf goal_joint_pos;
72+
VecXf goal_joint_vel;
73+
VecXf kp;
74+
VecXf kd;
75+
VecXf tau_ff;
6476

65-
MatXf ConvertToMat() {
66-
MatXf res(goal_joint_pos.rows(), 5);
67-
res.col(0) = kp;
68-
res.col(1) = goal_joint_pos;
69-
res.col(2) = kd;
70-
res.col(3) = goal_joint_vel;
71-
res.col(4) = tau_ff;
72-
return res;
73-
}
74-
};
77+
MatXf ConvertToMat() {
78+
MatXf res(goal_joint_pos.rows(), 5);
79+
res.col(0) = kp;
80+
res.col(1) = goal_joint_pos;
81+
res.col(2) = kd;
82+
res.col(3) = goal_joint_vel;
83+
res.col(4) = tau_ff;
84+
return res;
85+
}
86+
};
7587

7688

77-
struct UserCommand {
78-
double time_stamp;
89+
struct UserCommand {
90+
double time_stamp;
7991
uint8_t safe_control_mode; //0 normal, 1 stand, 2 sit, 3 joint damping
80-
uint8_t target_mode;
81-
float forward_vel_scale = 0;
82-
float side_vel_scale = 0;
83-
float turnning_vel_scale = 0;
84-
float reserved_scale;
85-
};
92+
uint8_t target_mode;
93+
float forward_vel_scale = 0;
94+
float side_vel_scale = 0;
95+
float turnning_vel_scale = 0;
96+
float reserved_scale;
97+
};
98+
99+
enum FromType {
100+
inside = 0,
101+
user,
102+
};
103+
struct NetInfo {
104+
std::string ip;
105+
int port;
106+
FromType fromType;
107+
};
108+
109+
struct DataInfo : public NetInfo {
110+
const char* buffer;
111+
ssize_t len;
112+
};
113+
struct CmdInfo : public NetInfo {
114+
int type;
115+
int command;
86116
};
117+
}; // namespace types

src/M20_sdk_deploy/include/types/custom_types.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace types{
1515
WaitingForStand = 0,
1616
StandingUp = 1,
1717
JointDamping = 2,
18+
LieDown = 4,
1819
RLControlMode = 6,
1920
};
2021

@@ -23,13 +24,22 @@ namespace types{
2324
kIdle = 0,
2425
kStandUp = 1,
2526
kJointDamping = 2,
27+
kLieDown = 4,
2628
kRLControl = 6,
2729
};
2830

2931
enum RemoteCommandType{
3032
kKeyBoard = 0,
33+
kGamepad,
3134
};
3235

36+
enum KeyCode {
37+
L1,
38+
L2,
39+
R1,
40+
R2,
41+
UNKNOWN
42+
};
3343

3444
inline std::string GetAbsPath(){
3545
char buffer[PATH_MAX];

src/M20_sdk_deploy/include/utils/basic_function.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,22 @@ inline double GetTimestampMs(){
7777
clock_gettime(CLOCK_MONOTONIC,&now_timestamp);
7878
return (now_timestamp.tv_sec-startup_timestamp.tv_sec)*1e3 + (now_timestamp.tv_nsec-startup_timestamp.tv_nsec)/1e6;
7979
}
80+
81+
inline float GetCubicSplinePos(float x0, float v0, float xf, float vf, float t, float T){
82+
if(t >= T) return xf;
83+
float a, b, c, d;
84+
d = x0;
85+
c = v0;
86+
a = (vf*T - 2*xf + v0*T + 2*x0) / pow(T, 3);
87+
b = (3*xf - vf*T - 2*v0*T - 3*x0) / pow(T, 2);
88+
return a*pow(t, 3)+b*pow(t, 2)+c*t+d;
89+
}
90+
91+
inline float GetCubicSplineVel(float x0, float v0, float xf, float vf, float t, float T){
92+
if(t >= T) return 0;
93+
float a, b, c;
94+
c = v0;
95+
a = (vf*T - 2*xf + v0*T + 2*x0) / pow(T, 3);
96+
b = (3*xf - vf*T - 2*v0*T - 3*x0) / pow(T, 2);
97+
return 3.*a*pow(t, 2) + 2.*b*t + c;
98+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* @file thread_pool.hpp
3+
* @brief thread pool
4+
* @author DeepRobotics
5+
* @version 1.0
6+
* @date 2026-01-07
7+
*
8+
* @copyright Copyright (c) 2025 DeepRobotics
9+
*
10+
*/
11+
#pragma once
12+
#include <atomic>
13+
#include <condition_variable>
14+
#include <functional>
15+
#include <mutex>
16+
#include <queue>
17+
#include <thread>
18+
#include <vector>
19+
20+
class ThreadPool {
21+
public:
22+
ThreadPool(size_t numThreads) : stop(false) {
23+
for (size_t i = 0; i < numThreads; ++i) {
24+
workers.emplace_back([this]() {
25+
while (true) {
26+
std::function<void()> task;
27+
{
28+
std::unique_lock<std::mutex> lock(this->queueMutex);
29+
this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
30+
if (this->stop && this->tasks.empty()) return;
31+
task = std::move(this->tasks.front());
32+
this->tasks.pop();
33+
}
34+
task();
35+
}
36+
});
37+
}
38+
}
39+
40+
~ThreadPool() {
41+
{
42+
std::unique_lock<std::mutex> lock(queueMutex);
43+
stop = true;
44+
}
45+
condition.notify_all();
46+
for (std::thread& worker : workers) worker.join();
47+
}
48+
49+
void enqueue(std::function<void()> task) {
50+
{
51+
std::unique_lock<std::mutex> lock(queueMutex);
52+
tasks.emplace(task);
53+
}
54+
condition.notify_one();
55+
}
56+
57+
private:
58+
std::vector<std::thread> workers;
59+
std::queue<std::function<void()>> tasks;
60+
61+
std::mutex queueMutex;
62+
std::condition_variable condition;
63+
std::atomic<bool> stop;
64+
};

0 commit comments

Comments
 (0)