ros-controls / ros_control Goto Github PK
View Code? Open in Web Editor NEWGeneric and simple controls framework for ROS
Home Page: http://wiki.ros.org/ros_control
License: BSD 3-Clause "New" or "Revised" License
Generic and simple controls framework for ROS
Home Page: http://wiki.ros.org/ros_control
License: BSD 3-Clause "New" or "Revised" License
If you have a hardware interface that implements more than one type - i.e. EffortJointInterface, PositionJointInterface, VelocityJointInterface - how can you tell which one is currently being used/written to? For example, in the Gazebo ros_control plugin I want to be able to implement all three of the above interfaces, and send commands to a simulated robot depending on which method is being used. I do not see a method to get this property - the closest thing I have found is for controllers, which have a getHardwareInterfaceType
method - but this isn't accessible from the hardware_interface itself.
Thanks!
@adolfo-rt @jbohren
The controller_manager manifest.xml lists pr2_controller_interface as a dependency.
I'm guessing that this is a leftover and isn't needed.
I have also opened a separate issue to ask how to manage these things in the future (e.g. using fork and pull etc.)
Leverage the CATKIN_ENABLE_TESTING
CMake variable (example) and the <test_depend>
package.xml element.
Hello All,
I have a question to pose to the developers of this stack regarding the overall architecture and it's application to robots in general. I realize that this area is for issues regarding this stack, but I didn't know where to find a mailing list to present questions such as this. I will be more that willing to redirect this question to a mailing list if one is available. I've following the development of this stack for the last month and it looks very promising. I've also been looking at the source code to gain a better understanding of the architecture because I'm very interested in using this stack for my robot (specifically, a quadrotor), but I haven't been able to quite figure out how to apply it. I understand that this stack is still in its primitive stages of development, but I like the generic control philosophy behind it and think that it could very well apply to quadrotor robot as well. Looking at the code I surmised that you should use the stack as follows:
Would this be correct? I just want to make sure I understood the use of this stack correctly before digging deeper.
This will make the TransmissionInterface class more consistent with all other hardware interfaces. If #45 is addressed, then there would be a consistent API for managing joint, actuator, sensor and transmission resources.
The TransmissionInterface::propagate()
method is convenient for propagating all transmissions in an interface, but could be exposed as a free function taking the TransmissionInterface as a parameter.
Hi Wim,
I just started to look at what it would take to switch control modes.
I noticed that STL vectors are getting cleared within the please_switch_ code block.
I'm guessing that this would not be realtime safe.
In this case we could probably clear the vectors in the switchController function?
It looks like there's some old functionality that is #ifdef 0
'd in limited_proxy.cpp:
https://github.com/willowgarage/ros_control/blob/master/control_toolbox/src/limited_proxy.cpp#L240
Can we decide if this should be in or not?
Since the Redwood arm has separate motor and joint encoders, it might be nice to distinguish between them and have an easy way for the controllers to use one or the other.
the JointStateInterface currently uses the function names getPosition, getVelocity. Might be good to change this to getMotorPosition, getJointPosition ... (one set could be in the JointStateInterface and the other in MotorStateInterface).
This might be worth a short discussion because we haven't really thought about what all will get affected by it.
According to this ros_comm issue, the rostest+gtest combination does not seem to be well supported in Catkin. Further, I apparently added a test the wrong way in the joint_limits_interface package, as per the answer to this question.
At this moment, I'll allow the ros_comm issue to evolve a bit, as I don't see clearly how to proceed.
It's looking like another module of the ros_control toolchain that we could provide a pluggin-able interface for is trajectory interpolation.
The goal here would be to provide a simple interface that includes:
There should be an emphasis on dealing not just with long discrete trajectories, but also for use as an interpolator for streaming contexts like teleoperation. To that end, depending on performance, it might make sense to also provide an interface for JointTrajectoryPoint
and CartesianTrajectoryPoint
.
This is based on discussion on joint trajectory controllers and the idea to split some of the features of the current PR2 joint trajectory controllerthe robot control SIG here:
https://groups.google.com/forum/#!topic/ros-sig-robot-control/VseNnkqXBkY
See discussion here:
ros/catkin#486 (comment)
Wait for this to be released:
https://github.com/ros/cmake_modules
@wjwwood how will we know when this is released?
Update TinyXML documentation for including the custom cmake file here:
http://www.ros.org/wiki/tinyxml#preview
It's the only part of the joint_limits_interface
package without coverage.
I noticed when using rosrun controller_manager spawner
there isn't an argument to specify a namespace, and it expects the load_controller service to be at /controller_manager/load_controller
. Is this on purpose or should I add this feature to the spawner?
Currently, my robot as its controller manager services at
rrbot/ros_control/controller_manager/load_controller
joint_limits_interface/manifest.xml
includes a reference to a pre-Hydro package, urdf_interface
. This is as intended so that a rosbuild can work pre-Hydro and catkin can work for Groovy, Hydro and forward.
The problem is that when you run:
rosdep install --from-paths . --ignore-src --rosdistro hydro -y
rosdep scans both package.xml
and manifest.xml
files and throws errors because it can't find the package urdf_interface
in Hydro.
I'm not sure what the best course of action would be, perhaps splitting the hydro-devel branch to no longer support rosbuild? This would make syncing updates way more difficult then.
Another option would be to fix rosdep to ignore manifest.xml when in a catkin workspace, or some logic like that. @wjwwood ?
The JointInfo and ActuatorInfo structs contain TiXmlElement*
instances to transmission-specific configuration. The current parser implementation has the issue that these pointers are only valid during the lifetime of the associated TiXmlDocument instance, which goes out of scope when parse(...)
returns. This means that we basically can't use this pointers.
Two solutions come to mind:
TiXmlDocument
instance. In this case pointers will only be valid as long as the parser is alive.TiXmlElement
. The parser remains stateless, and the transmission plugins would only have to convert this string to a TinyXml data structure.I prefer the second option, and will be implementing it.
This seems like a regression, as I'm pretty sure it worked not long ago. @davetcoleman could you take a look at this, as you pushed some changes in the script recently?.
As of this writing, the biggest limitation that I see in ros_control is its inability to connect a single controller to two different hardware interfaces / robot hardware abstractions. As far as I can tell, removing this limitation would fundamentally change the design of ros_control.
RobotHW
components at the level of ros_control (consider connecting a PHANToM Omni to a KUKA LWR via ros_control),RobotHW
components which use the same low-level interface (consider a robot that can have different numbers of arms or arm components like grippers which all talk over CANBus like the WAM),The pipeline currently connects like so:
ControllerManager
calls ControllerBase::initRequest()
ControllerBase::initRequest()
calls ControllerInterfaceType<HardwareInterfaceType>::init()
HardwareInterfaceType::init()
is passed the single HardwareInterfaceType
All of this connection via template inference means:
ControllerManager
cannot connect a single controller to multiple hardware interfaces of different types from a single robot hardware abstraction and the only way to connect two different interfaces is to connect them with the RobotHW
which means control computation would be happening in the hardware abstraction layer instead of the controllers.ControllerManager
cannot connect a single controller to multiple robot hardware abstractions which means you need to create a RobotHW
subclass for every robot configuration (including master/slave devices which might be fundamentally different hardware).To support multiple robot hardware abstractions in a controller manager, we could take a hierarchical approach, and compose RobotHW
subclasses in a single CompositeRobotHW
class which combines the resources of each component's hardware interfaces. This would require some template magic and/or a redesign of the resource manager to enable the extraction and aggregating of handles of the same type.
As a slight alternative, we could modify the ControllerManager
to keep its own aggregated hardware interfaces internally, and instead register RobotHW
instances with it, and have the controller manager extract and aggregate the handles, itself.
Controllers are currently strongly typed at compile time based on a single hardware interface. via template parameter. In order to allow a single controller to talk to two different hardware interfaces, we could change the lookup pattern from using templates to just using string identifiers. It's worth noting that the interface types are already being extracted from the RobotHW
class in this way by calling internal::demangledTypeName<T>()
and looking up the interface object in a std::map<std::string, HardwareInterface*>
.
Please comment on what you think about the described limitation and my sketches of workarounds, and feel free to suggest other solutions!
How do you all want to manage collaboration with Redwood?
Simple example (I'll open an issue for this):
controller_manager depends on pr2_controller_interface. I want to change the manifest.xml but would rather not be pushing to master.
Do you want to try having me fork and send pull requests? I haven't done this before so I don't know exactly what will happen and I'm unsure how this would work once Redwood has more than one person committing code.
Alternately, I could create a Redwood branch and let you all merge it back into master if useful?
Hi Wim,
Rob Wilson and I just found that ros::Time::now() results in a syscall.
Do you all have a good way to test if the code is realtime safe? If you're willing to install RTAI on a machine then we can provide you with our installation instructions and the method that we are using to check for syscalls.
The EffortJointSoftLimitsHandle constructor requires a soft_limits argument, even though the URDF specification states that the <safety_controller> element is optional. My robot's URDF file does not contain safety controllers, so I'm passing a dummy soft_limits to EffortJointSoftLimitsHandle() in my version of default_robot_hw_sim.cpp. This isn't working well, since control is sensitive to the default values I store in the dummy soft_limits. I've thought of two solutions:
Create an EffortJointSaturationHandle class that works like EffortJointSoftLimitsHandle, except that only "limits" is used (no soft_limits). writeSim() in default_robot_hw_sim.cpp would have to make calls to the enforceLimits() member functions for both the soft limits and saturation interfaces.
Add an additional constructor to EffortJointSoftLimitsHandle, which does not have a soft_limits parameter. A has_soft_limits member variable would control whether computations were made with "limits" or "soft_limits".
Let me know which solution you prefer, or if whether you have an alternative solution.
Handles are pretty much useless when created with these constructors. They were added in 2a3c118, but the reason was not documented. What was the original purpose?, to do something like...
JointStateHandle js; // Raw data not yet available
// Later on
js = JointStateHandle("name", &pos, &vel, &eff); // Raw data available
I don't like much the idea of constructing unusable objects.
"Interaface" -> "Interface" in both package.xml and manifest.xml of the transmission_interface
package (description element).
Would it make sense to store demangled symbols when getting the typeid of a type?. I could prepare a patch that, when available (gcc >= 3.0), would use demangled names, otherwise fallback to mangled names.
The upside would be that log statements, inspection of controllers via command line (eg. controller_manager/list_controllers), etc. would be much easier to read, eg.
hardware_interface::VelocityJointInterface
instead of
N18hardware_interface22VelocityJointInterfaceE
I'm getting a 404 error on this URL https://github.com/osrf/gazebo_ros_control
Did it go somewhere else?.
I can imagine that it would be nice if the Cartesian and position effort controllers could work with an EffortJointInterface and an EffortMotorInterface.
Would it be possible to have a templated class for the controllers that can be reused with both the EffortJointInterface and an (as yet undefined) EffortMotorInterface?
If this is a possibility then we could go ahead and define a MotorCommandInterface and EffortMotorInterface. Maybe there is an opportunity for using templates for this too?
Adding @sachinchitta and @vpradeep07 to this conversation.
The JointStateInterface no longer has the getJointNames function.
I would still like to be able to get the list of all the joint names but can not figure out how to do that with the new structure.
This is really nitpicking, but I'm a big fan of consistency.
In the hardware_interface and transmission_interface packages, joint, actuator, and transmission names are printed [between square brackets], while in the controller_manager package, controller names are printed 'between single quotes'. I'd like to harmonize this, so the same delimiters are used throughout the whole of ros_control's log statements. I'll leave the choice to the original developers, but offer to provide a patch implementing the fix.
If a controller fails to start or stop, it would be great to be able to report to the system that such a failure has occurred. This would be similar to the way that OROCOS RTT handles these events.
See the current behavior here (success always):
https://github.com/willowgarage/ros_control/blob/master/controller_interface/include/controller_interface/controller_base.h#L93
I know we shouldn't be re-inventing OROCOS, but this is one aspect that I think could prevent a lot of problems during controller switching.
Either this, or should an exception be thrown?
I just wanted to check if there are any plans to catkinize this stack soon.
Thanks!
The ControllerManager::getControllerSchedule private method is currently unimplemented. Is it a feature yet to be implemented?, if so, what purpose would it serve?.
The version of ros_controllers got recently bumped to 0.5.0-0 in the rosdistro release file for Hydro, while ros_control is still on 0.4.0-2. This is causing the ros_controllers build to fail, as it's expecting headers from ros_control 0.5.0-0 to be available. Could you please issue a rosdistro PR to bump ros_control to 0.5.0-0 as well?.
I'm writing an implementation of RobotHW and I need to expose multiple joint interfaces, each of which could potentially claim the same joints. In the read/write update loop, how do I determine which interface is currently commanding the joints? I can think of a couple ways to do this indirectly, but I would like to know if there is a direct way or at least an "accepted way".
My current implementation uses a command mode parameter which the controller is obligated to set based on the interface being used. This seems like a really messy way of doing things.
I'm probably going to switch to a method which sets all command variables to NaN, then checks them all at read time to see which one updated.
I'm running into a wall trying to create a controller that needs to control multiple joints/actuators. I believe a similar solution has been proposed here Support multiple hardware interfaces in controllers and a less similar idea of composite controllers but it seems to me a simpler solution would be to create controllers that operate on multiple joints/multiple sub-controllers.
This notion is something I've seen implemented effectively in the dynamixel_hardware_interface originally created by @arebgun. In this implementation you can load MultiJointControllers basically the same was as you load SingleJointControllers except you also pass it in it's init()
function a list of pointers to sub controllers that it can use to actually control hardware. You continue to have your normal controllers.yaml
file but you now have an additional configuration file similar to:
clam_trajectory_controller:
type: dynamixel_hardware_interface/JointTrajectoryActionController
dependencies:
- shoulder_pan_controller
- gripper_roll_controller
- shoulder_pitch_controller
...
joint_trajectory_action_node:
min_velocity: 0.0
constraints:
goal_time: 0.3
shoulder_pan_joint:
goal: 0.2
gripper_roll_joint:
goal: 0.2
shoulder_pitch_joint:
goal: 0.2
...
This allows you to easily implement a joint trajectory action controller or a controller that listens to ROS messages that contain commands for multiple joints (as is the case with Baxter).
Your launch file for the joint trajectory action controller might then look like:
<rosparam file="$(find clam_controller)/config/clam_trajectory_controller.yaml" command="load"/>
<node name="arm_trajectory_controller_spawner" pkg="dynamixel_hardware_interface" type="controller_spawner.py"
args="--manager=clam_controller_manager
clam_trajectory_controller"
output="screen"/>
What are you guy's thoughts on supporting this?
calling unlockAndPublish() causes the RealtimePublisher to make a syscall. If I comment out that line from my code, I don't see any syscalls.
What other information would you guys need to track this down?
Currently there is no data validation in place when wrapping raw hardware data in ros_control, eg, nothing prevents you from doing
JointStateInterface js_iface;
js_iface.registerJoint("the_breaker", 0, 0, 0);
One should get feedback when invalid resource registrations occur, so that things don't blow up in your face when the system is actually running and tries to read a dangling pointer.
I'd like to address this issue once some consensus is reached in #45, as its outcome will influence how this issue is dealt with.
I'd like to cleanup the branches in this repo, feedback welcomed, similar to what I did in ros_controllers
fuerte-dev --> fuerte-devel
fuerte - REMOVE - this is the same as fuerte-dev
groovy-dev --> groovy-devel
groovy - REMOVE - this is the same as groovy-dev
hydro-devel - keep
master - REMOVE - this is behind hydro-devel by a lot of commits and not really needed
pr2-mechanism-release - keep because i'm not sure what its for
the "devel" name is a standard the ROS community seems to have settled on
Is there a plan to port pr2_controller_manager_interface.py and pr2_controller_manager (the python script in the scripts folder) to this new controller_manager infrastructure?
We see a spawner but not anything more in controller_manager/scripts.
Hi,
I looked through the wiki pages and a little into the code and would like to know what the status of the project is. The wiki states: "is not even completely written yet"
Is that still true? Is there any plan to publish it? I unfortunately found it a little too late but I seriously consider implementing your controllers for my robot. If this project is ready to use it would be great to have it a little more visible, maybe on ros.org
Kai
Identical to #78, but for hardware_interface
. Just caught my eye.
Now that the hydro-devel branch is in place, does it make sense to keep master alive?.
Right now there are seemingly three development branches: master
, fuerte
, and groovy
. Since this package hasn't been catkinized, should there be any distinction between these three?
The different interfaces implemented in the hardware_interface package have a very similar look and feel between them, the main differences being mostly aesthetic, eg.
JointStateInterface: getJointNames(), registerJoint(...), getJointStateHandle()
ActuatorCommandInterface: getActuatorNames(), registerActuator(...), getActuatorHandle()
ImuSensorInterface: getSensorNames(), registerSensor(), getSensorHandle()
Implementations are also very similar, so e55fd29 tried to refactor common code to avoid some duplication. Still, I'm not very satisfied with the current situation.
I'd like to propose an API-breaking change ( lots of code will break), that would address the code duplication issue and make unit testing much much easier along the way.
The idea would be to have something like:
// Feel free to propose alternative names
template <class ResouceHandle>
class ResourceManager
{
std::vector<std::string> getNames() const;
void registerHandle(const std::string& name, const ResouceHandle& handle);
ResouceHandle getHandle(const std::string& name) const;
};
typedef ResourceManager<JointStateHandle> JointStateInterface;
typedef ResourceManager<ActuatorCommandHandle> ActuatorCommandInterface;
typedef ResourceManager<ImuSensorHandle> ImuSensorInterface;
The main things that changes apart from a uniform API across hardware interfaces is that to register a resource, you must first create a handle object instead of the current practice of providing the requisites to the register[Joint|Actuator|Sensor|Transmission]
methods.
I don't see a loss in code clarity by going from joint_state_iface.registerJoint(name, pos, vel, eff)
to joint_state_iface.registerHandle(handle)
, but YMMV.
Thoughts?.
I'm adapting the tff_controller
from www.github.com/jbohren-forks/pr2_doors and like most cartesian controllers, it requires a kinematic model to do it's thing. The old PR2 controller would get the robot model from the old pr2_mechanism_model
but the neither hardware_interface::HardwareInterface
nor hardware_interface::JointCommandInterface
have a standard interface for getting a robot model. So for now, I'm just pulling it out of a controller-specific parameter.
Whether this is a KDL model or an URDF model doesn't really matter, but is such an interface something that the ros_control team is considering?
CMake Error at /opt/ros/hydro/share/transmission_interface/cmake/transmission_interfaceConfig.cmake:127 (message):
Project 'gazebo_ros_control' tried to find library
'transmission_interface_parser'. The library is neither a target nor
built/installed properly. Did you compile project
'transmission_interface'? Did you find_package() it before the subdirectory
containing its code is included?
Call Stack (most recent call first):
/opt/ros/hydro/share/catkin/cmake/catkinConfig.cmake:72 (find_package)
CMakeLists.txt:6 (find_package)
@wjwwood :(
Looking at controller_manager/src/controller_manager.cpp (7062d96) in ControllerManager::update(...), there does not seem to be a way to gracefully handle an error from the ControllerBase::updateRequest(...) function, either from catching exceptions or errors.
We think that this feature would be necessary for handling controller faults.
What would be a good error handling policy? Just stopping all controllers and setting an error state? (Like Orocos?)
We're trying a rosmake in joint_state_controller and getting this error:
joint_state_controller.h:55:15: error: ‘JointState’ is not a member of ‘hardware_interface
The offending piece of code is:
std::vector<hardware_interface::JointState> joint_state_;
We don't see any JointState class within the hardware_interface namespace although we do see JointStateHandle and JointStateInterface in joint_state_interface.h
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.