├── .gitignore
├── LICENSE
├── README.md
├── doc
├── compare
│ ├── backward.gif
│ ├── forward.gif
│ └── sidewalk.gif
├── gazebo_a1.png
├── hardware_a1.png
├── isaac_a1.png
└── sys.png
├── docker
└── Dockerfile
├── docker_noetic_focal
├── Dockerfile
└── test.txt
├── gazebo_docker
├── Dockerfile
└── run_gazebo_docker.bash
└── src
├── a1_cpp
├── CMakeLists.txt
├── config
│ ├── gazebo_a1_mpc.yaml
│ ├── gazebo_a1_mpc_2x.yaml
│ ├── gazebo_a1_qp.yaml
│ ├── hardware_a1_mpc.yaml
│ ├── hardware_a1_mpc_new.yaml
│ ├── hardware_a1_qp.yaml
│ ├── isaac_a1_mpc.yaml
│ └── isaac_a1_qp.yaml
├── launch
│ └── a1_ctrl.launch
├── package.xml
└── src
│ ├── A1BasicEKF.cpp
│ ├── A1BasicEKF.h
│ ├── A1CtrlStates.h
│ ├── A1Params.h
│ ├── A1RobotControl.cpp
│ ├── A1RobotControl.h
│ ├── ConvexMpc.cpp
│ ├── ConvexMpc.h
│ ├── GazeboA1ROS.cpp
│ ├── GazeboA1ROS.h
│ ├── HardwareA1ROS.cpp
│ ├── HardwareA1ROS.h
│ ├── IsaacA1ROS.cpp
│ ├── IsaacA1ROS.h
│ ├── MainGazebo.cpp
│ ├── MainHardware.cpp
│ ├── MainIsaac.cpp
│ ├── legKinematics
│ ├── A1Kinematics.cpp
│ ├── A1Kinematics.h
│ └── README.md
│ ├── test
│ ├── test_bezier.cpp
│ ├── test_mpc.cpp
│ ├── test_rotation.cpp
│ └── test_unitree_msgs.cpp
│ └── utils
│ ├── Utils.cpp
│ ├── Utils.h
│ └── filter.hpp
├── data_collection
├── CMakeLists.txt
├── data
│ ├── qSineSignal.txt
│ └── qSineSignalClean.txt
├── launch
│ └── lowlevel_demo.launch
├── package.xml
└── src
│ ├── HighLevel.cpp
│ ├── HighLevel.hpp
│ ├── Lowlevel.cpp
│ ├── Lowlevel.hpp
│ ├── MainHardware.cpp
│ ├── signal_sine.cpp
│ └── signal_sine.hpp
├── go1_rl_ctrl_cpp
├── CMakeLists.txt
├── config
│ ├── hardware_parameters.yaml
│ ├── parameters.yaml
│ └── xml
│ │ ├── act.xml
│ │ ├── foot_force.xml
│ │ ├── foot_force_hardware.xml
│ │ ├── foot_pos.xml
│ │ ├── joint_pos.xml
│ │ ├── joint_vel.xml
│ │ ├── obs.xml
│ │ └── torque.xml
├── launch
│ ├── a1_ctrl.launch
│ ├── go1_ctrl.launch
│ └── go1_ctrl_hardware.launch
├── package.xml
├── resource
│ ├── cpp_model.pt
│ ├── mass.pt
│ ├── position.pt
│ └── stand_cpp_model.pt
└── src
│ ├── EKF
│ ├── Go1BasicEKF.cpp
│ └── Go1BasicEKF.hpp
│ ├── Go1CtrlStates.hpp
│ ├── Go1Params.hpp
│ ├── Go1RLController.cpp
│ ├── Go1RLController.hpp
│ ├── Go1RLHardwareController.cpp
│ ├── Go1RLHardwareController.hpp
│ ├── MainGazebo.cpp
│ ├── SwitchController.hpp
│ ├── TestHardware.cpp
│ ├── legKinematics
│ ├── Go1Kinematics.cpp
│ ├── Go1Kinematics.hpp
│ └── README.md
│ ├── observation
│ ├── Go1HardwareObservation.hpp
│ └── Go1Observation.hpp
│ ├── servo_stand_policy
│ ├── GazeboServo.cpp
│ ├── GazeboServo.hpp
│ ├── HardwareServo.cpp
│ ├── HardwareServo.hpp
│ ├── HardwareServoSwitch.cpp
│ ├── HardwareServoSwitch.hpp
│ ├── body.cpp
│ ├── body.h
│ └── servo.cpp
│ ├── torch_eigen
│ ├── TorchEigen.cpp
│ └── TorchEigen.hpp
│ └── utils
│ ├── Utils.cpp
│ ├── Utils.hpp
│ └── filter.hpp
└── pytorch_debug
├── CMakeLists.txt
├── actor_architecture_default_1.pth
├── cpp_model.pt
├── main.cpp
├── module.py
├── py_model.pt
├── rl_policy_module.py
└── student_traced_debug.pt
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
34 |
35 | build
36 | devel
37 | logs
38 | src/a1_cpp/cmake-build-debug
39 | .catkin_tools
40 | .idea
41 | .vscode
42 | src/a1_cpp/cmake-build-debug-remote/
43 |
44 | src/a1_cpp/src/mpc_osqp.cc
45 |
46 |
47 | src/pytorch_debug/libtorch
48 | src/go1_rl_ctrl_cpp/libtorch
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Go1-RL-Controller
2 | ## Introduction
3 |
4 | This repo provides a quadruped control stack that controls the Unitree Go1 robot, one of the most popular quadruped robots used in academic research in recent years. This control stack implements model free reinforcement learning control methods. Additionally, we use Docker and ROS1 to make it easy to install and develop.
5 |
6 | To facilitate quadruped research and application development, we provide interfaces to use this controller to control either simulated robots or real robots. We support following types of robots
7 |
8 | 1. Go1 Robot simulated in Gazebo Simulator
9 | 2. Go1 Robot hardware (coming soon)
10 |
11 | Even if you do not have an Go1 robot hardware, our simulation setup can let you do research in either the Gazebo simulator. Various efforts have been done to reduce the sim2real gap in this work.
12 |
13 | ## Controller Installation
14 | Will update for full installation procedure later. For now, please use google doc for reference.
15 |
16 | https://docs.google.com/document/d/1oeaLzuxC3kVKrw5ra6BAsyoRr79fPUHETEeBppi0BQo/edit
17 |
18 | After the installation setup is ready
19 |
20 | ## Controller Learning
21 | Train in issac gym, in which we can achieve a massive parallel reinforcement learning pipeline. Details will be updated later.
22 |
23 | ## Gazebo Demo
24 | Open the gazebo
25 | ```shell
26 | roslaunch unitree_gazebo normal.launch rname:=go1
27 | ```
28 |
29 | 
30 | 
31 | 
32 |
33 |
34 | ### Adjust the robot in the Gazebo
35 | During the development, we can let the robot stand up by two Unitree testing scripts. The following two commands are very handy.
36 | ```shell
37 | rosrun unitree_controller unitree_servo # let the robot stretch legs
38 | rosrun unitree_controller unitree_move_kinetic # place the robot back to origin
39 | ```
40 | We oftern running the two commands alternatively by running one and ctrl-C after a while to adjust the pose of the robot.
41 | After the robot properly stands up, it is ready to be controlled.
42 |
43 | ### Start the controller
44 |
45 | Continue to run the controller
46 | ```shell
47 | roslaunch roslaunch go1_rl_ctrl_cpp go1_ctrl.launch
48 | ```
49 |
50 | Now, the controller engages the robot in Gazebo. The robot has two modes: "stand" (default) and "walk". The robot still stands at the beginning. If using QP controller, your robot may be not very stable when standing up, you can use the two unitree_controller commands we mentioned above to adjust the robot to make it stands up first. The Convex MPC controller is more stable.
51 |
52 | Different computers have different performance. If the robot is very unstable, chances are the simulation parameters of the Gazebo needs to be tuned (unitree_ros/unitree_gazebo/worlds). See [Gazebo tutorial](https://gazebosim.org/tutorials?tut=physics_params&cat=physics) for more information.
53 |
54 | Connect a USB joystick to the host computer.
55 |
56 | Currently, we need a Linux-supported joystick like an Xbox One Controller to drive the robot around.
57 | You should follow the instructions in http://wiki.ros.org/joy/Tutorials/ConfiguringALinuxJoystick to learn how to setup a joystick controller.
58 |
59 | Take Xbox One Controller as an example:
60 |
61 | | Button | Function |
62 | | :----- | :------- |
63 | | Left Joystick | Control the robot's yaw orientation |
64 | | Right Joystick | Control the robot's walking direction |
65 | | `A`| Switch the mode between "stand" and "walk" |
66 |
67 |
68 | ## Troubleshooting
69 | Please create issues for any installation problem.
70 |
71 | ## Acknowledgement
72 | We referenced the controller architecture written by Shuo Yang and Zixin Zhang in there A1-QP-MPC-Controller.
73 |
--------------------------------------------------------------------------------
/doc/compare/backward.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zerenluo123/Go1-RL-Controller/eb0a05908f8e5a812b6f089ea3bce1c48c952541/doc/compare/backward.gif
--------------------------------------------------------------------------------
/doc/compare/forward.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zerenluo123/Go1-RL-Controller/eb0a05908f8e5a812b6f089ea3bce1c48c952541/doc/compare/forward.gif
--------------------------------------------------------------------------------
/doc/compare/sidewalk.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zerenluo123/Go1-RL-Controller/eb0a05908f8e5a812b6f089ea3bce1c48c952541/doc/compare/sidewalk.gif
--------------------------------------------------------------------------------
/doc/gazebo_a1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zerenluo123/Go1-RL-Controller/eb0a05908f8e5a812b6f089ea3bce1c48c952541/doc/gazebo_a1.png
--------------------------------------------------------------------------------
/doc/hardware_a1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zerenluo123/Go1-RL-Controller/eb0a05908f8e5a812b6f089ea3bce1c48c952541/doc/hardware_a1.png
--------------------------------------------------------------------------------
/doc/isaac_a1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zerenluo123/Go1-RL-Controller/eb0a05908f8e5a812b6f089ea3bce1c48c952541/doc/isaac_a1.png
--------------------------------------------------------------------------------
/doc/sys.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zerenluo123/Go1-RL-Controller/eb0a05908f8e5a812b6f089ea3bce1c48c952541/doc/sys.png
--------------------------------------------------------------------------------
/docker_noetic_focal/test.txt:
--------------------------------------------------------------------------------
1 | root@shuoyang-Z390:/tmp# wget http://ftp.de.debian.org/debian/pool/main/g/glib2.0/libglib2.0-0_2.66.8-1_amd64.deb
2 |
3 |
4 | root@shuoyang-Z390:/tmp# dpkg -i libglib2.0-0_2.66.8-1_amd64.deb
5 | dpkg: warning: downgrading libglib2.0-0:amd64 from 2.68.4-1ubuntu1 to 2.66.8-1
6 | (Reading database ... 119026 files and directories currently installed.)
7 | Preparing to unpack libglib2.0-0_2.66.8-1_amd64.deb ...
8 | Unpacking libglib2.0-0:amd64 (2.66.8-1) over (2.68.4-1ubuntu1) ...
9 | dpkg: dependency problems prevent configuration of libglib2.0-0:amd64:
10 | libglib2.0-0:amd64 depends on libmount1 (>= 2.35.2-7~); however:
11 | Version of libmount1:amd64 on system is 2.34-0.1ubuntu9.3.
12 | libglib2.0-0:amd64 depends on libselinux1 (>= 3.1~); however:
13 | Version of libselinux1:amd64 on system is 3.0-1build2.
14 |
15 | dpkg: error processing package libglib2.0-0:amd64 (--install):
16 | dependency problems - leaving unconfigured
17 | Processing triggers for libc-bin (2.31-0ubuntu9.7) ...
18 | Errors were encountered while processing:
19 | libglib2.0-0:amd64
20 | root@shuoyang-Z390:/tmp# wget http://archive.ubuntu.com/ubuntu/pool/main/libs/libselinux/libselinux1_3.1-3build2_amd64.deb
21 |
22 | root@shuoyang-Z390:/tmp# dpkg -i libselinux1_3.1-3build2_amd64.deb
23 |
24 | root@shuoyang-Z390:/tmp# wget http://archive.ubuntu.com/ubuntu/pool/main/g/glibc/libc6_2.34-0ubuntu3_amd64.deb
25 | --2022-05-30 22:33:19-- http://archive.ubuntu.com/ubuntu/pool/main/g/glibc/libc6_2.34-0ubuntu3_amd64.deb
26 |
27 | root@shuoyang-Z390:/tmp# dpkg -i libc6_2.34-0ubuntu3_amd64.deb
28 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
29 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
30 | root@shuoyang-Z390:/tmp# sudo dpkg -i libc6_2.34-0ubuntu3_amd64.deb
31 | sudo: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
32 | sudo: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
33 | root@shuoyang-Z390:/tmp# dpkg -i libc6_2.34-0ubuntu3_amd64.deb
34 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
35 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
36 | root@shuoyang-Z390:/tmp# dpkg -i libselinux1_3.1-3build2_amd64.deb
37 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
38 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
39 | root@shuoyang-Z390:/tmp# wget http://archive.ubuntu.com/ubuntu/pool/main/u/util-linux/libmount1_2.36.1-8ubuntu1_amd64.deb
40 |
41 | root@shuoyang-Z390:/tmp# ls
42 | ls: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
43 | ls: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
44 |
45 | root@shuoyang-Z390:/tmp# dpkg -i *.deb
46 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
47 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
48 | root@shuoyang-Z390:/tmp# apt-get -f install
49 | Reading package lists... Done
50 | Building dependency tree
51 | Reading state information... Done
52 | Correcting dependencies... failed.
53 | The following packages have unmet dependencies:
54 | libglib2.0-0 : Depends: libmount1 (>= 2.35.2-7~) but 2.34-0.1ubuntu9.3 is installed
55 | Recommends: xdg-user-dirs but it is not installed
56 | libglib2.0-bin : Depends: libglib2.0-0 (= 2.64.6-1~ubuntu20.04.4) but 2.66.8-1 is installed
57 | libglib2.0-dev : Depends: libglib2.0-0 (= 2.64.6-1~ubuntu20.04.4) but 2.66.8-1 is installed
58 | libselinux1 : Depends: libc6 (>= 2.34) but 2.31-0ubuntu9.9 is installed
59 | libselinux1-dev : Depends: libselinux1 (= 3.0-1build2) but 3.1-3build2 is installed
60 | W: Target Packages (main/binary-amd64/Packages) is configured multiple times in /etc/apt/sources.list.d/ros-latest.list:1 and /etc/apt/sources.list.d/ros1-latest.list:1
61 | W: Target Packages (main/binary-all/Packages) is configured multiple times in /etc/apt/sources.list.d/ros-latest.list:1 and /etc/apt/sources.list.d/ros1-latest.list:1
62 | E: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages.
63 | E: Unable to correct dependencies
64 | root@shuoyang-Z390:/tmp# dpkg -i libc6_2.34-0ubuntu3_amd64.deb
65 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
66 | dpkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /lib/x86_64-linux-gnu/libselinux.so.1)
--------------------------------------------------------------------------------
/gazebo_docker/Dockerfile:
--------------------------------------------------------------------------------
1 | # we build this docker based on a docker with ros already installed
2 | FROM osrf/ros:melodic-desktop-full
3 |
4 | LABEL maintainer="shuoyang@andrew.cmu.edu"
5 | ENV REFRESH_AT 2022-03-22
6 |
7 | # nvidia-container-runtime
8 | ENV NVIDIA_VISIBLE_DEVICES \
9 | ${NVIDIA_VISIBLE_DEVICES:-all}
10 | ENV NVIDIA_DRIVER_CAPABILITIES \
11 | ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics
12 |
13 | # install necessary dependencies
14 | RUN if [ "x$(nproc)" = "x1" ] ; then export USE_PROC=1 ; \
15 | else export USE_PROC=$(($(nproc)/2)) ; fi && \
16 | apt-get update && apt-get install -y \
17 | vim \
18 | libatlas-base-dev \
19 | libeigen3-dev \
20 | libgoogle-glog-dev \
21 | libsuitesparse-dev \
22 | python-catkin-tools \
23 | python3-matplotlib \
24 | gfortran \
25 | autoconf \
26 | coinor-libipopt-dev \
27 | libgfortran3 \
28 | curl \
29 | libopenmpi-dev \
30 | apt-utils \
31 | software-properties-common \
32 | build-essential \
33 | libssl-dev \
34 | wget \
35 | libtool \
36 | cmake
37 |
38 | # install python 3.6
39 | RUN apt-get update && \
40 | apt-get install -y python3.6
41 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.6 1
42 | RUN curl https://bootstrap.pypa.io/pip/3.6/get-pip.py -o get-pip.py
43 | RUN python get-pip.py
44 | RUN rm get-pip.py
45 |
46 | # change timezone (this is very important otherwise many ROS topic time will be strange)
47 | ENV TZ=America/New_York
48 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
49 |
50 | # make unitree workspace
51 | ENV SUPPORT_WS=/root/support_files
52 | ENV UNITREE_WS=/root/unitree_ws
53 | RUN mkdir -p $SUPPORT_WS
54 | RUN mkdir -p $UNITREE_WS/src
55 | WORKDIR $UNITREE_WS
56 | RUN /bin/bash -c "source /opt/ros/${ROS_DISTRO}/setup.bash; catkin init;"
57 |
58 | # install unitree sdk dependencies
59 | WORKDIR $SUPPORT_WS
60 | RUN git clone https://github.com/lcm-proj/lcm.git && \
61 | cd ${SUPPORT_WS}/lcm && \
62 | git checkout tags/v1.4.0 && \
63 | mkdir build && \
64 | cd build && \
65 | cmake .. && \
66 | make -j12 && \
67 | make install
68 |
69 | # notice we must use v3.2
70 | WORKDIR $SUPPORT_WS
71 | RUN git clone https://github.com/unitreerobotics/unitree_legged_sdk.git && \
72 | cd ${SUPPORT_WS}/unitree_legged_sdk && git checkout v3.2 && \
73 | mkdir build && \
74 | cd build && \
75 | cmake .. && \
76 | make -j12
77 |
78 | WORKDIR $SUPPORT_WS
79 | RUN git clone https://github.com/unitreerobotics/aliengo_sdk.git && \
80 | cd ${SUPPORT_WS}/aliengo_sdk && \
81 | mkdir build && \
82 | cd build && \
83 | cmake .. && \
84 | make -j12
85 |
86 | # install necessary dependencies
87 | RUN if [ "x$(nproc)" = "x1" ] ; then export USE_PROC=1 ; \
88 | else export USE_PROC=$(($(nproc)/2)) ; fi && \
89 | apt-get update && apt-get install -y \
90 | ros-${ROS_DISTRO}-ros-control \
91 | ros-${ROS_DISTRO}-gazebo-ros \
92 | ros-${ROS_DISTRO}-joy \
93 | ros-${ROS_DISTRO}-ros-controllers \
94 | ros-${ROS_DISTRO}-robot-state-publisher \
95 | ros-${ROS_DISTRO}-plotjuggler-ros
96 |
97 | WORKDIR $UNITREE_WS/src
98 | RUN git clone https://github.com/ShuoYangRobotics/unitree_ros.git
99 | WORKDIR $UNITREE_WS
100 |
101 | ENV UNITREE_SDK_VERSION=3_2
102 | ENV UNITREE_LEGGED_SDK_PATH=${SUPPORT_WS}/unitree_legged_sdk
103 | ENV ALIENGO_SDK_PATH=${SUPPORT_WS}/aliengo_sdk
104 | ENV UNITREE_PLATFORM=amd64
105 | RUN echo "#unitree config" >> ~/.bashrc
106 | RUN echo "export export UNITREE_SDK_VERSION=3_2" >> ~/.bashrc
107 | RUN echo "export UNITREE_LEGGED_SDK_PATH=${SUPPORT_WS}/unitree_legged_sdk" >> ~/.bashrc
108 | RUN echo "export ALIENGO_SDK_PATH=${SUPPORT_WS}/aliengo_sdk" >> ~/.bashrc
109 | RUN echo "export UNITREE_PLATFORM=\"amd64\"" >> ~/.bashrc
110 | RUN echo "source ${UNITREE_WS}/devel/setup.bash" >> ~/.bashrc
111 |
112 | # compile unitree ros
113 | RUN ls $UNITREE_WS/src/unitree_ros
114 | RUN /bin/bash -c "source /opt/ros/${ROS_DISTRO}/setup.bash; catkin build unitree_legged_msgs; source ${UNITREE_WS}/devel/setup.bash; catkin build"
115 |
116 |
117 | RUN echo "export ROS_MASTER_URI=http://localhost:11311;export ROS_IP=localhost;export ROS_HOSTNAME=localhost" >> ~/.bashrc
118 |
119 | # To use rosparam load yaml files
120 | RUN pip install pyyaml
121 |
122 | # default use python 2.7, or type this command when docker starts
123 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python2.7 3
--------------------------------------------------------------------------------
/gazebo_docker/run_gazebo_docker.bash:
--------------------------------------------------------------------------------
1 | XAUTH=/tmp/.docker.xauth
2 | if [ ! -f $XAUTH ]
3 | then
4 | xauth_list=$(xauth nlist :0 | sed -e 's/^..../ffff/')
5 | if [ ! -z "$xauth_list" ]
6 | then
7 | sudo echo $xauth_list | sudo xauth -f $XAUTH nmerge -
8 | else
9 | sudo touch $XAUTH
10 | fi
11 | sudo chmod a+r $XAUTH
12 | fi
13 |
14 | sudo docker run -it \
15 | --env="DISPLAY=$DISPLAY" \
16 | --env="QT_X11_NO_MITSHM=1" \
17 | --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
18 | --env="XAUTHORITY=$XAUTH" \
19 | --volume="$XAUTH:$XAUTH" \
20 | --runtime=nvidia \
21 | --privileged \
22 | --network host \
23 | --name a1_unitree_gazebo_docker \
24 | a1_unitree_gazebo_image
25 |
--------------------------------------------------------------------------------
/src/a1_cpp/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10.1)
2 | project(a1_cpp)
3 | set(CMAKE_BUILD_TYPE "Release")
4 | #set(CMAKE_BUILD_TYPE "Debug")
5 | set(CMAKE_CXX_FLAGS "-std=c++14")
6 | set(CMAKE_CXX_STANDARD 14)
7 | #-DEIGEN_USE_MKL_ALL")
8 | set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g")
9 |
10 | #check environmental variables
11 | message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
12 |
13 | find_package(catkin REQUIRED COMPONENTS
14 | roscpp
15 | rospy
16 | std_msgs
17 | geometry_msgs
18 | unitree_legged_msgs
19 | )
20 |
21 | find_package(Eigen3)
22 | include_directories(
23 | ${EIGEN3_INCLUDE_DIR}
24 | )
25 |
26 | catkin_package(
27 | # INCLUDE_DIRS include
28 | # LIBRARIES rc_sim_oub
29 | # CATKIN_DEPENDS roscpp rospy std_msgs
30 | # DEPENDS system_lib
31 | )
32 |
33 | include_directories(
34 | ${catkin_INCLUDE_DIRS}
35 | )
36 |
37 | # to find osqp.h
38 | include_directories($ENV{UNITREE_LOCAL_INSTALL}/include/osqp)
39 | find_package(OsqpEigen REQUIRED)
40 |
41 | # add unitree hardware library, these flags must be correctly set
42 | include_directories(
43 | $ENV{UNITREE_LEGGED_SDK_PATH}/include
44 | )
45 |
46 | link_directories($ENV{UNITREE_LEGGED_SDK_PATH}/lib/cpp/amd64)
47 | set(EXTRA_LIBS -pthread libunitree_legged_sdk.so)
48 |
49 | # Declare cpp libraries
50 | # common robot controller every type of robots need
51 | add_library(a1_lib
52 | src/legKinematics/A1Kinematics.h
53 | src/legKinematics/A1Kinematics.cpp
54 | src/A1Params.h
55 | src/A1CtrlStates.h
56 | src/utils/Utils.cpp
57 | src/utils/Utils.h
58 | src/A1RobotControl.cpp
59 | src/A1RobotControl.h
60 | src/A1BasicEKF.cpp
61 | src/A1BasicEKF.h
62 | src/ConvexMpc.cpp
63 | src/ConvexMpc.h
64 | )
65 | target_link_libraries(a1_lib ${catkin_LIBRARIES} OsqpEigen::OsqpEigen)
66 |
67 | # lib of different types of robots
68 | add_library(gazebo_a1_lib
69 | src/GazeboA1ROS.h
70 | src/GazeboA1ROS.cpp
71 | )
72 |
73 | add_library(hardware_a1_lib
74 | src/HardwareA1ROS.h
75 | src/HardwareA1ROS.cpp
76 | )
77 |
78 | # all robots depends on the a1_lib
79 | target_link_libraries(gazebo_a1_lib a1_lib)
80 | target_link_libraries(hardware_a1_lib a1_lib ${EXTRA_LIBS})
81 |
82 | # Declare a cpp executable for gazebo robot
83 | add_executable(gazebo_a1_ctrl src/MainGazebo.cpp)
84 | target_link_libraries(gazebo_a1_ctrl
85 | gazebo_a1_lib
86 | ${catkin_LIBRARIES}
87 | OsqpEigen::OsqpEigen
88 | )
89 |
90 | # Declare a cpp executable for hardware robot
91 | add_executable(hardware_a1_ctrl src/MainHardware.cpp)
92 | target_link_libraries(hardware_a1_ctrl
93 | hardware_a1_lib
94 | ${catkin_LIBRARIES}
95 | OsqpEigen::OsqpEigen
96 | )
97 |
98 | # tests
99 | # Declare a cpp executable
100 |
101 | #add_executable(test_rotation src/test/test_rotation.cpp
102 | # src/utils/Utils.cpp
103 | # src/utils/Utils.h
104 | # )
105 |
106 | add_executable(test_bezier src/test/test_bezier.cpp
107 | src/utils/Utils.cpp
108 | src/utils/Utils.h
109 | )
110 |
111 | add_executable(test_mpc src/test/test_mpc.cpp)
112 | target_link_libraries(test_mpc
113 | a1_lib
114 | ${catkin_LIBRARIES}
115 | OsqpEigen::OsqpEigen
116 | )
117 |
118 | add_executable(test_unitree_legged_msgs src/test/test_unitree_msgs.cpp)
119 | target_link_libraries(test_unitree_legged_msgs
120 | ${catkin_LIBRARIES}
121 | )
122 |
--------------------------------------------------------------------------------
/src/a1_cpp/config/gazebo_a1_mpc.yaml:
--------------------------------------------------------------------------------
1 | use_sim_time: true
2 | stance_leg_control_type: 1 # 0: QP; 1: MPC
3 |
4 | # physics parameters
5 |
6 | a1_robot_mass: 12.0
7 |
8 | a1_trunk_inertia_xx: 0.0168352186
9 | a1_trunk_inertia_xy: 0.0
10 | a1_trunk_inertia_xz: 0.0
11 | a1_trunk_inertia_yz: 0.0
12 | a1_trunk_inertia_yy: 0.0656071082
13 | a1_trunk_inertia_zz: 0.0742720659
14 |
15 | # default foothold position
16 |
17 | a1_default_foot_pos_FL_x: 0.17
18 | a1_default_foot_pos_FL_y: 0.15
19 | a1_default_foot_pos_FL_z: -0.35
20 |
21 | a1_default_foot_pos_FR_x: 0.17
22 | a1_default_foot_pos_FR_y: -0.15
23 | a1_default_foot_pos_FR_z: -0.35
24 |
25 | a1_default_foot_pos_RL_x: -0.17
26 | a1_default_foot_pos_RL_y: 0.15
27 | a1_default_foot_pos_RL_z: -0.35
28 |
29 | a1_default_foot_pos_RR_x: -0.17
30 | a1_default_foot_pos_RR_y: -0.15
31 | a1_default_foot_pos_RR_z: -0.35
32 |
33 | a1_gait_counter_speed_FL: 1.0
34 | a1_gait_counter_speed_FR: 1.0
35 | a1_gait_counter_speed_RL: 1.0
36 | a1_gait_counter_speed_RR: 1.0
37 |
38 | # MPC parameters
39 |
40 | q_weights_0: 20.0 # roll
41 | q_weights_1: 10.0 # pitch
42 | q_weights_2: 1.0 # yaw
43 |
44 | q_weights_3: 0.0 # pos x
45 | q_weights_4: 0.0 # pos y
46 | q_weights_5: 420.0 # pos z
47 |
48 | q_weights_6: 0.05 # omega x
49 | q_weights_7: 0.05 # omega y
50 | q_weights_8: 0.05 # omega z
51 |
52 | q_weights_9: 30.0 # vel x
53 | q_weights_10: 30.0 # vel y
54 | q_weights_11: 10.0 # vel z
55 |
56 | q_weights_12: 0.0
57 |
58 | r_weights_0: 0.0000001
59 | r_weights_1: 0.0000001
60 | r_weights_2: 0.0000001
61 |
62 | r_weights_3: 0.0000001
63 | r_weights_4: 0.0000001
64 | r_weights_5: 0.0000001
65 |
66 | r_weights_6: 0.0000001
67 | r_weights_7: 0.0000001
68 | r_weights_8: 0.0000001
69 |
70 | r_weights_9: 0.0000001
71 | r_weights_10: 0.0000001
72 | r_weights_11: 0.0000001
73 |
74 | # foot swing controller parameters
75 | # force_tgt = km_foot * kp_foot * foot_pos_error
76 |
77 | a1_kp_foot_x: 200.0
78 | a1_kp_foot_y: 200.0
79 | a1_kp_foot_z: 150.0
80 |
81 | a1_kd_foot_x: 10.0
82 | a1_kd_foot_y: 10.0
83 | a1_kd_foot_z: 5.0
84 |
85 | a1_km_foot_x: 0.1
86 | a1_km_foot_y: 0.1
87 | a1_km_foot_z: 0.1
88 |
--------------------------------------------------------------------------------
/src/a1_cpp/config/gazebo_a1_mpc_2x.yaml:
--------------------------------------------------------------------------------
1 | use_sim_time: true
2 | stance_leg_control_type: 1 # 0: QP; 1: MPC
3 |
4 | # physics parameters
5 |
6 | a1_robot_mass: 12.0
7 |
8 | a1_trunk_inertia_xx: 0.0168352186
9 | a1_trunk_inertia_xy: 0.0
10 | a1_trunk_inertia_xz: 0.0
11 | a1_trunk_inertia_yz: 0.0
12 | a1_trunk_inertia_yy: 0.0656071082
13 | a1_trunk_inertia_zz: 0.0742720659
14 |
15 | # default foothold position
16 |
17 | a1_default_foot_pos_FL_x: 0.17
18 | a1_default_foot_pos_FL_y: 0.12
19 | a1_default_foot_pos_FL_z: -0.32
20 |
21 | a1_default_foot_pos_FR_x: 0.17
22 | a1_default_foot_pos_FR_y: -0.12
23 | a1_default_foot_pos_FR_z: -0.32
24 |
25 | a1_default_foot_pos_RL_x: -0.17
26 | a1_default_foot_pos_RL_y: 0.12
27 | a1_default_foot_pos_RL_z: -0.32
28 |
29 | a1_default_foot_pos_RR_x: -0.17
30 | a1_default_foot_pos_RR_y: -0.12
31 | a1_default_foot_pos_RR_z: -0.32
32 |
33 | a1_gait_counter_speed_FL: 1.5
34 | a1_gait_counter_speed_FR: 1.5
35 | a1_gait_counter_speed_RL: 1.5
36 | a1_gait_counter_speed_RR: 1.5
37 |
38 | # MPC parameters
39 |
40 | q_weights_0: 20.0 # roll
41 | q_weights_1: 10.0 # pitch
42 | q_weights_2: 20.0 # yaw
43 |
44 | q_weights_3: 0.0 # pos x
45 | q_weights_4: 0.0 # pos y
46 | q_weights_5: 320.0 # pos z
47 |
48 | q_weights_6: 0.05 # omega x
49 | q_weights_7: 0.05 # omega y
50 | q_weights_8: 0.05 # omega z
51 |
52 | q_weights_9: 30.0 # vel x
53 | q_weights_10: 30.0 # vel y
54 | q_weights_11: 10.0 # vel z
55 |
56 | q_weights_12: 0.0
57 |
58 | r_weights_0: 0.00004
59 | r_weights_1: 0.00004
60 | r_weights_2: 0.00004
61 |
62 | r_weights_3: 0.00004
63 | r_weights_4: 0.00004
64 | r_weights_5: 0.00004
65 |
66 | r_weights_6: 0.0005
67 | r_weights_7: 0.0005
68 | r_weights_8: 0.00004
69 |
70 | r_weights_9: 0.0005
71 | r_weights_10: 0.0005
72 | r_weights_11: 0.00004
73 |
74 | # foot swing controller parameters
75 | # force_tgt = km_foot * kp_foot * foot_pos_error
76 |
77 | a1_kp_foot_x: 200.0
78 | a1_kp_foot_y: 200.0
79 | a1_kp_foot_z: 150.0
80 |
81 | a1_kd_foot_x: 10.0
82 | a1_kd_foot_y: 10.0
83 | a1_kd_foot_z: 5.0
84 |
85 | a1_km_foot_x: 0.1
86 | a1_km_foot_y: 0.1
87 | a1_km_foot_z: 0.1
88 |
--------------------------------------------------------------------------------
/src/a1_cpp/config/gazebo_a1_qp.yaml:
--------------------------------------------------------------------------------
1 | use_sim_time: true
2 | stance_leg_control_type: 0 # 0: QP; 1: MPC
3 |
4 | # physics parameters
5 |
6 | a1_robot_mass: 12.0
7 |
8 | # default foothold position
9 |
10 | a1_default_foot_pos_FL_x: 0.17
11 | a1_default_foot_pos_FL_y: 0.15
12 | a1_default_foot_pos_FL_z: -0.35
13 |
14 | a1_default_foot_pos_FR_x: 0.17
15 | a1_default_foot_pos_FR_y: -0.15
16 | a1_default_foot_pos_FR_z: -0.35
17 |
18 | a1_default_foot_pos_RL_x: -0.17
19 | a1_default_foot_pos_RL_y: 0.15
20 | a1_default_foot_pos_RL_z: -0.35
21 |
22 | a1_default_foot_pos_RR_x: -0.17
23 | a1_default_foot_pos_RR_y: -0.15
24 | a1_default_foot_pos_RR_z: -0.35
25 |
26 | a1_gait_counter_speed_FL: 0.7
27 | a1_gait_counter_speed_FR: 0.7
28 | a1_gait_counter_speed_RL: 0.7
29 | a1_gait_counter_speed_RR: 0.7
30 |
31 | # foot swing controller parameters
32 | # force_tgt = km_foot * kp_foot * foot_pos_error
33 |
34 | a1_kp_foot_x: 200.0
35 | a1_kp_foot_y: 300.0
36 | a1_kp_foot_z: 200.0
37 |
38 | a1_kd_foot_x: 4.0
39 | a1_kd_foot_y: 4.0
40 | a1_kd_foot_z: 4.0
41 |
42 | a1_km_foot_x: 0.1
43 | a1_km_foot_y: 0.1
44 | a1_km_foot_z: 0.1
45 |
46 | # foot stance force controller parameters
47 | # root_acc = [root_ddot_p_deisre; root_ddot_w_desire]
48 | # root_ddot_p_deisre = kp_linear (pos error)
49 | # + kd_linear (linear velocity error)
50 | # root_ddot_w_desire = kp_angular (euler error)
51 | # + kd_linear (rotation velocity error)
52 | # root_acc are used to compute ground contact force
53 |
54 | a1_kp_linear_x: 100.0
55 | a1_kp_linear_y: 100.0
56 | a1_kp_linear_z: 300.0
57 |
58 | a1_kd_linear_x: 70.0
59 | a1_kd_linear_y: 70.0
60 | a1_kd_linear_z: 120.0
61 |
62 | a1_kp_angular_x: 150.0
63 | a1_kp_angular_y: 150.0
64 | a1_kp_angular_z: 1.0
65 |
66 | a1_kd_angular_x: 4.5
67 | a1_kd_angular_y: 4.5
68 | a1_kd_angular_z: 30.0
69 |
--------------------------------------------------------------------------------
/src/a1_cpp/config/hardware_a1_mpc.yaml:
--------------------------------------------------------------------------------
1 | use_sim_time: false
2 | a1_hardware_power_level: 10
3 | stance_leg_control_type: 1 # 0: QP; 1: MPC
4 |
5 | # physics parameters
6 |
7 | a1_robot_mass: 13.5
8 |
9 | a1_trunk_inertia_xx: 0.0168352186
10 | a1_trunk_inertia_xy: 0.0
11 | a1_trunk_inertia_xz: 0.0
12 | a1_trunk_inertia_yz: 0.0
13 | a1_trunk_inertia_yy: 0.0656071082
14 | a1_trunk_inertia_zz: 0.0742720659
15 |
16 | # default foothold position
17 |
18 | a1_default_foot_pos_FL_x: 0.17
19 | a1_default_foot_pos_FL_y: 0.15
20 | a1_default_foot_pos_FL_z: -0.3
21 |
22 | a1_default_foot_pos_FR_x: 0.17
23 | a1_default_foot_pos_FR_y: -0.15
24 | a1_default_foot_pos_FR_z: -0.3
25 |
26 | a1_default_foot_pos_RL_x: -0.17
27 | a1_default_foot_pos_RL_y: 0.15
28 | a1_default_foot_pos_RL_z: -0.3
29 |
30 | a1_default_foot_pos_RR_x: -0.17
31 | a1_default_foot_pos_RR_y: -0.15
32 | a1_default_foot_pos_RR_z: -0.3
33 |
34 | a1_gait_counter_speed_FL: 1.4
35 | a1_gait_counter_speed_FR: 1.4
36 | a1_gait_counter_speed_RL: 1.4
37 | a1_gait_counter_speed_RR: 1.4
38 |
39 | # MPC parameters
40 |
41 | q_weights_0: 150.0 # roll
42 | q_weights_1: 150.0 # pitch
43 | q_weights_2: 50.0 # yaw
44 |
45 | q_weights_3: 0.0 # pos x
46 | q_weights_4: 0.0 # pos y
47 | q_weights_5: 80.0 # pos z
48 |
49 | q_weights_6: 0.2 # omega x
50 | q_weights_7: 0.2 # omega y
51 | q_weights_8: 0.2 # omega z
52 |
53 | q_weights_9: 0.3 # vel x
54 | q_weights_10: 0.3 # vel y
55 | q_weights_11: 0.3 # vel z
56 |
57 | q_weights_12: 0.0
58 |
59 | r_weights_0: 0.01
60 | r_weights_1: 0.01
61 | r_weights_2: 0.001
62 |
63 | r_weights_3: 0.01
64 | r_weights_4: 0.01
65 | r_weights_5: 0.001
66 |
67 | r_weights_6: 0.01
68 | r_weights_7: 0.01
69 | r_weights_8: 0.001
70 |
71 | r_weights_9: 0.01
72 | r_weights_10: 0.01
73 | r_weights_11: 0.001
74 |
75 | # foot swing controller parameters
76 | # force_tgt = km_foot * kp_foot * foot_pos_error
77 |
78 | a1_kp_foot_x: 120.0
79 | a1_kp_foot_y: 120.0
80 | a1_kp_foot_z: 80.0
81 |
82 | a1_kd_foot_x: 6.0
83 | a1_kd_foot_y: 6.0
84 | a1_kd_foot_z: 5.0
85 |
86 | a1_km_foot_x: 0.1
87 | a1_km_foot_y: 0.1
88 | a1_km_foot_z: 0.1
89 |
--------------------------------------------------------------------------------
/src/a1_cpp/config/hardware_a1_mpc_new.yaml:
--------------------------------------------------------------------------------
1 | use_sim_time: false
2 | a1_hardware_power_level: 9
3 | stance_leg_control_type: 1 # 0: QP; 1: MPC
4 |
5 | # physics parameters
6 |
7 | a1_robot_mass: 12.5
8 |
9 | a1_trunk_inertia_xx: 0.0178533
10 | a1_trunk_inertia_xy: 0.0
11 | a1_trunk_inertia_xz: 0.0
12 | a1_trunk_inertia_yz: 0.0
13 | a1_trunk_inertia_yy: 0.0377999
14 | a1_trunk_inertia_zz: 0.0456542
15 |
16 | # default foothold position
17 |
18 | a1_default_foot_pos_FL_x: 0.17
19 | a1_default_foot_pos_FL_y: 0.12
20 | a1_default_foot_pos_FL_z: -0.32
21 |
22 | a1_default_foot_pos_FR_x: 0.17
23 | a1_default_foot_pos_FR_y: -0.12
24 | a1_default_foot_pos_FR_z: -0.32
25 |
26 | a1_default_foot_pos_RL_x: -0.17
27 | a1_default_foot_pos_RL_y: 0.12
28 | a1_default_foot_pos_RL_z: -0.32
29 |
30 | a1_default_foot_pos_RR_x: -0.17
31 | a1_default_foot_pos_RR_y: -0.12
32 | a1_default_foot_pos_RR_z: -0.32
33 |
34 | a1_gait_counter_speed_FL: 0.55
35 | a1_gait_counter_speed_FR: 0.55
36 | a1_gait_counter_speed_RL: 0.55
37 | a1_gait_counter_speed_RR: 0.55
38 |
39 | # MPC parameters
40 |
41 | q_weights_0: 10.0 # roll 60
42 | q_weights_1: 20.0 # pitch 80
43 | q_weights_2: 60.0 # yaw
44 |
45 | q_weights_3: 0 # pos x
46 | q_weights_4: 0 # pos y
47 | q_weights_5: 50 # pos z
48 |
49 | q_weights_6: 0.02 # omega x
50 | q_weights_7: 0.02 # omega y
51 | q_weights_8: 10.0 # omega z
52 |
53 | q_weights_9: 5 # vel x
54 | q_weights_10: 5 # vel y
55 | q_weights_11: 1 # vel z
56 |
57 |
58 | q_weights_12: 0.0
59 |
60 | r_weights_0: 0.000011
61 | r_weights_1: 0.000011
62 | r_weights_2: 0.000011
63 |
64 | r_weights_3: 0.000011
65 | r_weights_4: 0.000011
66 | r_weights_5: 0.000011
67 |
68 | r_weights_6: 0.000011
69 | r_weights_7: 0.000011
70 | r_weights_8: 0.000011
71 |
72 | r_weights_9: 0.000011
73 | r_weights_10: 0.000011
74 | r_weights_11: 0.000011
75 |
76 | # foot swing controller parameters
77 | # force_tgt = km_foot * kp_foot * foot_pos_error
78 |
79 | a1_kp_foot_x: 40.0
80 | a1_kp_foot_y: 40.0
81 | a1_kp_foot_z: 30.0
82 |
83 | a1_kd_foot_x: 2.0
84 | a1_kd_foot_y: 2.0
85 | a1_kd_foot_z: 2.0
86 |
87 | a1_km_foot_x: 0.1
88 | a1_km_foot_y: 0.1
89 | a1_km_foot_z: 0.1
--------------------------------------------------------------------------------
/src/a1_cpp/config/hardware_a1_qp.yaml:
--------------------------------------------------------------------------------
1 | use_sim_time: false
2 | a1_hardware_power_level: 8
3 | stance_leg_control_type: 0 # 0: QP; 1: MPC
4 |
5 | # physics parameters
6 |
7 | a1_robot_mass: 15.0
8 |
9 | # default foothold position
10 |
11 | a1_default_foot_pos_FL_x: 0.17
12 | a1_default_foot_pos_FL_y: 0.12
13 | a1_default_foot_pos_FL_z: -0.32
14 |
15 | a1_default_foot_pos_FR_x: 0.17
16 | a1_default_foot_pos_FR_y: -0.12
17 | a1_default_foot_pos_FR_z: -0.32
18 |
19 | a1_default_foot_pos_RL_x: -0.17
20 | a1_default_foot_pos_RL_y: 0.12
21 | a1_default_foot_pos_RL_z: -0.32
22 |
23 | a1_default_foot_pos_RR_x: -0.17
24 | a1_default_foot_pos_RR_y: -0.12
25 | a1_default_foot_pos_RR_z: -0.32
26 |
27 | a1_gait_counter_speed_FL: 0.2
28 | a1_gait_counter_speed_FR: 0.2
29 | a1_gait_counter_speed_RL: 0.2
30 | a1_gait_counter_speed_RR: 0.2
31 |
32 | # foot swing controller parameters
33 | # force_tgt = km_foot * kp_foot * foot_pos_error
34 |
35 | a1_kp_foot_x: 160.0
36 | a1_kp_foot_y: 160.0
37 | a1_kp_foot_z: 250.0
38 |
39 | a1_kd_foot_x: 1.5
40 | a1_kd_foot_y: 1.5
41 | a1_kd_foot_z: 1.5
42 |
43 | a1_km_foot_x: 0.1
44 | a1_km_foot_y: 0.1
45 | a1_km_foot_z: 0.1
46 |
47 | # foot stance force controller parameters
48 | # root_acc = [root_ddot_p_deisre; root_ddot_w_desire]
49 | # root_ddot_p_deisre = kp_linear (pos error)
50 | # + kd_linear (linear velocity error)
51 | # root_ddot_w_desire = kp_angular (euler error)
52 | # + kd_linear (rotation velocity error)
53 | # root_acc are used to compute ground contact force
54 |
55 | a1_kp_linear_x: 600.0
56 | a1_kp_linear_y: 600.0
57 | a1_kp_linear_z: 1500.0
58 |
59 | a1_kd_linear_x: 150.0
60 | a1_kd_linear_y: 150.0
61 | a1_kd_linear_z: 200.0
62 |
63 | a1_kp_angular_x: 30.0
64 | a1_kp_angular_y: 30.0
65 | a1_kp_angular_z: 10.0
66 |
67 | a1_kd_angular_x: 1.0
68 | a1_kd_angular_y: 1.0
69 | a1_kd_angular_z: 3.5
70 |
--------------------------------------------------------------------------------
/src/a1_cpp/config/isaac_a1_mpc.yaml:
--------------------------------------------------------------------------------
1 | use_sim_time: true
2 | stance_leg_control_type: 1 # 0: QP; 1: MPC
3 | use_terrain_adapt: 0 # 0 do not use terrain adaptation
4 |
5 | # physics parameters
6 |
7 | a1_robot_mass: 12.0
8 |
9 | a1_trunk_inertia_xx: 0.0158533
10 | a1_trunk_inertia_xy: 0.0
11 | a1_trunk_inertia_xz: 0.0
12 | a1_trunk_inertia_yz: 0.0
13 | a1_trunk_inertia_yy: 0.0377999
14 | a1_trunk_inertia_zz: 0.0456542
15 |
16 | # default foothold position
17 |
18 | a1_default_foot_pos_FL_x: 0.24
19 | a1_default_foot_pos_FL_y: 0.15
20 | a1_default_foot_pos_FL_z: -0.35
21 |
22 | a1_default_foot_pos_FR_x: 0.24
23 | a1_default_foot_pos_FR_y: -0.15
24 | a1_default_foot_pos_FR_z: -0.35
25 |
26 | a1_default_foot_pos_RL_x: -0.17
27 | a1_default_foot_pos_RL_y: 0.15
28 | a1_default_foot_pos_RL_z: -0.35
29 |
30 | a1_default_foot_pos_RR_x: -0.17
31 | a1_default_foot_pos_RR_y: -0.15
32 | a1_default_foot_pos_RR_z: -0.35
33 |
34 | a1_gait_counter_speed_FL: 2.5
35 | a1_gait_counter_speed_FR: 2.5
36 | a1_gait_counter_speed_RL: 2.5
37 | a1_gait_counter_speed_RR: 2.5
38 |
39 | # MPC parameters
40 |
41 | q_weights_0: 100.0 # roll
42 | q_weights_1: 100.0 # pitch
43 | q_weights_2: 50.0 # yaw
44 |
45 | q_weights_3: 0.0 # pos x
46 | q_weights_4: 0.0 # pos y
47 | q_weights_5: 420.0 # pos z
48 |
49 | q_weights_6: 0.01 # omega x
50 | q_weights_7: 0.01 # omega y
51 | q_weights_8: 0.05 # omega z
52 |
53 | q_weights_9: 30.0 # vel x
54 | q_weights_10: 30.0 # vel y
55 | q_weights_11: 10.0 # vel z
56 |
57 | q_weights_12: 0.0
58 |
59 | r_weights_0: 1e-7
60 | r_weights_1: 1e-7
61 | r_weights_2: 1e-7
62 |
63 | r_weights_3: 1e-7
64 | r_weights_4: 1e-7
65 | r_weights_5: 1e-7
66 |
67 | r_weights_6: 1e-7
68 | r_weights_7: 1e-7
69 | r_weights_8: 1e-7
70 |
71 | r_weights_9: 1e-7
72 | r_weights_10: 1e-7
73 | r_weights_11: 1e-7
74 |
75 | # foot swing controller parameters
76 | # force_tgt = km_foot * kp_foot * foot_pos_error
77 |
78 | a1_kp_foot_x: 3250.0
79 | a1_kp_foot_y: 3250.0
80 | a1_kp_foot_z: 4000.0
81 |
82 | a1_kd_foot_x: 5.0
83 | a1_kd_foot_y: 5.0
84 | a1_kd_foot_z: 5.0
85 |
86 | a1_km_foot_x: 0.5
87 | a1_km_foot_y: 0.5
88 | a1_km_foot_z: 0.5
89 |
--------------------------------------------------------------------------------
/src/a1_cpp/config/isaac_a1_qp.yaml:
--------------------------------------------------------------------------------
1 | use_sim_time: true
2 | stance_leg_control_type: 0 # 0: QP; 1: MPC
3 |
4 | # physics parameters
5 |
6 | a1_robot_mass: 12.0
7 |
8 | # default foothold position
9 |
10 | a1_default_foot_pos_FL_x: 0.25
11 | a1_default_foot_pos_FL_y: 0.15
12 | a1_default_foot_pos_FL_z: -0.33
13 |
14 | a1_default_foot_pos_FR_x: 0.25
15 | a1_default_foot_pos_FR_y: -0.15
16 | a1_default_foot_pos_FR_z: -0.33
17 |
18 | a1_default_foot_pos_RL_x: -0.17
19 | a1_default_foot_pos_RL_y: 0.15
20 | a1_default_foot_pos_RL_z: -0.33
21 |
22 | a1_default_foot_pos_RR_x: -0.17
23 | a1_default_foot_pos_RR_y: -0.15
24 | a1_default_foot_pos_RR_z: -0.33
25 |
26 | a1_gait_counter_speed_FL: 2.0
27 | a1_gait_counter_speed_FR: 2.0
28 | a1_gait_counter_speed_RL: 2.0
29 | a1_gait_counter_speed_RR: 2.0
30 |
31 | # foot swing controller parameters
32 | # force_tgt = km_foot * kp_foot * foot_pos_error
33 |
34 | a1_kp_foot_x: 4250.0
35 | a1_kp_foot_y: 4250.0
36 | a1_kp_foot_z: 3000.0
37 |
38 | a1_kd_foot_x: 0.0
39 | a1_kd_foot_y: 0.0
40 | a1_kd_foot_z: 0.0
41 |
42 | a1_km_foot_x: 0.5
43 | a1_km_foot_y: 0.5
44 | a1_km_foot_z: 0.5
45 |
46 | # foot stance force controller parameters
47 | # root_acc = [root_ddot_p_deisre; root_ddot_w_desire]
48 | # root_ddot_p_deisre = kp_linear (pos error)
49 | # + kd_linear (linear velocity error)
50 | # root_ddot_w_desire = kp_angular (euler error)
51 | # + kd_linear (rotation velocity error)
52 | # root_acc are used to compute ground contact force
53 |
54 | a1_kp_linear_x: 1450.0
55 | a1_kp_linear_y: 1450.0
56 | a1_kp_linear_z: 3800.0
57 |
58 | a1_kd_linear_x: 2600.0
59 | a1_kd_linear_y: 2600.0
60 | a1_kd_linear_z: 0.0
61 |
62 | a1_kp_angular_x: 420.0
63 | a1_kp_angular_y: 420.0
64 | a1_kp_angular_z: 150.0
65 |
66 | a1_kd_angular_x: 0.0
67 | a1_kd_angular_y: 0.0
68 | a1_kd_angular_z: 560.0
69 |
--------------------------------------------------------------------------------
/src/a1_cpp/launch/a1_ctrl.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/a1_cpp/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | a1_cpp
4 | 0.0.1
5 | The A1 Cpp Controller
6 |
7 |
8 |
9 |
10 | shuo
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | catkin
43 | roscpp
44 | rospy
45 | std_msgs
46 | unitree_legged_msgs
47 | roscpp
48 | rospy
49 | std_msgs
50 | unitree_legged_msgs
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/a1_cpp/src/A1BasicEKF.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by shuoy on 11/1/21.
3 | //
4 |
5 | #include "A1BasicEKF.h"
6 |
7 | A1BasicEKF::A1BasicEKF () {
8 | // constructor
9 | eye3.setIdentity();
10 | // C is fixed
11 | C.setZero();
12 | for (int i=0; i(i*3,0) = -eye3; //-pos
14 | C.block<3,3>(i*3,6+i*3) = eye3; //foot pos
15 | C.block<3,3>(NUM_LEG*3+i*3,3) = eye3; // vel
16 | C(NUM_LEG*6+i,6+i*3+2) = 1; // height z of foot
17 | }
18 |
19 | // Q R are fixed
20 | Q.setIdentity();
21 | Q.block<3,3>(0,0) = PROCESS_NOISE_PIMU*eye3; // position transition
22 | Q.block<3,3>(3,3) = PROCESS_NOISE_VIMU*eye3; // velocity transition
23 | for (int i=0; i(6+i*3,6+i*3) = PROCESS_NOISE_PFOOT*eye3; // foot position transition
25 | }
26 |
27 | R.setIdentity();
28 | for (int i=0; i(i*3,i*3) = SENSOR_NOISE_PIMU_REL_FOOT*eye3; // fk estimation
30 | R.block<3,3>(NUM_LEG*3+i*3,NUM_LEG*3+i*3) = SENSOR_NOISE_VIMU_REL_FOOT*eye3; // vel estimation
31 | R(NUM_LEG*6+i,NUM_LEG*6+i) = SENSOR_NOISE_ZFOOT; // height z estimation
32 | }
33 |
34 | // set A to identity
35 | A.setIdentity();
36 |
37 | // set B to zero
38 | B.setZero();
39 |
40 | assume_flat_ground = true;
41 |
42 | }
43 |
44 | A1BasicEKF::A1BasicEKF (bool assume_flat_ground_):A1BasicEKF() {
45 | // constructor
46 | assume_flat_ground = assume_flat_ground_;
47 | // change R according to this flag, if we do not assume the robot moves on flat ground,
48 | // then we cannot infer height z using this way
49 | if (assume_flat_ground == false) {
50 | for (int i=0; i(0) = Eigen::Vector3d(0, 0, 0.09);
64 | for (int i = 0; i < NUM_LEG; ++i) {
65 | Eigen::Vector3d fk_pos = state.foot_pos_rel.block<3, 1>(0, i);
66 | x.segment<3>(6 + i * 3) = state.root_rot_mat * fk_pos + x.segment<3>(0);
67 | }
68 | }
69 |
70 | void A1BasicEKF::update_estimation(A1CtrlStates& state, double dt) {
71 | // update A B using latest dt
72 | A.block<3, 3>(0, 3) = dt * eye3;
73 | B.block<3, 3>(3, 0) = dt * eye3;
74 |
75 | // control input u is Ra + ag
76 | Eigen::Vector3d u = state.root_rot_mat * state.imu_acc + Eigen::Vector3d(0, 0, -9.81);
77 |
78 | // contact estimation, do something very simple first
79 | if (state.movement_mode == 0) { // stand
80 | for (int i = 0; i < NUM_LEG; ++i) estimated_contacts[i] = 1.0;
81 | } else { // walk
82 | for (int i = 0; i < NUM_LEG; ++i) {
83 | estimated_contacts[i] = std::min(std::max((state.foot_force(i)) / (100.0 - 0.0), 0.0), 1.0);
84 | // estimated_contacts[i] = 1.0/(1.0+std::exp(-(state.foot_force(i)-100)));
85 | }
86 | }
87 | // update Q
88 | Q.block<3, 3>(0, 0) = PROCESS_NOISE_PIMU * dt / 20.0 * eye3;
89 | Q.block<3, 3>(3, 3) = PROCESS_NOISE_VIMU * dt * 9.8 / 20.0 * eye3;
90 | // update Q R for legs not in contact
91 | for (int i = 0; i < NUM_LEG; ++i) {
92 | Q.block<3, 3>(6 + i * 3, 6 + i * 3)
93 | =
94 | (1 + (1 - estimated_contacts[i]) * 1e3) * dt * PROCESS_NOISE_PFOOT * eye3; // foot position transition
95 | // for estimated_contacts[i] == 1, Q = 0.002
96 | // for estimated_contacts[i] == 0, Q = 1001*Q
97 |
98 | R.block<3, 3>(i * 3, i * 3)
99 | = (1 + (1 - estimated_contacts[i]) * 1e3) * SENSOR_NOISE_PIMU_REL_FOOT *
100 | eye3; // fk estimation
101 | R.block<3, 3>(NUM_LEG * 3 + i * 3, NUM_LEG * 3 + i * 3)
102 | = (1 + (1 - estimated_contacts[i]) * 1e3) * SENSOR_NOISE_VIMU_REL_FOOT * eye3; // vel estimation
103 | if (assume_flat_ground) {
104 | R(NUM_LEG * 6 + i, NUM_LEG * 6 + i)
105 | = (1 + (1 - estimated_contacts[i]) * 1e3) * SENSOR_NOISE_ZFOOT; // height z estimation
106 | }
107 | }
108 |
109 |
110 | // process update
111 | xbar = A*x + B*u ;
112 | Pbar = A * P * A.transpose() + Q;
113 |
114 | // measurement construction
115 | yhat = C*xbar;
116 | // leg_v = (-J_rf*av-skew(omega)*p_rf);
117 | // r((i-1)*3+1:(i-1)*3+3) = body_v - R_er*leg_v;
118 | // actual measurement
119 | for (int i=0; i(0,i);
121 | y.block<3,1>(i*3,0) = state.root_rot_mat*fk_pos; // fk estimation
122 | Eigen::Vector3d leg_v = -state.foot_vel_rel.block<3,1>(0,i) - Utils::skew(state.imu_ang_vel)*fk_pos;
123 | y.block<3,1>(NUM_LEG*3+i*3,0) =
124 | (1.0-estimated_contacts[i])*x.segment<3>(3) + estimated_contacts[i]*state.root_rot_mat*leg_v; // vel estimation
125 |
126 | y(NUM_LEG*6+i) =
127 | (1.0-estimated_contacts[i])*(x(2)+fk_pos(2)) + estimated_contacts[i]*0; // height z estimation
128 | }
129 |
130 | S = C * Pbar *C.transpose() + R;
131 | S = 0.5*(S+S.transpose());
132 |
133 | error_y = y - yhat;
134 | Serror_y = S.fullPivHouseholderQr().solve(error_y);
135 |
136 | x = xbar + Pbar * C.transpose() * Serror_y;
137 |
138 | SC = S.fullPivHouseholderQr().solve(C);
139 | P = Pbar - Pbar * C.transpose() * SC * Pbar;
140 | P = 0.5 * (P + P.transpose());
141 |
142 | // reduce position drift
143 | if (P.block<2, 2>(0, 0).determinant() > 1e-6) {
144 | P.block<2, 16>(0, 2).setZero();
145 | P.block<16, 2>(2, 0).setZero();
146 | P.block<2, 2>(0, 0) /= 10.0;
147 | }
148 |
149 | // final step
150 | // put estimated values back to A1CtrlStates& state
151 | for (int i = 0; i < NUM_LEG; ++i) {
152 | if (estimated_contacts[i] < 0.5) {
153 | state.estimated_contacts[i] = false;
154 | } else {
155 | state.estimated_contacts[i] = true;
156 | }
157 | }
158 | // std::cout << x.transpose() <(0);
160 | state.estimated_root_vel = x.segment<3>(3);
161 |
162 | state.root_pos = x.segment<3>(0);
163 | state.root_lin_vel = x.segment<3>(3);
164 | }
--------------------------------------------------------------------------------
/src/a1_cpp/src/A1BasicEKF.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by shuoy on 11/1/21.
3 | //
4 |
5 | #ifndef A1_CPP_A1BASICEKF_H
6 | #define A1_CPP_A1BASICEKF_H
7 |
8 | #include "A1Params.h"
9 | #include "A1CtrlStates.h"
10 | #include "utils/Utils.h"
11 |
12 |
13 | // state estimator parameters
14 | #define STATE_SIZE 18
15 | #define MEAS_SIZE 28
16 | #define PROCESS_NOISE_PIMU 0.01
17 | #define PROCESS_NOISE_VIMU 0.01
18 | #define PROCESS_NOISE_PFOOT 0.01
19 | #define SENSOR_NOISE_PIMU_REL_FOOT 0.001
20 | #define SENSOR_NOISE_VIMU_REL_FOOT 0.1
21 | #define SENSOR_NOISE_ZFOOT 0.001
22 |
23 | // implement a basic error state KF to estimate robot pose
24 | // assume orientation is known from a IMU (state.root_rot_mat)
25 | class A1BasicEKF {
26 | public:
27 | A1BasicEKF ();
28 | A1BasicEKF (bool assume_flat_ground_);
29 | void init_state(A1CtrlStates& state);
30 | void update_estimation(A1CtrlStates& state, double dt);
31 | bool is_inited() {return filter_initialized;}
32 | private:
33 | bool filter_initialized = false;
34 | // state
35 | // 0 1 2 pos 3 4 5 vel 6 7 8 foot pos FL 9 10 11 foot pos FR 12 13 14 foot pos RL 15 16 17 foot pos RR
36 | Eigen::Matrix x; // estimation state
37 | Eigen::Matrix xbar; // estimation state after process update
38 | Eigen::Matrix P; // estimation state covariance
39 | Eigen::Matrix Pbar; // estimation state covariance after process update
40 | Eigen::Matrix A; // estimation state transition
41 | Eigen::Matrix B; // estimation state transition
42 | Eigen::Matrix Q; // estimation state transition noise
43 |
44 | // observation
45 | // 0 1 2 FL pos residual
46 | // 3 4 5 FR pos residual
47 | // 6 7 8 RL pos residual
48 | // 9 10 11 RR pos residual
49 | // 12 13 14 vel residual from FL
50 | // 15 16 17 vel residual from FR
51 | // 18 19 20 vel residual from RL
52 | // 21 22 23 vel residual from RR
53 | // 24 25 26 27 foot height
54 | Eigen::Matrix y; // observation
55 | Eigen::Matrix yhat; // estimated observation
56 | Eigen::Matrix error_y; // estimated observation
57 | Eigen::Matrix Serror_y; // S^-1*error_y
58 | Eigen::Matrix C; // estimation state observation
59 | Eigen::Matrix SC; // S^-1*C
60 | Eigen::Matrix R; // estimation state observation noise
61 | // helper matrices
62 | Eigen::Matrix eye3; // 3x3 identity
63 | Eigen::Matrix S; // Innovation (or pre-fit residual) covariance
64 | Eigen::Matrix K; // kalman gain
65 |
66 |
67 | bool assume_flat_ground = false;
68 |
69 | // variables to process foot force
70 | double smooth_foot_force[4];
71 | double estimated_contacts[4];
72 | };
73 |
74 |
75 | #endif //A1_CPP_A1BASICEKF_H
76 |
--------------------------------------------------------------------------------
/src/a1_cpp/src/A1Params.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by shuoy on 10/18/21.
3 | //
4 |
5 | #ifndef A1_CPP_A1PARAMS_H
6 | #define A1_CPP_A1PARAMS_H
7 |
8 | // control time related
9 | //#define CTRL_FREQUENCY 2.5 // ms
10 | #define GRF_UPDATE_FREQUENCY 0.5 // ms
11 | #define MAIN_UPDATE_FREQUENCY 0.5 // ms
12 | #define HARDWARE_FEEDBACK_FREQUENCY 1.0 // ms
13 |
14 | // constant define
15 | // joy stick command interprate
16 | #define JOY_CMD_BODY_HEIGHT_MAX 0.32 // m
17 | #define JOY_CMD_BODY_HEIGHT_MIN 0.1 // m
18 | #define JOY_CMD_BODY_HEIGHT_VEL 0.04 // m/s
19 | #define JOY_CMD_VELX_MAX 0.6 // m/s
20 | #define JOY_CMD_VELY_MAX 0.3 // m/s
21 | #define JOY_CMD_YAW_MAX 0.8 // rad
22 | #define JOY_CMD_PITCH_MAX 0.4 // rad
23 | #define JOY_CMD_ROLL_MAX 0.4 // rad
24 |
25 | // mpc
26 | #define PLAN_HORIZON 10
27 | #define MPC_STATE_DIM 13
28 | #define MPC_CONSTRAINT_DIM 20
29 |
30 | // robot constant
31 | #define NUM_LEG 4
32 | #define NUM_DOF_PER_LEG 3
33 | #define DIM_GRF 12
34 | #define NUM_DOF 12
35 |
36 | #define LOWER_LEG_LENGTH 0.21
37 |
38 | #define FOOT_FORCE_LOW 30.0
39 | #define FOOT_FORCE_HIGH 80.0
40 |
41 | #define FOOT_SWING_CLEARANCE1 0.0f
42 | #define FOOT_SWING_CLEARANCE2 0.4f
43 |
44 | #define FOOT_DELTA_X_LIMIT 0.1
45 | #define FOOT_DELTA_Y_LIMIT 0.1
46 |
47 | #define ERROR_CURVE_ALREADY_SET 184
48 | #define ERROR_CURVE_NOT_SET 185
49 |
50 | #endif //A1_CPP_A1PARAMS_H
51 |
--------------------------------------------------------------------------------
/src/a1_cpp/src/A1RobotControl.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by shuoy on 10/19/21.
3 | //
4 |
5 | #ifndef A1_CPP_A1ROBOTCONTROL_H
6 | #define A1_CPP_A1ROBOTCONTROL_H
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | // to debug
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | // osqp-eigen
21 | #include "OsqpEigen/OsqpEigen.h"
22 | #include
23 |
24 | #include "A1Params.h"
25 | #include "A1CtrlStates.h"
26 | #include "utils/Utils.h"
27 | #include "ConvexMpc.h"
28 |
29 | #include "utils/filter.hpp"
30 |
31 |
32 | class A1RobotControl {
33 | public:
34 | A1RobotControl();
35 |
36 | A1RobotControl(ros::NodeHandle &_nh);
37 |
38 | void update_plan(A1CtrlStates &state, double dt);
39 |
40 | void generate_swing_legs_ctrl(A1CtrlStates &state, double dt);
41 |
42 | void compute_joint_torques(A1CtrlStates &state);
43 |
44 | Eigen::Matrix compute_grf(A1CtrlStates &state, double dt);
45 |
46 | Eigen::Vector3d compute_walking_surface(A1CtrlStates &state);
47 |
48 | private:
49 | BezierUtils bezierUtils[NUM_LEG];
50 |
51 | Eigen::Matrix root_acc;
52 | // allocate the problem weight matrices
53 | Eigen::DiagonalMatrix Q;
54 | double R;
55 | // ground friction coefficient
56 | double mu;
57 | double F_min;
58 | double F_max;
59 | // allocate QP problem matrices and vectors
60 | Eigen::SparseMatrix hessian;
61 | Eigen::VectorXd gradient;
62 | Eigen::SparseMatrix linearMatrix;
63 | Eigen::VectorXd lowerBound;
64 | Eigen::VectorXd upperBound;
65 |
66 |
67 | OsqpEigen::Solver solver;
68 |
69 | //add a number of ROS debug topics
70 | ros::NodeHandle nh;
71 | ros::Publisher pub_foot_start[NUM_LEG];
72 | ros::Publisher pub_foot_end[NUM_LEG];
73 | ros::Publisher pub_foot_path[NUM_LEG];
74 | visualization_msgs::Marker foot_start_marker[NUM_LEG];
75 | visualization_msgs::Marker foot_end_marker[NUM_LEG];
76 | visualization_msgs::Marker foot_path_marker[NUM_LEG];
77 |
78 | //debug topics
79 | // ros::Publisher pub_root_lin_vel;
80 | // ros::Publisher pub_root_lin_vel_d;
81 | ros::Publisher pub_terrain_angle;
82 |
83 | ros::Publisher pub_foot_pose_target_FL;
84 | ros::Publisher pub_foot_pose_target_FR;
85 | ros::Publisher pub_foot_pose_target_RL;
86 | ros::Publisher pub_foot_pose_target_RR;
87 |
88 | ros::Publisher pub_foot_pose_target_rel_FL;
89 | ros::Publisher pub_foot_pose_target_rel_FR;
90 | ros::Publisher pub_foot_pose_target_rel_RL;
91 | ros::Publisher pub_foot_pose_target_rel_RR;
92 |
93 | ros::Publisher pub_foot_pose_error_FL;
94 | ros::Publisher pub_foot_pose_error_FR;
95 | ros::Publisher pub_foot_pose_error_RL;
96 | ros::Publisher pub_foot_pose_error_RR;
97 |
98 | ros::Publisher pub_euler;
99 |
100 | //MPC does not start for the first 10 ticks to prevent uninitialized NAN goes into joint_torques
101 | int mpc_init_counter;
102 |
103 | std::string use_sim_time;
104 |
105 | // filters
106 | MovingWindowFilter terrain_angle_filter;
107 | MovingWindowFilter recent_contact_x_filter[NUM_LEG];
108 | MovingWindowFilter recent_contact_y_filter[NUM_LEG];
109 | MovingWindowFilter recent_contact_z_filter[NUM_LEG];
110 | };
111 |
112 |
113 | #endif //A1_CPP_A1ROBOTCONTROL_H
114 |
--------------------------------------------------------------------------------
/src/a1_cpp/src/ConvexMpc.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by zixin on 12/09/21.
3 | //
4 |
5 | #ifndef A1_CPP_CONVEXMPC_H
6 | #define A1_CPP_CONVEXMPC_H
7 |
8 | #define EIGEN_STACK_ALLOCATION_LIMIT 0
9 |
10 | #include
11 | #include
12 |
13 | #include "OsqpEigen/OsqpEigen.h"
14 | #include
15 | #include
16 | #include
17 |
18 | #include "A1CtrlStates.h"
19 | #include "A1Params.h"
20 | #include "utils/Utils.h"
21 |
22 | class ConvexMpc {
23 | public:
24 | ConvexMpc(Eigen::VectorXd &q_weights_, Eigen::VectorXd &r_weights_);
25 |
26 | void reset();
27 |
28 | void calculate_A_mat_c(Eigen::Vector3d root_euler);
29 |
30 | void calculate_B_mat_c(double robot_mass, const Eigen::Matrix3d &a1_trunk_inertia, Eigen::Matrix3d root_rot_mat,
31 | Eigen::Matrix foot_pos);
32 |
33 | void state_space_discretization(double dt);
34 |
35 | void calculate_qp_mats(A1CtrlStates &state);
36 |
37 | //private:
38 | // parameters initialized with class ConvexMpc
39 | double mu;
40 | double fz_min;
41 | double fz_max;
42 |
43 | // Eigen::VectorXd q_weights_mpc; // (state_dim * horizon) x 1
44 | // Eigen::VectorXd r_weights_mpc; // (action_dim * horizon) x 1
45 | Eigen::Matrix q_weights_mpc;
46 | Eigen::Matrix r_weights_mpc;
47 |
48 | Eigen::DiagonalMatrix Q;
49 | Eigen::DiagonalMatrix R;
50 | Eigen::SparseMatrix Q_sparse;
51 | Eigen::SparseMatrix R_sparse;
52 | // Eigen::Matrix Q;
53 | // Eigen::Matrix R;
54 |
55 | // parameters initialized in the function reset()
56 | // Eigen::MatrixXd A_mat_c;
57 | // Eigen::MatrixXd B_mat_c;
58 | // Eigen::MatrixXd AB_mat_c;
59 | //
60 | // Eigen::MatrixXd A_mat_d;
61 | // Eigen::MatrixXd B_mat_d;
62 | // Eigen::MatrixXd AB_mat_d;
63 | //
64 | // Eigen::MatrixXd A_qp;
65 | // Eigen::MatrixXd B_qp;
66 |
67 | Eigen::Matrix A_mat_c;
68 | Eigen::Matrix B_mat_c;
69 | Eigen::Matrix B_mat_c_list;
70 | Eigen::Matrix AB_mat_c;
71 |
72 | Eigen::Matrix A_mat_d;
73 | Eigen::Matrix B_mat_d;
74 | Eigen::Matrix B_mat_d_list;
75 | Eigen::Matrix AB_mat_d;
76 |
77 | Eigen::Matrix A_qp;
78 | Eigen::Matrix B_qp;
79 | Eigen::SparseMatrix A_qp_sparse;
80 | Eigen::SparseMatrix B_qp_sparse;
81 |
82 | // standard QP formulation
83 | // minimize 1/2 * x' * P * x + q' * x
84 | // subject to lb <= Ac * x <= ub
85 | Eigen::SparseMatrix hessian; // P
86 | // Eigen::VectorXd gradient; // q
87 | Eigen::SparseMatrix linear_constraints; // Ac
88 | // Eigen::VectorXd lb;
89 | // Eigen::VectorXd ub;
90 | Eigen::Matrix gradient; // q
91 | Eigen::Matrix lb;
92 | Eigen::Matrix ub;
93 |
94 | };
95 |
96 | #endif //A1_CPP_CONVEXMPC_H
97 |
--------------------------------------------------------------------------------
/src/a1_cpp/src/GazeboA1ROS.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by zixin on 11/1/21.
3 | //
4 |
5 | #ifndef A1_CPP_GAZEBOA1ROS_H
6 | #define A1_CPP_GAZEBOA1ROS_H
7 |
8 | // std
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include