{"action":"created","issue":{"url":"https://api.github.com/repos/ros-controls/ros_control/issues/198","labels_url":"https://api.github.com/repos/ros-controls/ros_control/issues/198/labels{/name}","comments_url":"https://api.github.com/repos/ros-controls/ros_control/issues/198/comments","events_url":"https://api.github.com/repos/ros-controls/ros_control/issues/198/events","html_url":"https://github.com/ros-controls/ros_control/issues/198","id":60555202,"number":198,"title":"Boilerplate Template","user":{"login":"davetcoleman","id":561060,"avatar_url":"https://avatars.githubusercontent.com/u/561060?v=3","gravatar_id":"","url":"https://api.github.com/users/davetcoleman","html_url":"https://github.com/davetcoleman","followers_url":"https://api.github.com/users/davetcoleman/followers","following_url":"https://api.github.com/users/davetcoleman/following{/other_user}","gists_url":"https://api.github.com/users/davetcoleman/gists{/gist_id}","starred_url":"https://api.github.com/users/davetcoleman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davetcoleman/subscriptions","organizations_url":"https://api.github.com/users/davetcoleman/orgs","repos_url":"https://api.github.com/users/davetcoleman/repos","events_url":"https://api.github.com/users/davetcoleman/events{/privacy}","received_events_url":"https://api.github.com/users/davetcoleman/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":13,"created_at":"2015-03-10T19:28:42Z","updated_at":"2015-03-20T15:26:16Z","closed_at":null,"body":"I'm thinking of making a boilerplate template for a simple hardware interface, does this already exist somewhere?"},"comment":{"url":"https://api.github.com/repos/ros-controls/ros_control/issues/comments/84048931","html_url":"https://github.com/ros-controls/ros_control/issues/198#issuecomment-84048931","issue_url":"https://api.github.com/repos/ros-controls/ros_control/issues/198","id":84048931,"user":{"login":"adolfo-rt","id":1128028,"avatar_url":"https://avatars.githubusercontent.com/u/1128028?v=3","gravatar_id":"","url":"https://api.github.com/users/adolfo-rt","html_url":"https://github.com/adolfo-rt","followers_url":"https://api.github.com/users/adolfo-rt/followers","following_url":"https://api.github.com/users/adolfo-rt/following{/other_user}","gists_url":"https://api.github.com/users/adolfo-rt/gists{/gist_id}","starred_url":"https://api.github.com/users/adolfo-rt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adolfo-rt/subscriptions","organizations_url":"https://api.github.com/users/adolfo-rt/orgs","repos_url":"https://api.github.com/users/adolfo-rt/repos","events_url":"https://api.github.com/users/adolfo-rt/events{/privacy}","received_events_url":"https://api.github.com/users/adolfo-rt/received_events","type":"User","site_admin":false},"created_at":"2015-03-20T15:26:16Z","updated_at":"2015-03-20T15:26:16Z","body":"I can't make inline comments on the code, because it's not a PR, so I'll be brief. Manually cross-referencing is time-consuming. I'm going to highlight only the most relevant best practices\r\n\r\n**generic_hardware_interface.cpp**\r\n\r\n** Control period**\r\n\r\nIn `void GenericHardwareInterface::update(const ros::TimerEvent& e)`: Don't compute the control period from system time differences. Extract from [this](https://groups.google.com/forum/?fromgroups#!topic/ros-sig-robot-control/18VRoTEV1vM) robot control sig thread:\r\n\r\n> \"I recommend using a monotonic source for computing control periods, as opposed to using system time differences (current - previous). The latter is not a good practice because system time is subject to changing at different rates (eg. ntp slew) or even discretely (eg. user calling `date --set=some_arbitrary_date`).\"\r\n\r\n[Posix-wise](http://linux.die.net/man/3/clock_gettime), you can use `clock_gettime(CLOCK_MONOTONIC`, t)` ([more](http://stackoverflow.com/questions/3523442/difference-between-clock-realtime-and-clock-monotonic))\r\n\r\n** Write**\r\n\r\nThe `write` method is somewhat specific to a particular setup. For a dummy example, I'd simply write commands to a raw data buffer. If you're dealing with only position and velocity interfaces, you could make `read` report back desired positions or integrate desired velocities, and you'd have a kinematic simulator in place.\r\n\r\n** Separate control loop from RobotHW**\r\n\r\n`GenericHardwareInterface` is the robot abstraction, and it's currently coupled with the control loop. I'd clearly separate these two. For instance, in your control loop you're imposing a separate process for it, and how time and durations are measured. Those two assumptions will not work well for everybody. I'm sure one can think of more.\r\n\r\n**generic_hardware_main.cpp**\r\n\r\nIt's very important to stress the need of an `AsyncSpinner` or similar, which you already do.\r\n\r\nYou could `ros::waitForShutdown();` instead of `ros::spin()`, right?.\r\n\r\n**General comments**\r\n\r\nI'd aim at having a basic example that's easy to understand, and then to scale it up with goodies, like joint limits, e-stop handling or transmissions. This exercise will likely help us identify building blocks that should be put in place to reduce the red tape needed to construct a robot hardware. Making sure that everybody understands the few key issues discussed above is already a big gain."}}