ros_control
ros_controlは何?何に使う?
ROSは応用層(APP)に汎用性を持たせるため、応用層と物理層の間に制御層を作れるようにros_controlのワークフレームを提供してくれた。提供されたインターフェース、controllerツールなどを使えば、より柔軟的な作り方ができるようになった。
※ハード制御のアーム側、若しくは車体側はROS hardware interfacesを入れないといけないけど。
これで何がいいの?(個人的な感想)
・移植しやすい、変更しやすい。物理層を変更しても、応用層を変えずにControl階層のIFを変えればほぼそのまま動かせるイメージ。
・システムの階層分けによって、仕様がよりシンプルにわかりやすくなる、作りやすい。
・分業しやすい。階層間の受け渡しデーターの内容を決めてしまえば、干渉なく作業ができそう。
・Gazeboでシミュレーションしやすい
ROS Contorlのデーターフロー(イメージ)
データーフローの中は下記階層が含まれる
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
複数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
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で試作し勉強する。