{ "info": { "author": "Kevin Walchko", "author_email": "walchko@noreply.github.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Operating System :: Unix", "Programming Language :: Python :: 3.7", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Scientific/Engineering :: Image Recognition", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# :lizard: pyGecko\n\n## My robot software.\n\n- Doesn't use [ROS](http://ros.org), ROS is a pain to install and maintain\non macOS and various linux systems\n - Uses some of the same ideas, constructs, architecture ideas, APIs but\n not strictly adhering to them\n- Uses [Zero MQ](http://http://zeromq.org/) as the inter-process communication\n(uses both TCP and UDS) instead of RPC-XML\n - looked at Google's protobuf, but was more complex than I needed\n - using [`msgpack`](https://msgpack.org/index.html) to serialize data currently,\n but could be changed to something different \n - instead of `roscore` use `geckocore.py` as the message hub\n - produces performance data (see below)\n - instead of `roslaunch` use `geckolaunch.py`\n- `json` - config and launch files\n- All of this runs on [Raspberry Pi 3](http://www.raspberrypi.org)\n - Also runs on macOS (UNIX)\n\n# Architecture\n\n![](pics/multiprocess-2.png)\n\n- GeckoCore is a hub that tracks what computer publishes what topic and prints\nnode cpu/memory usage\n - Actually, when gecko processes start up, they tell geckocore their pid\n numbers so it can track usage using `psutil` library\n - Obviously this only works on processes located on the same machine as geckocore\n - GeckoCore really just displays info and keeps track of publisher topics/addresses\n- Any number of pubs can talk to any number of sub ... it is not a one-to-one relationship\n- Pubs/Subs can exist on remote machines\n - If a Pub/Sub is on a remote machine, then it's performance data is not displayed\n - There currently is no mechanism to get the remote performance data\n\n## `geckocore.py`\n\n![](pics/multiprocess-3.png)\n\n1. Binder opens a random port for data\n 1. Note: either a publisher or a subscriber can bind to a port\n1. Binder tells GeckoCore the topic and address/port\n1. GeckoCore acknowledges the binder\n1. A connector wants to connect to a topic and asks GeckoCore for the address/port\n1. GeckoCore:\n 1. If topic is found, return the address/port and an ok status\n 1. If topic is *not* found, returns None\n1. Connector connects to the binder with the given address/port\n 1. *Binder:* only 1 per port, can be either pub or sub\n 1. *Connecter:* can be many per port, can be pub or sub\n\nThis is the main message hub. GeckoCore also is passed the PIDs for processes on the\nlocal machine and prints performance data on each process:\n\n```bash\n+========================================\n| Processes Performance\n| [24790] GeckoCore............. cpu: 0.3% mem: 0.0%\n| [24793] pub_ryan.............. cpu: 0.1% mem: 0.0%\n| [24795] pub_mike.............. cpu: 0.1% mem: 0.0%\n| [24796] sub_mike.............. cpu: 20.5% mem: 0.0%\n| [24797] pub_sammie............ cpu: 0.1% mem: 0.0%\n| [24798] sub_sammie............ cpu: 20.5% mem: 0.0%\n+------------------------------\n| ESTABLISHED Connections\n| pub_mike............ 192.168.86.22:50551 --> 192.168.86.22:50557\n| sub_mike............ 192.168.86.22:50557 --> 192.168.86.22:50551\n| pub_sammie.......... 192.168.86.22:50554 --> 192.168.86.22:50558\n| sub_sammie.......... 192.168.86.22:50558 --> 192.168.86.22:50554\n+------------------------------\n| LISTEN Connections\n| GeckoCore........... 192.168.86.22:11311\n| pub_ryan............ 192.168.86.22:50548\n| pub_mike............ 192.168.86.22:50551\n| pub_sammie.......... 192.168.86.22:50554\n+========================================\n| Published Topics @tcp://:\n| 1: ryan@tcp://192.168.86.22:50548\n| 2: mike@tcp://192.168.86.22:50551\n| 3: sammie@tcp://192.168.86.22:50554\n+========================================\n```\n\n```bash\n========================================\n Geckocore [65975]\n-------------\n Key: local\n Host IP: 10.0.1.57\n Listening on: 224.3.29.110:11311\n-------------\nKnown Services [6]\n * hello:........................ tcp://10.0.1.57:65303\n * hey there:.................... tcp://10.0.1.57:65304\n * ryan:......................... tcp://10.0.1.57:65310\n * mike:......................... tcp://10.0.1.57:65311\n * sammie:....................... tcp://10.0.1.57:65312\n * scott:........................ tcp://10.0.1.57:65313\n\nBinders [6]\n [65993] hello................. cpu: 0.0% mem: 0.0%\n [65994] hey there............. cpu: 0.0% mem: 0.0%\n [66008] ryan.................. cpu: 0.1% mem: 0.0%\n [66010] mike.................. cpu: 0.1% mem: 0.0%\n [66012] sammie................ cpu: 0.1% mem: 0.0%\n [66014] scott................. cpu: 0.1% mem: 0.0%\n\nConnections [8]\n [65995] hello................. cpu: 20.7% mem: 0.0%\n [65996] hello................. cpu: 20.9% mem: 0.0%\n [65997] hey there............. cpu: 21.0% mem: 0.0%\n [65998] hey there............. cpu: 20.8% mem: 0.0%\n [66011] mike.................. cpu: 19.0% mem: 0.0%\n [66013] sammie................ cpu: 19.0% mem: 0.0%\n [66015] scott................. cpu: 19.4% mem: 0.0%\n [66009] ryan.................. cpu: 18.7% mem: 0.0%\n```\n\n## `geckolaunch.py`\n\n`geckolaunch.py` allows you to launch a bunch of processes quickly using a launch\nfile. A launch file is just a simple json file where each line takes the form:\n`[file, function, kwargs]`. Here is an example:\n\n```bash\n{\n \"processes\":\n [\n [\"process\", \"publish\", {\"topic\": \"hello\"}],\n [\"process\", \"publish\", {\"topic\": \"hey there\"}],\n [\"process\", \"subscribe2\", {\"topic\": \"hello\"}],\n [\"process\", \"subscribe2\", {\"topic\": \"hello\"}],\n [\"process\", \"subscribe2\", {\"topic\": \"hey there\"}],\n [\"process\", \"subscribe2\", {\"topic\": \"hey there\"}],\n [\"process\", \"subscribe2\", {\"topic\": \"cv\"}],\n [\"process\", \"subscribe2\", {\"topic\": \"cv\"}],\n [\"process\", \"pcv\", {\"topic\": \"cv\"}]\n ],\n \"geckocore\": {\n \"host\": \"localhost\" # or hostname.local\n }\n}\n```\n\n## `geckopy`\n\nSee the examples, but this acts like a `rospy` and helps make writing\npub/sub processes easy. See the `/examples` folder to see it in action.\n\n- **init_node:** this sets up the the process for communications with `geckocore`\n- **logxxx:** prints log messages\n ```python\n from pygecko import geckopy\n geckopy.loginfo('this is a info message') # just send a string\n geckopy.logwarn('this is a warning message')\n geckopy.logerror('this is a error message')\n geckopy.logdebug('this is a debug message')\n ```\n- **Subscriber:** creates a subscriber and appends the callback function to an\narray in geckopy\n- **Publisher:** creates a publisher and returns it\n- **Rate:** given a frequency of how often a loop should run (i.e., 10Hz), the\nreturned object will dynamically set the sleep interval to achieve the rate. Ex:\n ```python\n from pygecko import geckopy\n rate = geckopy.Rate(20) # run loop at 20 Hz\n while True:\n rate.sleep()\n ```\n\n# Basic User API\n\n- geckopy.*\n - init_node(kwargs)\n - logX(test, topic='log')\n - X: Error, Debug, Info, Warning\n - is_shutdown()\n - Publisher(topics, addr=None, queue_size=10, bind=True)\n - Subscriber(topics, callback=None, addr=None, bind=False)\n\n# Change Log\n\nDate |Version| Notes\n------------|-------|---------------------------------\n2019-May-18 | 1.3.0 | working with c++\n2019-Mar-02 | 1.2.0 | set multicast as the default method to find nodes\n2018-Oct-28 | 1.1.0 | simplified and removed geckocore as the main hub\n2018-Sep-16 | 1.0.3 | implemented a multicast connection process\n2018-Sep-16 | 1.0.2 | dropping python 2.7 support, only 3.7+\n2018-Sep-11 | 1.0.1 | working, but still need to flush it out some more\n2018-Jul-28 | 1.0.0 | totally nuked everything from orbit and started over\n2017-May-14 | 0.8.3 | updates and refactor\n2017-Apr-02 | 0.8.2 | fix pypi doc and refactor\n2017-Mar-19 | 0.7.0 | refactored\n2017-Mar-12 | 0.6.0 | changed messages from dict to classes\n2016-Dec-26 | 0.5.0 | refactor\n2016-Oct-09 | 0.4.1 | published to PyPi\n2010-Mar-10 | 0.0.1 | init\n\n\n# MIT License\n\n**Copyright (c) 2010 Kevin J. Walchko**\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/MomsFriendlyRobotCompany/pygecko", "keywords": "framework,robotic,robot,vision,ros,distributed", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "pygecko", "package_url": "https://pypi.org/project/pygecko/", "platform": "", "project_url": "https://pypi.org/project/pygecko/", "project_urls": { "Homepage": "https://github.com/MomsFriendlyRobotCompany/pygecko" }, "release_url": "https://pypi.org/project/pygecko/1.3.0/", "requires_dist": [ "pyyaml", "psutil", "simplejson", "msgpack", "pyzmq", "colorama", "numpy", "build-utils" ], "requires_python": "", "summary": "A python robotic framework and tools", "version": "1.3.0" }, "last_serial": 5286919, "releases": { "0.4.0": [], "0.4.1": [ { "comment_text": "", "digests": { "md5": "60ad362da51dddafb59d572980b62298", "sha256": "a89fdd1d0c2698697f1970a100a72d59b25123ca7e95a001a1f879fa8649b387" }, "downloads": -1, "filename": "pygecko-0.4.1-py2-none-any.whl", "has_sig": false, "md5_digest": "60ad362da51dddafb59d572980b62298", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 46632, "upload_time": "2016-10-09T20:12:25", "url": "https://files.pythonhosted.org/packages/80/71/4d55084ea906b1c0af477a506a71542d7313c05a2ee7a82b752128f211f3/pygecko-0.4.1-py2-none-any.whl" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "4e8822010de4010e9cb154733d507458", "sha256": "a93b635068a6415c5a711d0facf5a17ad21c259c92fcc2e8c31f0857fb4b938d" }, "downloads": -1, "filename": "pygecko-0.4.2-py2-none-any.whl", "has_sig": false, "md5_digest": "4e8822010de4010e9cb154733d507458", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 46625, "upload_time": "2016-10-09T20:19:13", "url": "https://files.pythonhosted.org/packages/c9/86/856415337f133188b36b2252184de37a2ed4242674a619b6cf5347cf6146/pygecko-0.4.2-py2-none-any.whl" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "c1f367100cf42274455b12af8b90f5f7", "sha256": "04b0cd0e277589fd542947d9dbea82023d3c742e78122e12ce8a68a5934442b7" }, "downloads": -1, "filename": "pygecko-0.5.0-py2-none-any.whl", "has_sig": false, "md5_digest": "c1f367100cf42274455b12af8b90f5f7", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 47361, "upload_time": "2016-12-30T19:51:38", "url": "https://files.pythonhosted.org/packages/f2/0b/f75fe22b86a3a291a389f4b1c3724d3fb1e8c73256d2dac531168bc48dc5/pygecko-0.5.0-py2-none-any.whl" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "0e1ec72f31942349698191b3d517053b", "sha256": "db4d567530001924e3238da5a27b44c4e8750748f40465cf9284a48767b36c86" }, "downloads": -1, "filename": "pygecko-0.5.2-py2-none-any.whl", "has_sig": false, "md5_digest": "0e1ec72f31942349698191b3d517053b", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 49914, "upload_time": "2017-01-03T00:45:53", "url": "https://files.pythonhosted.org/packages/7b/1e/3589c61848e0423fda57b732b1345c9f2b5cc12ec79700d237415e11c894/pygecko-0.5.2-py2-none-any.whl" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "40e9dc4d7a7de094233da1402318d6bd", "sha256": "8782d93c055c858422f33798e4e5d5f98f005d2b55ad7d93a6c20fce5240cff0" }, "downloads": -1, "filename": "pygecko-0.7.0-py2-none-any.whl", "has_sig": false, "md5_digest": "40e9dc4d7a7de094233da1402318d6bd", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 33922, "upload_time": "2017-03-19T22:44:39", "url": "https://files.pythonhosted.org/packages/ee/e6/c610ac67e69993b0d9b1f08477ff9800d6eaae4df8486e1d5ef306292ee1/pygecko-0.7.0-py2-none-any.whl" } ], "0.7.1": [ { "comment_text": "", "digests": { "md5": "f138bfd7c03d8647c2acce492e653fb6", "sha256": "e1e858dd3381eb814cda9749a425c792fe10a6aa959669055bfa1d3cec1a6c11" }, "downloads": -1, "filename": "pygecko-0.7.1-py2-none-any.whl", "has_sig": false, "md5_digest": "f138bfd7c03d8647c2acce492e653fb6", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 33896, "upload_time": "2017-03-20T03:54:05", "url": "https://files.pythonhosted.org/packages/bc/0b/cbb8347536b3bb3143afc6830ae92e316ecf5a4b102c5a8a98157a05521a/pygecko-0.7.1-py2-none-any.whl" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "02cdedb26a8204024909a529eae54562", "sha256": "aad26f480a8e2ddf2b4d2e8b1d9673cfa4d7ab5bc1c89b3644abd2dc0b4e8da8" }, "downloads": -1, "filename": "pygecko-0.8.0-py2-none-any.whl", "has_sig": false, "md5_digest": "02cdedb26a8204024909a529eae54562", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 34208, "upload_time": "2017-04-03T01:52:34", "url": "https://files.pythonhosted.org/packages/fa/6f/a566e0c8a959d22409300965466758f4a6aafa3dc70a551f33df7faf75c8/pygecko-0.8.0-py2-none-any.whl" } ], "0.8.1": [ { "comment_text": "", "digests": { "md5": "8c7ea037b950dae49b5216df3303ff56", "sha256": "135c7c526f9184d29c4c1685ac93d355ec512368c50b51320340791a2edd4e22" }, "downloads": -1, "filename": "pygecko-0.8.1-py2-none-any.whl", "has_sig": false, "md5_digest": "8c7ea037b950dae49b5216df3303ff56", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 34072, "upload_time": "2017-04-03T02:15:02", "url": "https://files.pythonhosted.org/packages/f4/bd/0bf27dd68f134290578355b00acb9847a9296d2542572634d50e99ec2cf6/pygecko-0.8.1-py2-none-any.whl" } ], "0.8.2": [ { "comment_text": "", "digests": { "md5": "1dd7ae1d69b67ce5436efd4e892f7fff", "sha256": "69e06b741f87b85294bfba76efa519ea188e7a00c5c871e232888829c86c0245" }, "downloads": -1, "filename": "pygecko-0.8.2-py2-none-any.whl", "has_sig": false, "md5_digest": "1dd7ae1d69b67ce5436efd4e892f7fff", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 34110, "upload_time": "2017-04-03T02:23:39", "url": "https://files.pythonhosted.org/packages/b4/19/6efb5128abdf18d9339e1f3059dc4e058858d64855efc569ea1f4e5fa5d9/pygecko-0.8.2-py2-none-any.whl" } ], "0.8.3": [ { "comment_text": "", "digests": { "md5": "8b3e951d715e2637807cbe3de1302f79", "sha256": "468474a2db3e90b961810953acb1c5cf8d2a943abf513a6f57d016021bf85874" }, "downloads": -1, "filename": "pygecko-0.8.3-py2-none-any.whl", "has_sig": false, "md5_digest": "8b3e951d715e2637807cbe3de1302f79", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 34689, "upload_time": "2017-05-14T18:27:13", "url": "https://files.pythonhosted.org/packages/e7/52/10f8a666971bd0cedbc9c5d2fa16943f7014770285cd1e52dedd6315632d/pygecko-0.8.3-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "feb4c9eb64f3e56a0941e93a346e64cc", "sha256": "1bfc2aa979e6b18980e901a98ccaa1d994e6510a466cb5e8337c93a5a5143407" }, "downloads": -1, "filename": "pygecko-0.8.3.tar.gz", "has_sig": false, "md5_digest": "feb4c9eb64f3e56a0941e93a346e64cc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26078, "upload_time": "2017-05-14T18:27:16", "url": "https://files.pythonhosted.org/packages/ea/c1/bd4582c2892ccbc6e725bd191dc4f7cde69b5346e7e4bb6dd75924bb77c8/pygecko-0.8.3.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "cd58b39839dd0ac3b36e3be5002e23b0", "sha256": "ae3385e270816d535481fd1bef35aa03c82a4130be960e9ec30f188299237a0a" }, "downloads": -1, "filename": "pygecko-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "cd58b39839dd0ac3b36e3be5002e23b0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 13877, "upload_time": "2018-09-16T19:30:00", "url": "https://files.pythonhosted.org/packages/5d/51/e673407c293a12eef859bd2c3da688bcbc06409c41573c52ca39aa8c6344/pygecko-1.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "db69a6e74737addf4ec5a949cfe89195", "sha256": "491f5d0ff8c9339eb7f4218f56424742dfad47fca66fcd4cdc8db594bd587c9a" }, "downloads": -1, "filename": "pygecko-1.0.2.tar.gz", "has_sig": false, "md5_digest": "db69a6e74737addf4ec5a949cfe89195", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11012, "upload_time": "2018-09-16T19:30:01", "url": "https://files.pythonhosted.org/packages/5e/6c/4bfd38bfd0dddd44085d08d711d7c7924bab0ff541d115dd88ccdad9c93e/pygecko-1.0.2.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "f4d9ceebecee843737622b2fad4ad84d", "sha256": "2d901e8e8f7716b594744e0f4aa70c4f1d50e6325bf86048fdefadcabce6b986" }, "downloads": -1, "filename": "pygecko-1.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "f4d9ceebecee843737622b2fad4ad84d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16226, "upload_time": "2019-05-19T00:07:40", "url": "https://files.pythonhosted.org/packages/8c/a0/7409bdd79ab46ca5f4bbc4caf642d7d537e3517ddcc236554aa592f73193/pygecko-1.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "34b1b6d59144ff083eec4b7301a778c5", "sha256": "258180c2c9de1d08b048970534a35b6b2d0997aebc5ef5b9241e3136b53f1385" }, "downloads": -1, "filename": "pygecko-1.3.0.tar.gz", "has_sig": false, "md5_digest": "34b1b6d59144ff083eec4b7301a778c5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15482, "upload_time": "2019-05-19T00:07:42", "url": "https://files.pythonhosted.org/packages/b4/b0/2feeb025489a9eaf03a597511aba2f63b4a3724be74d1cf85670bfa13092/pygecko-1.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f4d9ceebecee843737622b2fad4ad84d", "sha256": "2d901e8e8f7716b594744e0f4aa70c4f1d50e6325bf86048fdefadcabce6b986" }, "downloads": -1, "filename": "pygecko-1.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "f4d9ceebecee843737622b2fad4ad84d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16226, "upload_time": "2019-05-19T00:07:40", "url": "https://files.pythonhosted.org/packages/8c/a0/7409bdd79ab46ca5f4bbc4caf642d7d537e3517ddcc236554aa592f73193/pygecko-1.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "34b1b6d59144ff083eec4b7301a778c5", "sha256": "258180c2c9de1d08b048970534a35b6b2d0997aebc5ef5b9241e3136b53f1385" }, "downloads": -1, "filename": "pygecko-1.3.0.tar.gz", "has_sig": false, "md5_digest": "34b1b6d59144ff083eec4b7301a778c5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15482, "upload_time": "2019-05-19T00:07:42", "url": "https://files.pythonhosted.org/packages/b4/b0/2feeb025489a9eaf03a597511aba2f63b4a3724be74d1cf85670bfa13092/pygecko-1.3.0.tar.gz" } ] }