Skip to content

Commit 3641fef

Browse files
author
Ziwen Zhuang
committed
[add] publish_imu option in robot.launch when func:=full
1 parent 93a3115 commit 3641fef

File tree

6 files changed

+90
-9
lines changed

6 files changed

+90
-9
lines changed

unitree_legged_real/include/convert.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ unitree_legged_msgs::IMU state2rosMsg(UNITREE_LEGGED_SDK::IMU &state)
3030
{
3131
unitree_legged_msgs::IMU ros_msg;
3232

33-
for (int i(0); i < 4; i++) ros_msg.quaternion[i] = state.quaternion[i];
33+
// make sure the ros_msg quaternion is in (x, y, z, w) order
34+
ros_msg.quaternion[0] = state.quaternion[1];
35+
ros_msg.quaternion[1] = state.quaternion[2];
36+
ros_msg.quaternion[2] = state.quaternion[3];
37+
ros_msg.quaternion[3] = state.quaternion[0];
3438

3539
for (int i(0); i < 3; i++)
3640
{

unitree_legged_real/include/real_robot.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ class UnitreeRos: public RosUdpHandler
2929
int state_check_times_max = 50; // When changing mode through UDP, the service handler checks the updated state at most this times
3030
int state_check_freq = 10; // The frequency of checking mode update.
3131
int timer_freq = 50; // default timer frequency for some default functions.
32+
bool publish_imu = false;
33+
int imu_publish_freq = 100;
34+
int imu_publish_seq = 0;
3235

33-
ros::Publisher pose_estimation_publisher;
36+
ros::Publisher imu_publisher;
3437
ros::Publisher wirelessRemote_publisher;
3538
ros::Publisher position_limit_publisher;
3639

@@ -44,13 +47,12 @@ class UnitreeRos: public RosUdpHandler
4447

4548
ros::Subscriber low_motor_subscriber;
4649

50+
ros::Timer imu_publish_timer;
4751
ros::Timer wirelessRemote_publish_timer;
4852
ros::Timer protect_limit_publish_timer;
4953

5054
protected:
5155
// For simplicity, some states and commands must be processed and estimate
52-
void pose_estimate_and_publish();
53-
5456
bool set_gaitType_srv_callback(
5557
unitree_legged_srvs::SetGaitType::Request &req,
5658
unitree_legged_srvs::SetGaitType::Response &res
@@ -70,6 +72,7 @@ class UnitreeRos: public RosUdpHandler
7072

7173
void low_motor_callback(const unitree_legged_msgs::LegsCmd::ConstPtr &msg);
7274

75+
void imu_publish_callback(const ros::TimerEvent& event);
7376
void wirelessRemote_publish_callback(const ros::TimerEvent& event);
7477
void protect_limit_publish_callback(const ros::TimerEvent& event);
7578

@@ -81,6 +84,8 @@ class UnitreeRos: public RosUdpHandler
8184
float position_protect_limit,
8285
int power_protect_level,
8386
bool cmd_check,
87+
bool start_stand,
88+
bool publish_imu,
8489
bool dryrun // If true, does not send the udp message in udp_send() but do everything else.
8590
);
8691
void publisher_init();

unitree_legged_real/include/ros_udp_node.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class RosUdpHandler
4040
float position_protect_limit;
4141
int low_power_protect_level;
4242
float low_cmd_default_tau = 0.65f;
43+
bool start_stand; // if true, the motor will be initialized to mode 10, otherwise mode 0.
4344

4445
UNITREE_LEGGED_SDK::HighCmd high_cmd_buffer = {0};
4546
UNITREE_LEGGED_SDK::HighState high_state_buffer = {0};
@@ -85,6 +86,7 @@ class RosUdpHandler
8586
float position_protect_limit, // Please check safety.h, 0.0 is the least limit
8687
int power_protect_level, // Refer to unitree_legged_sdk/safety.h
8788
bool cmd_check,
89+
bool start_stand, // If true, defualt motor mode is 10, otherwise 0.
8890
bool dryrun // If true, does not send the udp message in udp_send() but do everything else.
8991
);
9092
};

unitree_legged_real/launch/robot.launch

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
<arg name="power_protect_level" default="1"/>
1010
<arg name="output" default="screen"/>
1111
<arg name="func" default="full"/>
12+
<arg name="publish_imu" default="false"/>
13+
<arg name="start_stand" default="false"/>
1214
<!-- camera configurations, only when func:=full and camera_mode!=none -->
1315
<arg name="camera_mode" default="none"/>
1416
<arg name="image_fps" default="30"/>
@@ -23,6 +25,8 @@
2325
<param name="ctrl_level" type="str" value="$(arg ctrl_level)"/>
2426
<param name="position_protect_limit" type="double" value="$(arg position_protect_limit)"/>
2527
<param name="power_protect_level" type="int" value="$(arg power_protect_level)"/>
28+
<param name="publish_imu" type="bool" value="$(arg publish_imu)"/>
29+
<param name="start_stand" type="bool" value="$(arg start_stand)"/>
2630
</node>
2731

