ROS勉強メモ ros_control

ros_control
=
ros_controlは何？何に使う？
ROSは応用層（APP）に汎用性を持たせるため、応用層と物理層の間に制御層を作れるようにros_controlのワークフレームを提供してくれた。提供されたインターフェース、controllerツールなどを使えば、より柔軟的な作り方ができるようになった。
※ハード制御のアーム側、若しくは車体側はROS hardware　interfacesを入れないといけないけど。

これで何がいいの？（個人的な感想）
・移植しやすい、変更しやすい。物理層を変更しても、応用層を変えずにControl階層のIFを変えればほぼそのまま動かせるイメージ。
・システムの階層分けによって、仕様がよりシンプルにわかりやすくなる、作りやすい。
・分業しやすい。階層間の受け渡しデーターの内容を決めてしまえば、干渉なく作業ができそう。
・Gazeboでシミュレーションしやすい

ROS Contorlの全体（イメージ）
![20200525134012468.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/3d550891-31f2-258c-5531-bde3083b5773.png)

ROS Contorlのデーターフロー（イメージ）
=
![20200525131825728.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/367e97a5-ac9e-43eb-3784-30acf8bec946.png)
データーフローの中は下記階層が含まれる
1.Controller Manager
複数のControllerを管理する、PKGからControllerに対して出している要求を処理、管理してくれる階層のイメージ。

2.Controller
ステータスに応じてJointに対して制御を行う

3.Hardware Resource
ControllerとHardwareのソフト的なIFを提供する階層

4.Hardware Inferface（RobotHW）
物理的に制御物に接続してくれるIF。USB、シリアル通信、TCPなどで制御側と制御される側を接続して、Write()、Read()にて交信して、最終的な制御を行う

5.Real Robot
実際制御される物理層。この中にRobotHWと交信できるWrite()、Read()を実装した上、最終的にモーター、アクチュエータなどを動かす役割を持っていると共に閉環ループ制御をできるように状態をFBできるセンサのセンサー値を返すように設ける必要がある。

Controller Manager
=
コマンド
~~~~~~~~~~~~~~
rosrun controller_manager controller_manager <command> <controller_name>
~~~~~~~~~~~~~~

使えるCommand
load
unload
start
stop
spawn: load & start
kill: stop & unload
![20200525135022843.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/1e8f3e9a-6602-df93-f851-41aa79eed917.png)

複数Controller管理のターミナルの場合
~~~~~~~~~~~~~~~~
# load，but non start
rosrun controller_manager spawner [--stopped] name1 name2 name3

# load & start
rosrun controller_manager spawner name1 name2 name3

# stop,but non unload
rosrun controller_manager unspawner name1 name2 name3
~~~~~~~~~~~~~~~~

Controllerの状態を確認する場合のターミナルのCommand
~~~~~~~~~~~~~~~~
rosrun controller_manager controller_manager <command>
~~~~~~~~~~~~~~~~
使えるCommand
list
list-types
reload-libraries
reload-libraries --restore

launchファイルに入れる場合
~~~~~~~~~~~~~~~~
<!--load & start-->
<launch>
    <node pkg="controller_manager" 
    type="spawner" 
    args="controller_name1 controller_name2" />
</launch>

<!--load but non start-->
<launch>
  <node pkg="controller_manager"
    type="spawner"
    args="--stopped controller_name1 controller_name2" />
</launch>
~~~~~~~~~~~~~~~~
可視化するコマンド
~~~~~~~~~~~~~~~~
rosrun rqt_controller_manager rqt_controller_manager
~~~~~~~~~~~~~~~~

Controller
=
![20200525134023487.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/26109dd0-4fa6-331f-d436-d2b036510b4a.png)

ROSは色んなControllerを用意している

インストール
~~~~~~~~~~~~~~~~~~~~~
sudo apt-get install ros-Noetic -ros-control ros-Noetic-ros-controllers
~~~~~~~~~~~~~~~~~~~~~

ROSが提供してくれているPKG
https://github.com/ros-controls/ros_controllers

effort_controllers：Jointコントローラー
joint_effort_controller
joint_position_controller
joint_velocity_controller

