A1 Driver v2.8
==============

A1 is intended mostly for academic community. Unitree Robotics has
provided an
`SDK <https://github.com/unitreerobotics/unitree_legged_sdk>`__ for
their robots in C++ and a demo is also provided in
`ROS <https://github.com/unitreerobotics/unitree_ros>`__. But this ROS
driver lacks several ROS features. To cover them this driver is provided.

Requirements
------------

This driver requires a system setup with ROS. It is recommended to use
Ubuntu 18.04 with ROS melodic, however using Ubuntu 16.04 with ROS
kinetic should also work.

To make sure that robot control isn't affected by system latencies, it
is highly recommended to connect the robot via lan. The driver should
run intially on remote PC but can also be run on Rasberry Pi/Nvidia
board on robot.

Building
--------

The ROS driver for Quadruped robot is dependent upon following packages:

-  `ROS Melodic <http://wiki.ros.org/melodic/Installation/Ubuntu>`__ or
   `ROS
   Kinetic <http://wiki.ros.org/kinetic/Installation/Ubuntu>`__\ (has
   not been tested)
-  `Gazebo8 <http://gazebosim.org/tutorials?cat=install%EF%BC%89&tut=install_ubuntu&ver=8.0>`__
-  `unitree\_legged\_sdk <https://github.com/unitreerobotics/unitree_legged_sdk>`__
-  `aliengo\_sdk <https://github.com/unitreerobotics/aliengo_sdk>`__

Furthermore ``unitree_legged_sdk`` and ``aliengo_sdk`` have following
dependencies.

-  `Boost <http://www.boost.org>`__ (version 1.5.4 or higher)
-  `CMake <http://www.cmake.org>`__ (version 2.8.3 or higher)
-  `LCM <https://lcm-proj.github.io>`__ (version 1.4.0 or higher)

.. attention:: 
    It is important to check your CPU type via executing ``lscpu`` in the terminal. If you have ``Architecture:x86_64`` then nothing is to be changed,
    if you have ``Architecture:aarch64`` then in the ``utils/qre_unitree_envs.bash``, you must change it to the cpu from ``amd64`` to ``arm64``.

A script can be found below for automatic installation of all the required dependencies mentioned above and the provided software installation.
After downloading and changing directory to the downloaded folder, installation script can be run by the following command:

.. note:: `A1 installation script download <https://my.hidrive.com/share/fadwhxdkkc>`__

You first have to give the script root permission via:

.. code:: bash

    sudo chmod +x a1_installation_script.bash

.. code:: bash

    ./a1_installation_script.bash

Alternatively user can follow the procesure below to install all the dependencies and required software manually.

.. Warning::
    Please do not follow the installation guidelienes below for building the software, if you have executed the above mentioned installation script.

So now let's start installing the dependencies one by one.

To install Boost run the following command

.. code:: bash

    sudo apt install libboost-all-dev

CMake can be installed by the following command:

.. code:: bash

    sudo apt install cmake

To install ``LCM``, download the latest version
`here <https://github.com/lcm-proj/lcm/releases>`__. Unzip the file and
change directory to the LCM folder you just downloaded. Follow the steps
below:

.. code:: bash

    cd ~/lcm
    mkdir build
    cd build
    cmake ../
    make
    sudo make install

To install ``unitree_legged_sdk``:

.. code:: bash

    git clone https://github.com/unitreerobotics/unitree_legged_sdk ~/unitree_legged_sdk
    cd ~/unitree_legged_sdk
    mkdir build
    cd build
    cmake ../
    make

To install ``aliengo_sdk``:

.. code:: bash

    git clone https://github.com/unitreerobotics/aliengo_sdk ~/aliengo_sdk
    cd ~/aliengo_sdk
    mkdir build
    cd build
    cmake ../
    make

Before installing ROS driver from Quadruped Robotics, we have to install
``unitree_legged_real``\ (This will be removed in future versions).

.. code:: bash

    source /opt/ros/$ROS_DISTRO/setup.bash
    # For ROS melodic Gazebo 9 is supported so here make sure to use your respective Gazebo version.
    source /usr/share/gazebo-9/setup.sh
    source ~/catkin_ws/devel/setup.bash
    export ROS_PACKAGE_PATH=~/catkin_ws:${ROS_PACKAGE_PATH}
    export GAZEBO_PLUGIN_PATH=~/catkin_ws/devel/lib:${GAZEBO_PLUGIN_PATH}
    export LD_LIBRARY_PATH=~/catkin_ws/devel/lib:${LD_LIBRARY_PATH}
    export UNITREE_LEGGED_SDK_PATH=~/unitree_legged_sdk
    export ALIENGO_SDK_PATH=~/aliengo_sdk
    # amd64, arm32, arm64
    export UNITREE_PLATFORM="amd64"
    sudo apt-get install ros-$ROS_DISTRO-controller-interface  ros-$ROS_DISTRO-gazebo-ros-control ros-$ROS_DISTRO-joint-state-controller ros-$ROS_DISTRO-effort-controllers ros-$ROS_DISTRO-joint-trajectory-controller
    mkdir -p ~/catkin_ws/src
    cd ~/catkin_ws
    git clone https://github.com/unitreerobotics/unitree_ros src/unitree_ros
    catkin build
    source devel/setup.bash

Now everything is installed(assuming ROS and Gazebo installed prior to
following this tutorial). The next step is to install ROS driver
provided by Quadruped Robotics.

