Hello,
I am running Ubuntu 16.04, with Ros Kinetic and Gazebo7 ver 7.16.
At present my physical robot can be viewed as a mobile base, and a custom 3-d lidar. The mobile base is controlled via a diff_drive controller. The node responsible for moving the lidar subscribes to the Twist command the diff_drive is receiving and moves the lidar system across the path of the robot. A single revolution of the lidar is measured via radians, with the front of the robot being 0 degrees. Every twist command is associated with “sweeping” between two radian places. Hopefully this old image during construction helps you visualize what I mean:
Recently I have come to realize that simulation (Gazebo) is very important (I’m a late bloomer). So I have modified my URDF, launch files, and so on to work with Gazebo. In Gazebo the robot drives around (using a diff_drive), and provides lidar data just like the physical robot. However I am having a hard time getting the lidar joint to work like the real unit.
I have used this answer (https://answers.ros.org/question/273947/moving-joints-in-gazebo-simple-example/) to get a joint to move in Gazebo via ros_control. I am able to get a joint to move with a fixed velocity or get a joint to “snap” into place. I say snap as the joint jumps from one position to another, it does not rotate from one position to another. Based on these circumstances I have two questions:
(1) At present I can use a velocity controller, monitor the position, and then stop at some desired point/position to mimic my physical system. Is there some other way?
(2) How do I write code that can run on both my physical machine and the Gazebo simulation? Any tips? I not really a software guy, so any advice is appreciated.
Thanks in advance.
EDIT #1
By encoder-motor joint I mean that the encoder data (current position) has a direct effect on the motion of the motor (the joint). In my case the motor behavior is defined inside the hardware (acceleration, speed of travel, etc...) so all my code has to do is figure out the current position (from encoder data) and where we need to go (new position based on Twist data), and give a single command to the motor controller (physical device) which then takes care of the motion (starting motion, direction, velocity, and stopping the motion). I was hoping to be able to use ros_control to do the same in Gazebo. Give the position to the joint, and have the joint move from where it is to the new position (which would allow the lidar to collect data during the motion).
Something to clear up for me now: you mention Twist, but then ask about a position controlled system. geometry_msgs/Twist encodes velocities, not positions. Could you clarify how this works in your system?
The Twist data is used for the diff_drive controller to drive the robot around. At the same time one of my lidar nodes subscribes to the topic on which the Twist message arrives, and based on the type of motion (drive straight, slight turn, rotate on the spot) the code determines the motion of the lidar. If robot is going straight the lidar sweeps directly in front, if robot is turning the lidar sweeps a bit of the front and the side, if robot is rotating on the spot the lidar rotates. The purpose here is to use the lidar to get the data that is most useful (ex: don't sweep behind the robot when we drive straight). I am trying to replicate this behavior (that works in the physical robot) in Gazebo.
Edit #2
This sounds like a regular, closed-loop position controller.
Yes you are right. I'm a bit verbose.
Do you mean "the .yaml controller configuration file"? Because you don't typically configure controllers via/with/in a .xacro.
I followed this answer: https://answers.ros.org/question/273947/moving-joints-in-gazebo-simple-example/ where sample code had the two lines I mentioned in those files. You can see the yaml and urdf files here: https://github.com/Toronto-Robotics-club/Toronto-Robotics-club-ros_control_and_gazebo_simple_position_controller
Could you clarify what sort of behavior you are looking for exactly?
First off, thank you very much. You have helped me so much over the past while and I really appreciate your help. I put together a quick drawing for what I am trying to do in Gazebo (which is already implemented on the physical robot):
- The red lines show the sweeping arc that the lidar should perform given the Twist data.
- Issue #1 - the current answer does not allow me to give a "do a single revolution command". This will be needed in both directions (1 revolution right, 1 revolution left).
- Issue #2 - say the lidar is located on the green line (pointing in that direction). The lidar now needs to sweep the area in the red lines. The shortest path to a full sweep is to go CCW, but that is not what will happen.
I have a feeling the best solution is to use a velocity control on the joint, and monitor the position of the joint. Then when the joint is in position, send a stop command. What do you think?
Originally posted by BuilderMike on ROS Answers with karma: 247 on 2020-02-12
Post score: 0