{"action":"created","comment":{"url":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/comments/105609781","pull_request_review_id":26494990,"id":105609781,"diff_hunk":"@@ -32,38 +33,53 @@ class Robot(object):\n     def __init__(self, robot_name=\"\", wait_services=False):\n \n         self.robot_name = robot_name\n-\n         self.tf_listener = tf_server.TFClient()\n \n         # Body parts\n-        self.base = base.Base(self.robot_name, self.tf_listener, wait_service=wait_services)\n-        self.torso = torso.Torso(self.robot_name,wait_service=wait_services)\n-        self.spindle = self.torso\n-        self.leftArm = arms.Arm(self.robot_name, \"left\", self.tf_listener)\n-        self.rightArm = arms.Arm(self.robot_name, \"right\", self.tf_listener)\n-        self.arms = OrderedDict(left=self.leftArm, right=self.rightArm)\n-\n-        self.head = head.Head(self.robot_name)\n+        self.parts = dict()\n+        self.parts['base'] = base.Base(self.robot_name, self.tf_listener)\n+        self.parts['torso'] = torso.Torso(self.robot_name, self.tf_listener)\n+        self.parts['leftArm'] = arms.Arm(self.robot_name, self.tf_listener, side=\"left\")\n+        self.parts['rightArm'] = arms.Arm(self.robot_name, self.tf_listener, side=\"right\")\n+        self.parts['head'] = head.Head(self.robot_name, self.tf_listener)\n \n         # Human Robot Interaction\n-        self.lights = lights.Lights(self.robot_name)\n-        self.speech = speech.Speech(self.robot_name, wait_services, lambda: self.lights.set_color(1,0,0), lambda: self.lights.set_color(0,0,1))\n-        self.hmi = Api(\"/\" + self.robot_name + '/hmi')\n-        self.ears = ears.Ears(self.robot_name, lambda: self.lights.set_color(0,1,0), lambda: self.lights.set_color(0,0,1))\n-        self.ears._hmi = self.hmi # TODO: when ears is gone, remove this line\n-        self.ebutton = ebutton.EButton()\n+        self.parts['lights'] = lights.Lights(self.robot_name, self.tf_listener)\n+        self.parts['speech'] = speech.Speech(self.robot_name, self.tf_listener,\n+                                             lambda: self.lights.set_color(1, 0, 0),\n+                                             lambda: self.lights.set_color(0, 0, 1))\n+        self.parts['hmi'] = api.Api(self.robot_name, self.tf_listener)\n+        self.parts['ears'] = ears.Ears(self.robot_name,\n+                                       lambda: self.lights.set_color(0, 1, 0),\n+                                       lambda: self.lights.set_color(0, 0, 1))\n+\n+        self.parts['ebutton'] = ebutton.EButton(self.robot_name, self.tf_listener)\n \n         # Reasoning/world modeling\n-        self.ed = world_model_ed.ED(self.robot_name, self.tf_listener, wait_service=wait_services)\n+        self.parts['ed'] = world_model_ed.ED(self.robot_name, self.tf_listener)\n \n         # Miscellaneous\n         self.pub_target = rospy.Publisher(\"/target_location\", geometry_msgs.msg.Pose2D, queue_size=10)\n         self.base_link_frame = \"/\"+self.robot_name+\"/base_link\"\n \n-        #Grasp offsets\n+        # Grasp offsets\n         #TODO: Don't hardcode, load from parameter server to make robot independent.\n         self.grasp_offset = geometry_msgs.msg.Point(0.5, 0.2, 0.0)\n \n+        # Create attributes from dict\n+        for k, v in self.parts.iteritems():\n+            setattr(self, k, v)","path":"robot_skills/src/robot_skills/robot.py","position":72,"original_position":72,"commit_id":"221621708398a0204134b346dc85824104f126b7","original_commit_id":"221621708398a0204134b346dc85824104f126b7","user":{"login":"LoyVanBeek","id":709259,"avatar_url":"https://avatars1.githubusercontent.com/u/709259?v=3","gravatar_id":"","url":"https://api.github.com/users/LoyVanBeek","html_url":"https://github.com/LoyVanBeek","followers_url":"https://api.github.com/users/LoyVanBeek/followers","following_url":"https://api.github.com/users/LoyVanBeek/following{/other_user}","gists_url":"https://api.github.com/users/LoyVanBeek/gists{/gist_id}","starred_url":"https://api.github.com/users/LoyVanBeek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LoyVanBeek/subscriptions","organizations_url":"https://api.github.com/users/LoyVanBeek/orgs","repos_url":"https://api.github.com/users/LoyVanBeek/repos","events_url":"https://api.github.com/users/LoyVanBeek/events{/privacy}","received_events_url":"https://api.github.com/users/LoyVanBeek/received_events","type":"User","site_admin":false},"body":"This is indeed much nicer than override __getattr__ to dynamically look up the parts: this gives tab completion.\r\n\r\nBut instantiating them the old way and then putting in a dictionary or list also works. \r\n\r\nYou could also iterate over all members and then check if they are an instance of RobotPart with isinstance(part, RobotPart):\r\n```python\r\nfor part in [part for part in self.__dict__.values() if isinstance(part, RobotPart):\r\n    part.wait_for_connections(1.0)\r\n```","created_at":"2017-03-13T08:36:40Z","updated_at":"2017-03-13T08:40:27Z","html_url":"https://github.com/tue-robotics/tue_robocup/pull/184#discussion_r105609781","pull_request_url":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/184","_links":{"self":{"href":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/comments/105609781"},"html":{"href":"https://github.com/tue-robotics/tue_robocup/pull/184#discussion_r105609781"},"pull_request":{"href":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/184"}}},"pull_request":{"url":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/184","id":110260468,"html_url":"https://github.com/tue-robotics/tue_robocup/pull/184","diff_url":"https://github.com/tue-robotics/tue_robocup/pull/184.diff","patch_url":"https://github.com/tue-robotics/tue_robocup/pull/184.patch","issue_url":"https://api.github.com/repos/tue-robotics/tue_robocup/issues/184","number":184,"state":"open","locked":false,"title":"feature(RobotSkills) All parts inherit from RobotPart and all connect…","user":{"login":"jlunenburg","id":5235350,"avatar_url":"https://avatars0.githubusercontent.com/u/5235350?v=3","gravatar_id":"","url":"https://api.github.com/users/jlunenburg","html_url":"https://github.com/jlunenburg","followers_url":"https://api.github.com/users/jlunenburg/followers","following_url":"https://api.github.com/users/jlunenburg/following{/other_user}","gists_url":"https://api.github.com/users/jlunenburg/gists{/gist_id}","starred_url":"https://api.github.com/users/jlunenburg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jlunenburg/subscriptions","organizations_url":"https://api.github.com/users/jlunenburg/orgs","repos_url":"https://api.github.com/users/jlunenburg/repos","events_url":"https://api.github.com/users/jlunenburg/events{/privacy}","received_events_url":"https://api.github.com/users/jlunenburg/received_events","type":"User","site_admin":false},"body":"…ions are checked","created_at":"2017-03-11T14:03:33Z","updated_at":"2017-03-13T08:40:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6c2d2a614e030823947022f1dd48401006f9d5ca","assignee":{"login":"reinzor","id":4176023,"avatar_url":"https://avatars1.githubusercontent.com/u/4176023?v=3","gravatar_id":"","url":"https://api.github.com/users/reinzor","html_url":"https://github.com/reinzor","followers_url":"https://api.github.com/users/reinzor/followers","following_url":"https://api.github.com/users/reinzor/following{/other_user}","gists_url":"https://api.github.com/users/reinzor/gists{/gist_id}","starred_url":"https://api.github.com/users/reinzor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/reinzor/subscriptions","organizations_url":"https://api.github.com/users/reinzor/orgs","repos_url":"https://api.github.com/users/reinzor/repos","events_url":"https://api.github.com/users/reinzor/events{/privacy}","received_events_url":"https://api.github.com/users/reinzor/received_events","type":"User","site_admin":false},"assignees":[{"login":"reinzor","id":4176023,"avatar_url":"https://avatars1.githubusercontent.com/u/4176023?v=3","gravatar_id":"","url":"https://api.github.com/users/reinzor","html_url":"https://github.com/reinzor","followers_url":"https://api.github.com/users/reinzor/followers","following_url":"https://api.github.com/users/reinzor/following{/other_user}","gists_url":"https://api.github.com/users/reinzor/gists{/gist_id}","starred_url":"https://api.github.com/users/reinzor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/reinzor/subscriptions","organizations_url":"https://api.github.com/users/reinzor/orgs","repos_url":"https://api.github.com/users/reinzor/repos","events_url":"https://api.github.com/users/reinzor/events{/privacy}","received_events_url":"https://api.github.com/users/reinzor/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/184/commits","review_comments_url":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/184/comments","review_comment_url":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/comments{/number}","comments_url":"https://api.github.com/repos/tue-robotics/tue_robocup/issues/184/comments","statuses_url":"https://api.github.com/repos/tue-robotics/tue_robocup/statuses/221621708398a0204134b346dc85824104f126b7","head":{"label":"tue-robotics:feature/update-interfaces","ref":"feature/update-interfaces","sha":"221621708398a0204134b346dc85824104f126b7","user":{"login":"tue-robotics","id":2786024,"avatar_url":"https://avatars0.githubusercontent.com/u/2786024?v=3","gravatar_id":"","url":"https://api.github.com/users/tue-robotics","html_url":"https://github.com/tue-robotics","followers_url":"https://api.github.com/users/tue-robotics/followers","following_url":"https://api.github.com/users/tue-robotics/following{/other_user}","gists_url":"https://api.github.com/users/tue-robotics/gists{/gist_id}","starred_url":"https://api.github.com/users/tue-robotics/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tue-robotics/subscriptions","organizations_url":"https://api.github.com/users/tue-robotics/orgs","repos_url":"https://api.github.com/users/tue-robotics/repos","events_url":"https://api.github.com/users/tue-robotics/events{/privacy}","received_events_url":"https://api.github.com/users/tue-robotics/received_events","type":"Organization","site_admin":false},"repo":{"id":27433386,"name":"tue_robocup","full_name":"tue-robotics/tue_robocup","owner":{"login":"tue-robotics","id":2786024,"avatar_url":"https://avatars0.githubusercontent.com/u/2786024?v=3","gravatar_id":"","url":"https://api.github.com/users/tue-robotics","html_url":"https://github.com/tue-robotics","followers_url":"https://api.github.com/users/tue-robotics/followers","following_url":"https://api.github.com/users/tue-robotics/following{/other_user}","gists_url":"https://api.github.com/users/tue-robotics/gists{/gist_id}","starred_url":"https://api.github.com/users/tue-robotics/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tue-robotics/subscriptions","organizations_url":"https://api.github.com/users/tue-robotics/orgs","repos_url":"https://api.github.com/users/tue-robotics/repos","events_url":"https://api.github.com/users/tue-robotics/events{/privacy}","received_events_url":"https://api.github.com/users/tue-robotics/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/tue-robotics/tue_robocup","description":"RoboCup challenge implementations","fork":false,"url":"https://api.github.com/repos/tue-robotics/tue_robocup","forks_url":"https://api.github.com/repos/tue-robotics/tue_robocup/forks","keys_url":"https://api.github.com/repos/tue-robotics/tue_robocup/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tue-robotics/tue_robocup/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tue-robotics/tue_robocup/teams","hooks_url":"https://api.github.com/repos/tue-robotics/tue_robocup/hooks","issue_events_url":"https://api.github.com/repos/tue-robotics/tue_robocup/issues/events{/number}","events_url":"https://api.github.com/repos/tue-robotics/tue_robocup/events","assignees_url":"https://api.github.com/repos/tue-robotics/tue_robocup/assignees{/user}","branches_url":"https://api.github.com/repos/tue-robotics/tue_robocup/branches{/branch}","tags_url":"https://api.github.com/repos/tue-robotics/tue_robocup/tags","blobs_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/refs{/sha}","trees_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tue-robotics/tue_robocup/statuses/{sha}","languages_url":"https://api.github.com/repos/tue-robotics/tue_robocup/languages","stargazers_url":"https://api.github.com/repos/tue-robotics/tue_robocup/stargazers","contributors_url":"https://api.github.com/repos/tue-robotics/tue_robocup/contributors","subscribers_url":"https://api.github.com/repos/tue-robotics/tue_robocup/subscribers","subscription_url":"https://api.github.com/repos/tue-robotics/tue_robocup/subscription","commits_url":"https://api.github.com/repos/tue-robotics/tue_robocup/commits{/sha}","git_commits_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/commits{/sha}","comments_url":"https://api.github.com/repos/tue-robotics/tue_robocup/comments{/number}","issue_comment_url":"https://api.github.com/repos/tue-robotics/tue_robocup/issues/comments{/number}","contents_url":"https://api.github.com/repos/tue-robotics/tue_robocup/contents/{+path}","compare_url":"https://api.github.com/repos/tue-robotics/tue_robocup/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tue-robotics/tue_robocup/merges","archive_url":"https://api.github.com/repos/tue-robotics/tue_robocup/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tue-robotics/tue_robocup/downloads","issues_url":"https://api.github.com/repos/tue-robotics/tue_robocup/issues{/number}","pulls_url":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls{/number}","milestones_url":"https://api.github.com/repos/tue-robotics/tue_robocup/milestones{/number}","notifications_url":"https://api.github.com/repos/tue-robotics/tue_robocup/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tue-robotics/tue_robocup/labels{/name}","releases_url":"https://api.github.com/repos/tue-robotics/tue_robocup/releases{/id}","deployments_url":"https://api.github.com/repos/tue-robotics/tue_robocup/deployments","created_at":"2014-12-02T13:21:13Z","updated_at":"2017-02-19T06:20:19Z","pushed_at":"2017-03-11T14:44:09Z","git_url":"git://github.com/tue-robotics/tue_robocup.git","ssh_url":"git@github.com:tue-robotics/tue_robocup.git","clone_url":"https://github.com/tue-robotics/tue_robocup.git","svn_url":"https://github.com/tue-robotics/tue_robocup","homepage":"","size":74876,"stargazers_count":6,"watchers_count":6,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":27,"forks":0,"open_issues":27,"watchers":6,"default_branch":"master"}},"base":{"label":"tue-robotics:master","ref":"master","sha":"2a1e55bbfcff09542f5c0c8c890b31129c11509e","user":{"login":"tue-robotics","id":2786024,"avatar_url":"https://avatars0.githubusercontent.com/u/2786024?v=3","gravatar_id":"","url":"https://api.github.com/users/tue-robotics","html_url":"https://github.com/tue-robotics","followers_url":"https://api.github.com/users/tue-robotics/followers","following_url":"https://api.github.com/users/tue-robotics/following{/other_user}","gists_url":"https://api.github.com/users/tue-robotics/gists{/gist_id}","starred_url":"https://api.github.com/users/tue-robotics/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tue-robotics/subscriptions","organizations_url":"https://api.github.com/users/tue-robotics/orgs","repos_url":"https://api.github.com/users/tue-robotics/repos","events_url":"https://api.github.com/users/tue-robotics/events{/privacy}","received_events_url":"https://api.github.com/users/tue-robotics/received_events","type":"Organization","site_admin":false},"repo":{"id":27433386,"name":"tue_robocup","full_name":"tue-robotics/tue_robocup","owner":{"login":"tue-robotics","id":2786024,"avatar_url":"https://avatars0.githubusercontent.com/u/2786024?v=3","gravatar_id":"","url":"https://api.github.com/users/tue-robotics","html_url":"https://github.com/tue-robotics","followers_url":"https://api.github.com/users/tue-robotics/followers","following_url":"https://api.github.com/users/tue-robotics/following{/other_user}","gists_url":"https://api.github.com/users/tue-robotics/gists{/gist_id}","starred_url":"https://api.github.com/users/tue-robotics/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tue-robotics/subscriptions","organizations_url":"https://api.github.com/users/tue-robotics/orgs","repos_url":"https://api.github.com/users/tue-robotics/repos","events_url":"https://api.github.com/users/tue-robotics/events{/privacy}","received_events_url":"https://api.github.com/users/tue-robotics/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/tue-robotics/tue_robocup","description":"RoboCup challenge implementations","fork":false,"url":"https://api.github.com/repos/tue-robotics/tue_robocup","forks_url":"https://api.github.com/repos/tue-robotics/tue_robocup/forks","keys_url":"https://api.github.com/repos/tue-robotics/tue_robocup/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tue-robotics/tue_robocup/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tue-robotics/tue_robocup/teams","hooks_url":"https://api.github.com/repos/tue-robotics/tue_robocup/hooks","issue_events_url":"https://api.github.com/repos/tue-robotics/tue_robocup/issues/events{/number}","events_url":"https://api.github.com/repos/tue-robotics/tue_robocup/events","assignees_url":"https://api.github.com/repos/tue-robotics/tue_robocup/assignees{/user}","branches_url":"https://api.github.com/repos/tue-robotics/tue_robocup/branches{/branch}","tags_url":"https://api.github.com/repos/tue-robotics/tue_robocup/tags","blobs_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/refs{/sha}","trees_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tue-robotics/tue_robocup/statuses/{sha}","languages_url":"https://api.github.com/repos/tue-robotics/tue_robocup/languages","stargazers_url":"https://api.github.com/repos/tue-robotics/tue_robocup/stargazers","contributors_url":"https://api.github.com/repos/tue-robotics/tue_robocup/contributors","subscribers_url":"https://api.github.com/repos/tue-robotics/tue_robocup/subscribers","subscription_url":"https://api.github.com/repos/tue-robotics/tue_robocup/subscription","commits_url":"https://api.github.com/repos/tue-robotics/tue_robocup/commits{/sha}","git_commits_url":"https://api.github.com/repos/tue-robotics/tue_robocup/git/commits{/sha}","comments_url":"https://api.github.com/repos/tue-robotics/tue_robocup/comments{/number}","issue_comment_url":"https://api.github.com/repos/tue-robotics/tue_robocup/issues/comments{/number}","contents_url":"https://api.github.com/repos/tue-robotics/tue_robocup/contents/{+path}","compare_url":"https://api.github.com/repos/tue-robotics/tue_robocup/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tue-robotics/tue_robocup/merges","archive_url":"https://api.github.com/repos/tue-robotics/tue_robocup/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tue-robotics/tue_robocup/downloads","issues_url":"https://api.github.com/repos/tue-robotics/tue_robocup/issues{/number}","pulls_url":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls{/number}","milestones_url":"https://api.github.com/repos/tue-robotics/tue_robocup/milestones{/number}","notifications_url":"https://api.github.com/repos/tue-robotics/tue_robocup/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tue-robotics/tue_robocup/labels{/name}","releases_url":"https://api.github.com/repos/tue-robotics/tue_robocup/releases{/id}","deployments_url":"https://api.github.com/repos/tue-robotics/tue_robocup/deployments","created_at":"2014-12-02T13:21:13Z","updated_at":"2017-02-19T06:20:19Z","pushed_at":"2017-03-11T14:44:09Z","git_url":"git://github.com/tue-robotics/tue_robocup.git","ssh_url":"git@github.com:tue-robotics/tue_robocup.git","clone_url":"https://github.com/tue-robotics/tue_robocup.git","svn_url":"https://github.com/tue-robotics/tue_robocup","homepage":"","size":74876,"stargazers_count":6,"watchers_count":6,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":27,"forks":0,"open_issues":27,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/184"},"html":{"href":"https://github.com/tue-robotics/tue_robocup/pull/184"},"issue":{"href":"https://api.github.com/repos/tue-robotics/tue_robocup/issues/184"},"comments":{"href":"https://api.github.com/repos/tue-robotics/tue_robocup/issues/184/comments"},"review_comments":{"href":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/184/comments"},"review_comment":{"href":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/tue-robotics/tue_robocup/pulls/184/commits"},"statuses":{"href":"https://api.github.com/repos/tue-robotics/tue_robocup/statuses/221621708398a0204134b346dc85824104f126b7"}}}}
{"actor":{"display_login":"LoyVanBeek"}}