2832
<group if="$(eval arg('camera_mode') == 'raw')">
@@ -70,6 +74,7 @@
7074
<param name="ctrl_level" type="str" value="$(arg ctrl_level)"/>
7175
<param name="position_protect_limit" type="double" value="$(arg position_protect_limit)"/>
7276
<param name="power_protect_level" type="int" value="$(arg power_protect_level)"/>
77+
<param name="start_stand" type="bool" value="$(arg start_stand)"/>
7378
</node>
7479
</group>
7580
</launch>

unitree_legged_real/src/real_robot.cpp

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,35 @@ void UnitreeRos::low_motor_callback(const unitree_legged_msgs::LegsCmd::ConstPtr
123123
}
124124
}
125125

126+
void UnitreeRos::imu_publish_callback(const ros::TimerEvent& event){
127+
sensor_msgs::Imu ros_msg;
128+
UNITREE_LEGGED_SDK::IMU *imu_ptr;
129+
if (this->ctrl_level == UNITREE_LEGGED_SDK::HIGHLEVEL)
130+
imu_ptr = &this->high_state_buffer.imu;
131+
else
132+
imu_ptr = &this->low_state_buffer.imu;
133+
134+
// fill ros message
135+
ros_msg.header.seq = this->imu_publish_seq++;
136+
ros_msg.header.stamp = ros::Time::now();
137+
ros_msg.header.frame_id = this->robot_namespace_ + "/imu_link";
138+
ros_msg.orientation.x = imu_ptr->quaternion[0];
139+
ros_msg.orientation.y = imu_ptr->quaternion[1];
140+
ros_msg.orientation.z = imu_ptr->quaternion[2];
141+
ros_msg.orientation.w = imu_ptr->quaternion[3];
142+
// ros_msg.orientation_covariance unknown
143+
ros_msg.angular_velocity.x = imu_ptr->gyroscope[0];
144+
ros_msg.angular_velocity.y = imu_ptr->gyroscope[1];
145+
ros_msg.angular_velocity.z = imu_ptr->gyroscope[2];
146+
// ros_msg.angular_velocity_covariance unknown
147+
ros_msg.linear_acceleration.x = imu_ptr->accelerometer[0];
148+
ros_msg.linear_acceleration.y = imu_ptr->accelerometer[1];
149+
ros_msg.linear_acceleration.z = imu_ptr->accelerometer[2];
150+
// ros_mag.linear_acceleration_covariance unknown
151+
152+
this->imu_publisher.publish(ros_msg);
153+
}
154+
126155
void UnitreeRos::wirelessRemote_publish_callback(const ros::TimerEvent& event)
127156
{
128157
unitree_legged_msgs::WirelessRemote ros_msg;
@@ -197,9 +226,21 @@ UnitreeRos::UnitreeRos(
197226
float position_protect_limit,
198227
int power_protect_level,
199228
bool cmd_check,
229+
bool start_stand,
230+
bool publish_imu,
200231
bool dryrun
201232
):
202-
RosUdpHandler(robot_namespace, udp_duration, level, position_protect_limit, power_protect_level, cmd_check, dryrun)
233+
publish_imu(publish_imu),
234+
RosUdpHandler(
235+
robot_namespace,
236+
udp_duration,
237+
level,
238+
position_protect_limit,
239+
power_protect_level,
240+
cmd_check,
241+
start_stand,
242+
dryrun
243+
)
203244
{
204245
this->publisher_init();
205246
this->server_init();
@@ -214,13 +255,14 @@ void UnitreeRos::publisher_init()
214255
{
215256
if (this->ctrl_level == UNITREE_LEGGED_SDK::LOWLEVEL)
216257
{
217-
this->pose_estimation_publisher = this->ros_handle.advertise<sensor_msgs::Imu>(
218-
this->robot_namespace_ + "/imu_estimated", 1
219-
);
220258
this->position_limit_publisher = this->ros_handle.advertise<std_msgs::Float32MultiArray>(
221259
this->robot_namespace_ + "/position_limit", 1
222260
);
223261
}
262+
if (this->publish_imu)
263+
this->imu_publisher = this->ros_handle.advertise<sensor_msgs::Imu>(
264+
this->robot_namespace_ + "/imu", 1
265+
);
224266
this->wirelessRemote_publisher = this->ros_handle.advertise<unitree_legged_msgs::WirelessRemote>(
225267
this->robot_namespace_ + "/wireless_remote", 1
226268
);
@@ -281,6 +323,12 @@ void UnitreeRos::timer_init()
281323
this
282324
);
283325
}
326+
if (this->publish_imu)
327+
this->imu_publish_timer = this->ros_handle.createTimer(
328+
ros::Duration(1. / this->imu_publish_freq),
329+
&UnitreeRos::imu_publish_callback,
330+
this
331+
);
284332
this->wirelessRemote_publish_timer = this->ros_handle.createTimer(
285333
ros::Duration(1. / this->timer_freq),
286334
&UnitreeRos::wirelessRemote_publish_callback,
@@ -304,6 +352,11 @@ int main(int argc, char **argv)
304352
if (use_low_level) level = UNITREE_LEGGED_SDK::LOWLEVEL;
305353
float position_protect_limit; nh.param<float>("position_protect_limit", position_protect_limit, 0.087);
306354
int power_protect_level; nh.param<int>("power_protect_level", power_protect_level, 1);
355+
bool publish_imu; nh.param<bool>("publish_imu", publish_imu, false);
356+
bool start_stand; nh.param<bool>("start_stand", start_stand, true);
357+
358+
if (start_stand) ROS_INFO("Motor will be initialized to mode 10, please put the leg in stand positions.");
359+
else ROS_INFO("Motor will be initialized to mode 0, please put the robot on the ground or hang up.");
307360

308361
// construct and initialize this ros node
309362
UnitreeRos unitree_ros_node(
@@ -313,6 +366,8 @@ int main(int argc, char **argv)
313366
position_protect_limit,
314367
power_protect_level,
315368
cmd_check,
369+
start_stand,
370+
publish_imu,
316371
dryrun
317372
);
318373
ros::spin();

unitree_legged_real/src/ros_udp_node.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,10 @@ void RosUdpHandler::set_default_high_cmd()
110110
void RosUdpHandler::set_default_low_cmd()
111111
{
112112
// set mode
113-
for (int i(0); i < 12; i++) this->low_cmd_buffer.motorCmd[i].mode = 10;
113+
if (this->start_stand)
114+
for (int i(0); i < 12; i++) this->low_cmd_buffer.motorCmd[i].mode = 10;
115+
else
116+
for (int i(0); i < 12; i++) this->low_cmd_buffer.motorCmd[i].mode = 0;
114117
// set q (position)
115118
this->low_cmd_buffer.motorCmd[UNITREE_LEGGED_SDK::FR_0].q = -0.3;
116119
this->low_cmd_buffer.motorCmd[UNITREE_LEGGED_SDK::FR_1].q = 0.9;
@@ -245,6 +248,7 @@ RosUdpHandler::RosUdpHandler(
245248
float position_protect_limit,
246249
int power_protect_level,
247250
bool cmd_check,
251+
bool start_stand,
248252
bool dryrun
249253
):
250254
safe(UNITREE_LEGGED_SDK::LeggedType::A1),
@@ -256,6 +260,7 @@ RosUdpHandler::RosUdpHandler(
256260
position_protect_limit(position_protect_limit),
257261
low_power_protect_level(power_protect_level),
258262
cmd_check(cmd_check),
263+
start_stand(start_stand),
259264
dryrun_(dryrun),
260265
loop_udp_send("udp_send", udp_duration, 3, boost::bind(&RosUdpHandler::udp_send, this)),
261266
loop_udp_recv("udp_recv", udp_duration, 3, boost::bind(&RosUdpHandler::udp_recv, this))
@@ -302,6 +307,10 @@ int main(int argc, char **argv)
302307
if (use_low_level) level = UNITREE_LEGGED_SDK::LOWLEVEL;
303308
float position_protect_limit; nh.param<float>("position_protect_limit", position_protect_limit, 0.087);
304309
int power_protect_level; nh.param<int>("power_protect_level", power_protect_level, 1);
310+
bool start_stand; nh.param<bool>("start_stand", start_stand, true);
311+
312+
if (start_stand) ROS_INFO("Motor will be initialized to mode 10, please put the leg in stand positions.");
313+
else ROS_INFO("Motor will be initialized to mode 0, please put the robot on the ground or hang up.");
305314

306315
// construct and initialize this ros node
307316
RosUdpHandler ros_udp_handler(
@@ -311,6 +320,7 @@ int main(int argc, char **argv)
311320
position_protect_limit,
312321
power_protect_level,
313322
cmd_check,
323+
start_stand,
314324
dryrun
315325
);
316326
ros::spin();

0 commit comments

Comments
 (0)