To build the driver download the source code from `here <https://my.hidrive.com/share/m5erkbhd12>`__ and copy/paste it inside `catkin\_ws/src` and run the following commands:

.. code:: bash

    source /opt/ros/$ROS_DISTRO/setup.bash
    cd ~/catkin_ws && catkin build 
    source devel/setup.bash
    sudo apt update -qq
    rosdep update
    rosdep install --from-paths src --ignore-src -y
    catkin build 
    source devel/setup.bash

Software Overview
-----------------

Quadruped robots work in two modes:

1. High level mode
2. Low level mode

User can be in one of these modes and they can not be switched after
running.

High level mode
~~~~~~~~~~~~~~~

High level mode is mainly for walking and running. This mode too has two
modes normal and motion mode which can be distinguished from their
ips(For more details see Quadruped software guide). At the moment this
driver is working with default configuration.

In high level mode the robot can walk/run. To run the robot in high
level mode run the following command as root user(after turning on the
robot and connecting through lan, the robot will be standing):

.. code:: bash

    sudo su
    source ~/catkin_ws/devel/setup.bash
    roslaunch qre_ros high_level_mode.launch

With ``high_level_mode.launch`` *unitree\_legged\_real/real.launch*
launches a communication channel between the robot and remote PC. Then
later in *qre\_unitree\_ros/high\_level\_mode* a ROS node is run.

::

    Node [high_level_driver]

    Publications: state [unitree_legged_msgs/HighState]

    Subscriptions: cmd_vel [geometry_msgs/Twist]

    Services: set_body_pose [qre_msgs/SetBodyPose]

The robot pose can be set using the robot ``set_body_pose`` service.
Robot state is published in ``state`` topic. This message contains a lot
of information. For more information see `high state
message <https://github.com/unitreerobotics/unitree_ros_to_real/blob/master/unitree_legged_msgs/msg/HighState.msg>`__
message.

**Using the driver**

The node subscribes to ``cmd_vel`` topic. Here special attention needs
to be paid. As the robot is holonimic so different ``Twist`` message
fields determine different movement. A nice tool here would be
`teleop\_twist\_keyboard <http://wiki.ros.org/teleop_twist_keyboard>`__.
Here in the teleop holonomic and non holonomic modes can be used(Be
aware key strokes and their usage).

.. figure:: media/low/walk_and_squat.gif
   :width: 33%
   :align: center
   :alt: Body height and walking

   Body height and walking demo

Low level mode
~~~~~~~~~~~~~~

In this mode all the motors can be controlled directly. For that one
needs to first change the operation mode either to Servo mode or
Electronic brake mode. Low level mode has again three control modes:

1. Position
2. Velocity
3. Torque

In low level mode joint level control can be achieved. In Quadruped A1
this low level mode can be in three different levels i.e. Position,
Velocity, Torque. All three of them can be used with this driver by
publishing appropriate messages. Unlike high level mode robot
communication is achieved inside the driver node so no seperate node
should run.

After turning on the robot and connecting through lan run the following
command:

.. code:: bash

    sudo su
    source ~/catkin_ws/devel/setup.bash
    roslaunch qre_ros low_level_mode.launch

A node with follwoing information will be run:

::

    Node [low_level_driver]

    Publications: state [unitree_legged_msgs/LowState]
                  joint_states [sensor_msgs/JointState]

    Subscriptions: joint_cmd [qre_msgs/JointCMD]

    Services: set_body_pose [qre_msgs/SetBodyPose] -> Not implemented yet
              set_control [qre_msgs/SetControl]


.. image:: media/low/position_control.gif
    :width: 32.5%
    :alt:   PositionControl

.. image:: media/low/velocity_control_fast.gif
    :width: 32.5%
    :alt:   VelocityControlFast

.. image:: media/low/torque_control.gif
    :width: 32.5%
    :alt:   TorqueControl

.. raw:: html

    <table style="width:100%">
        <tr>
            <td> &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; Position control</td>
            <td> &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; Velocity control</td>
            <td> &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; Torque control</td>
        </tr>
    </table>

The node subscribes to ``joint_cmd`` topic. Again here special attention
to be paid as well for the joints. For joint sequence see
`qre\_msgs <https://my.hidrive.com/share/6kxgj8nox2>`__
README. The driver publishes two topics state topic pubslihes the
information from the robot. For more details see `low state
message <https://github.com/unitreerobotics/unitree_ros_to_real/blob/master/unitree_legged_msgs/msg/LowState.msg>`__.
Joint state messages are also published. ``set_control`` service is can
change the robot three modes namely i.e. Position, Velocity, Torque(Case
sensitive). For every control level here similar joint messages need to
be filled in ``joint_cmd`` topic other fields are not considered.

::

    Position -> JointCMD.q
                JointCMD.Kd
                JointCMD.Kd
    Velocity -> JointCMD.dq
                JointCMD.Kp
                JointCMD.Kd
    Torque   -> JointCMD.tau


**Using the driver**
    
For velocity and torque control communication can done easily by just publishing the respected values e.g. by using `rqt topic publisher <http://wiki.ros.org/rqt>`__, in terminal:

.. code:: bash

    rqt

For position control mode the same control can be used through ``rqt``, but to get smoother motions and communication a demo is provided for some predefined joint values. After running the ``low_level_driver.launch``, execute the following command:

.. code:: bash

    rosrun qre_ros llm_demo.py

.. figure:: media/low/position_control_example.gif
    :width: 33%
    :align: center
    :alt: PositionControlExample
 
    Low level position control demo with ROS