joint_state_controller：Joint状態コントローラー
joint_state_controller

position_controllers： Joint位置コントローラー
joint_position_controller
joint_group_position_controller

velocity_controllers： Joint速度コントローラー
joint_velocity_controller
joint_group_velocity_controller

joint_trajectory_controllers： 軌道コントローラー
position_controller
velocity_controller
effort_controller
position_velocity_controller
position_velocity_acceleration_controller

コントローラーは自作もできる。作り方はまた勉強メモを作るが、まず参照先をメモする
https://github.com/ros-controls/ros_control/wiki/controller_interface


Hardware IF
=
hardware_interface Namespace Reference（使えるIFのAPI）
http://docs.ros.org/melodic/api/hardware_interface/html/c++/namespacehardware__interface.html

Joint Command Interface - Jointの指令のIF
Effort Joint Interface - for commanding effort-based joints.
Velocity Joint Interface - for commanding velocity-based joints.
Position Joint Interface - for commanding position-based joints.
Joint State Interfaces - Jointの位置、速度などの情報を読み取るIF
Actuator State Interfaces - アクチュエータの位置、速度などの情報を読み取るIF
Actuator Command Interfaces - アクチュエータの指令のIF
などなど、、、

IF自作もできる。作り方はまた勉強メモを作るが、まず参照先をメモする
https://github.com/ros-controls/ros_control/wiki/hardware_interface

Transmissions
=
動かせるJointの場合、URDFファイル内に動きに関係する情報を追加しないといけない。
URDFの追加方法
~~~~~~~~~~~~~~~~~~~~~
<transmission name="simple_trans">
	 <!--タイプ指定-->
     <type>transmission_interface/SimpleTransmission</type>
	 <!--Joint-->
     <joint name="foo_joint">
     	  <!--Gazeboに入れる場合の値はEffortJointInterface-->
     	  <!--RobotHWに入れる場合の値はhardware_interface/EffortJointInterface-->
          <hardwareInterface>EffortJointInterface</hardwareInterface>
     </joint>
     <actuator name="foo_motor">
     	  <!--Opption，減速比-->
          <mechanicalReduction>50</mechanicalReduction>
          <!--Opption，HW IF指定-->
          <hardwareInterface>EffortJointInterface</hardwareInterface>
     </actuator>
</transmission>
~~~~~~~~~~~~~~~~~~~~~

Joint Limits
=
アクチュエータの場合、周りのものに当たるとかの問題を回避するため例えば、アームをある角度範囲内で動かしたい場合はあるよね。PID制御した結果が極端な値に行かないように値を拘束する場合も使える。HWを守るためのものかな。

URDFの場合
~~~~~~~~~~~~~~~~~~~~~
<joint name="$foo_joint" type="revolute">
  <!-- other joint description elements -->

  <!-- Joint limits -->
  <limit lower="0.0"
         upper="1.0"
         effort="10.0"
         velocity="5.0" />

  <!-- Soft limits -->
  <safety_controller k_position="100"
                     k_velocity="10"
                     soft_lower_limit="0.1"
                     soft_upper_limit="0.9" /> 
</joint>
~~~~~~~~~~~~~~~~~~~~~
YAMLの場合
~~~~~~~~~~~~~~~~~~~~~
joints_limits:
    foo_joint:
        has_position_limits: true
        min_position: 0.0
        max_position: 1.0
        has_velocity_limits: true
        max_velocity: 2.0
        has_acceleration_limits: true
        max_acceleration: 5.0
        has_jerk_limits: true
        max_jerk: 100.0
        has_effort_limits: true
        max_effort: 5.0
    bar_joint:
        has_position_limits: false
        has_velocity_limits: true
        max_velocity: 4.0
~~~~~~~~~~~~~~~~~~~~~
YAMLとURDF方式のメリット、デメリット、できることとできないことがあるようで、また勉強する。
Real RobotもまたAuduinoで試作し勉強する。

https://qiita.com/take4eng/items/527793c9a1f902a0a62c#2-ros%E4%BE%9D%E5%AD%98%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB