gazebo入门_Gazebo仿真控制中,有哪些你不知道的秘密?
生活随笔
收集整理的這篇文章主要介紹了
gazebo入门_Gazebo仿真控制中,有哪些你不知道的秘密?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
大家好,我是(月更俠)小明,很高興我們又見面啦。相信大家從我之前的文章中能看出來,我所講的內容基本都面向ROS新人,因為大家剛入門時,往往很難一窺程序的深層運行邏輯,使得許多問題遲遲無法解決,甚是耽誤時間。例如在和小伙伴們日常交流時,就反復遇到過一些關于Gazebo仿真控制的“經典”問題:A 我的模型一直抖動,怎么辦?B PID參數該怎么設置啊?我怎么調都沒用!C 我必須要設置PID參數嗎?如果不設置會怎么樣D gazebo_ros_control插件可以完成計算力矩控制等更加復雜的控制策略嗎?E 我的并聯機器人模型只能用sdf創建,可以使用gazebo_ros_control進行控制嗎?......通過本篇文章的分析,我們將揭曉這些問題的答案。在Gazebo仿真中,我們最常使用的控制插件就是是gazebo_ros_control,它是ros_control針對Gazebo仿真開發的插件。圖 1 ros_control組成概覽,其中左上角方框內就是gazebo_ros_control插件所實現的功能該插件的詳細使用方法,可參考古月居ROS探索總結系列的相關文章。簡單來說,就是進行了如下三個操作:在機器人模型的URDF文件中,添加gazebo_ros_control插件,并添加transmission指明了各關節控制器的類型信息 建立一個yaml文件,用來定義各控制器的pid參數 建立一個roslaunch,用來加載模型、控制參數、控制器,并發布tf 1、文件結構接下來我們來看看gazebo_ros_control功能包究竟對這些文件做了什么。需要注意,gazebo_ros_control源碼已經集成到了github帳號ros-simulation下的gazebo_ros_pkgs項目中,而ros_controls賬號下的gazebo_ros_pkgs是舊版本,現在已經不再使用了。該功能包的核心是硬件接口文件src/default_robot_hw_sim.cpp,該文件定義了以下函數,用以實現相應功能:clamp():區間限定函數,用以規范某些變量的上下限DefaultRobotHWSim::initSim():初始化插件的各項屬性DefaultRobotHWSim::readSim():從Gazebo仿真器中讀取模型的信息和狀態DefaultRobotHWSim::writeSim():將目標值寫入Gazebo仿真器中下面我們分析幾個重點函數。DefaultRobotHWSim::initSim()函數初始化了整個插件,首先處理了URDF文件中transmissions模塊信息,主要是以下方面:
- 定義了機器人的自由度數
- 從transmissions中獲取各個關節接口類型,名稱
- 判斷是否使用PID控制,如果沒有設置PID參數,則視為不使用PID
- 從gazebo模型中獲取關節名稱,并實例化各關節
- 為各個關節gazebo模型的行程設置上下限
- 從gazebo仿真器中讀取個關節的當前狀態
- 根據控制器類型將控制量寫入仿真器
①力控制
力控制十分簡單,直接將目標量寫入了仿真器,其中SetForce()函數是Gazebo仿真器自帶的關節力設置函數。case EFFORT:{ const double effort = e_stop_active_ ? 0 : joint_effort_command_[j]; sim_joints_[j]->SetForce(0, effort);}break;②PID位置控制PID位置控制稍顯復雜,首先計算當前狀態下的位置誤差error,其中對于REVOLUTE(轉動副)類型的關節,還要考慮關節限位。再利用pid_controllers下的computeCommand()方法計算當前誤差下應當施加到關節上的力,并使用區間限定函數clamp()來規范力的上下限。從此處可以看出,gazebo_ros_control插件實際上使用了輸入力的PID位置控制,該方法的原理可見我在古月居發表的《PID控制是個啥?ROS實驗讓你恍然大悟》。最后,利用SetForce()函數將目標量寫入了仿真器。case POSITION_PID:{ double error; switch (joint_types_[j]) { case urdf::Joint::REVOLUTE: angles::shortest_angular_distance_with_limits(joint_position_[j], joint_position_command_[j], joint_lower_limits_[j], joint_upper_limits_[j], error); break; case urdf::Joint::CONTINUOUS: error = angles::shortest_angular_distance(joint_position_[j], joint_position_command_[j]); break; default: error = joint_position_command_[j] - joint_position_[j]; } const double effort_limit = joint_effort_limits_[j]; const double effort = clamp(pid_controllers_[j].computeCommand(error, period), -effort_limit, effort_limit); sim_joints_[j]->SetForce(0, effort);}break;③PID速度控制PID速度控制函數和PID位置控制函數的邏輯完全一致,唯一的區別是誤差error取的是速度誤差。case?VELOCITY_PID: double error; if (e_stop_active_) error = -joint_velocity_[j]; else error = joint_velocity_command_[j] - joint_velocity_[j]; const double effort_limit = joint_effort_limits_[j]; const double effort = clamp(pid_controllers_[j].computeCommand(error, period), -effort_limit, effort_limit); sim_joints_[j]->SetForce(0, effort); break;④非PID的位置控制和速度控制如果不使用PID控制,那么硬件會直接調用Gazebo的SetPosition()和SetVelocity()接口,強行設置關節的位置和速度,而非通過輸入力的方式進行控制。代碼分別位于320行到330行,以及359行到372行。3、答案揭曉根據源碼的分析,我們在Gazebo仿真中的很多“萬年難題”就迎刃而解啦!例如:A 我的模型在仿真時一直抖動,怎么辦?答:在保證模型慣量屬性、關節摩擦、阻尼合理的前提下,調整PID參數。從源碼看到,控制器的PID控制實際上是輸入力的PID控制,模型物理屬性不符合真實情況、PID參數不合理必然導致關節振蕩。這也提醒我們,良好的Gazebo仿真,其前提是真實的物理模型和合理的理論推導。務必不要將其當做純動畫制作軟件!圖2 圖3 由于質量屬性\PID參數不合理,機械臂發生了細微的或鬼畜般的抖動。B PID參數該怎么設置啊?我怎么調都沒用!答:自己努力吧孩子!還是如上一個問題所述,在仿真之前,先進行完整的控制理論推導,而非隨便嘗試。提供兩個小技巧:動態配置插件Dynamic Reconfigure可以方便地動態調整PID參數,如圖。另外尤其要注意一個問題:gazebo_ros_control對于PID中的積分增益i是默認鎖定為0的,要想使用積分控制,需要在yaml文件中打開積分增益的上下限,否則無論怎么調積分增益都沒有用的(坑...)。 # pid增益的正確配置姿勢(如要使用積分控制,必須打開積分增益的上下限,否則默認均為0)joint1_position_controller: type: effort_controllers/JointPositionController joint: joint_1 pid: {p: 100.0, i: 1.0, d: 10.0, ,i_clamp_max: 0.0, i_clamp_max: 1.0}圖4 PID參數動態配置插件Dynamic ReconfigureC 我必須要設置PID參數嗎?如果不設置會怎么樣答:不是必要的,但推薦在yaml中設置PID參數。從源碼中可以看到,gazebo_ros_control插件會自動判斷用戶是否在yaml文件中設置了PID參數。如果沒有,當用戶使用位置控制和速度控制時,就會調用Gazebo默認的位置和速度設置接口。而根據注釋信息可以看到,如果你的Gazebo版本小于9,這樣做就是有壞處的:仿真器不會模擬模型的重力,會導致動力學仿真異常。因此,我們最好還是在yaml文件中設置合理的PID參數。ROS_WARN_ONCE("The default_robot_hw_sim plugin is using the Joint::SetPosition method without preserving the link velocity.");ROS_WARN_ONCE("As a result, gravity will not be simulated correctly for your model.");ROS_WARN_ONCE("Please set gazebo_pid parameters, switch to the VelocityJointInterface or EffortJointInterface, or upgrade to Gazebo 9.");ROS_WARN_ONCE("For details, see https://github.com/ros-simulation/gazebo_ros_pkgs/issues/612");圖5 在gazebo9以前的版本中,一只手由于沒有設置PID參數導致重力異常,懸浮在空中。D gazebo_ros_control插件可以完成計算力矩控制等更加復雜的控制策略嗎?答:需要基于插件的自定義接口自己編寫程序。從源碼中看到,插件所提供的控制策略只有基本的PID控制,其輸入量的計算只考慮了誤差,并沒有考慮任何動力學模型。詳見control_toolbox項目下的src/pid.cpp文件。E 我的并聯機器人模型只能用sdf創建,可以使用gazebo_ros_control進行控制嗎?答:不可以。從源碼看出,控制器類型等相關信息必須從urdf下的transmissions獲取,甚至在注冊關節限位時也使用了urdf類,而并沒有支持sdf格式。不過,由于sdf是Gazebo默認的支持格式,有完整的官方文檔提供,因此根據gazebo_ros_control的邏輯重新創建一個適用于sdf的控制插件其實并不困難。圖6 筆者利用sdf創建的六自由度并聯機器人,使用自定義Gazebo控制插件以上就是我們從源碼中找到的答案,有沒有解決你的一些疑惑呢?如果你還想進一步交流,歡迎登錄古月居網站,到這篇文章下給我留言,用戶名也是小明工坊。微信公眾號留言也可,但我需要拜托小編幫助回復,不能保證時效性。本次分享就到這里啦,期待我們下一次見面~古月居原創作者簽約計劃已開啟,網站(guyuehome.com)已上線【投稿】功能,歡迎大家積極投稿,原創優質文章作者將有機會成為古月居簽約作者。
MoveIt編程入門
課程特價倒計時
掃碼查看→
戳下方原文閱讀查看課程總結
以上是生活随笔為你收集整理的gazebo入门_Gazebo仿真控制中,有哪些你不知道的秘密?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hashmap应用场景_Redis 5种
- 下一篇: python对象三个特性_百度资讯搜索_