├── .gitignore ├── Arduino_test_file ├── README.md ├── arduino_example.png └── example1 │ └── example1.ino ├── LICENSE ├── Makefile ├── Pyquino.e4p ├── README.md ├── core ├── Ui_mainwindow.py ├── __init__.py ├── __init__.pyc ├── gcode │ ├── gcodeParser.py │ ├── mainwindow.ui │ └── test1.gcode ├── graphy │ ├── Ui_graphy.py │ ├── __init__.py │ ├── graphy.py │ └── graphy.ui ├── graphy_test.py ├── info.py ├── mainwindow.py ├── mainwindow.pyc ├── mainwindow.ui ├── monitor │ ├── Ui_machine_mointor.py │ ├── __init__.py │ ├── machine_mointor.py │ ├── machine_mointor.ui │ └── mainwindow.ui ├── serialportcontext.py ├── serialportedittext.py ├── vrep │ ├── Ui_vrep_setting.py │ ├── vrep_setting.py │ ├── vrep_setting.ui │ └── vrep_test.py └── vrep_remoAPI │ ├── one_link_robot_remoteAPI_joint_position.py │ ├── remoteApi.dll │ ├── remoteApi.so │ ├── vrep.py │ └── vrepConst.py ├── data.txt ├── icons.qrc ├── icons ├── END ├── START ├── arduino_example.png ├── arrow-down-a.png ├── arrow-down-b.png ├── arrow-left-b.png ├── arrow-right-b.png ├── arrow-up-a.png ├── arrow-up-b.png ├── cover.png ├── serialport.png ├── usb.ico └── usb.png ├── icons_rc.py ├── launchPyquino.py ├── pnael.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/* 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | 103 | # eric6 104 | _eric6project/ 105 | .eric6project/ 106 | 107 | # pycharm 108 | *.idle 109 | *.idea 110 | -------------------------------------------------------------------------------- /Arduino_test_file/README.md: -------------------------------------------------------------------------------- 1 | Arduino Example 2 | === 3 | 4 | use Arduino Ide upload the code in the example code. 5 | 6 | ![](arduino_example.png) 7 | 8 | ##Windows system 9 | 10 | you need to check you COM Port and setup the correct number in Pyquino. 11 | 12 | ##Linux system 13 | 14 | you can use this bash to checkout the controller . 15 | 16 | ```bash 17 | #!/bin/bash 18 | 19 | for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do 20 | ( 21 | syspath="${sysdevpath%/dev}" 22 | devname="$(udevadm info -q name -p $syspath)" 23 | [[ "$devname" == "bus/"* ]] && continue 24 | eval "$(udevadm info -q property --export -p $syspath)" 25 | [[ -z "$ID_SERIAL" ]] && continue 26 | echo "/dev/$devname - $ID_SERIAL" 27 | ) 28 | done 29 | ``` 30 | 31 | On my system ,the result in the following: 32 | 33 | ```bash 34 | /dev/input/event14 - 1bcf_USB_Optical_Mouse 35 | /dev/input/mouse1 - 1bcf_USB_Optical_Mouse 36 | /dev/input/event4 - Logitech_USB_Optical_Mouse 37 | /dev/input/mouse0 - Logitech_USB_Optical_Mouse 38 | /dev/ttyACM0 - Arduino__www.arduino.cc__0042_75439313637351511181 39 | /dev/sdb - Generic-_Compact_Flash_20070818000000000-0:0 40 | /dev/sdc - Generic-_SM_xD-Picture_20070818000000000-0:1 41 | /dev/sdd - Generic-_SD_MMC_20070818000000000-0:2 42 | /dev/sde - Generic-_MS_MS-Pro_20070818000000000-0:3 43 | 44 | done 45 | ``` 46 | 47 | you can see the controller in ttyACM0,setup the Pyquino in tty/ACM0 48 | 49 | can get communcation with Arduino controller 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Arduino_test_file/arduino_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/Arduino_test_file/arduino_example.png -------------------------------------------------------------------------------- /Arduino_test_file/example1/example1.ino: -------------------------------------------------------------------------------- 1 | String get; 2 | 3 | void setup() { 4 | 5 | //setting baurd rate 6 | Serial.begin(115200); 7 | 8 | } 9 | 10 | void loop(){ 11 | while (Serial.available() >0 ) 12 | { 13 | Serial.println("please send somthing"); 14 | if (Serial.available() >0 ){ 15 | 16 | get = Serial.readString(); 17 | Serial.println(get); 18 | } 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #Pyquino Makefile 2 | 3 | all: build run 4 | 5 | build: launchPyquino.py 6 | pyinstaller -F $< -i ./icons/usb.ico \ 7 | --path="C:\Users\Lin\AppData\Local\Programs\Python\Python35\Lib\site-packages\PyQt5\Qt\bin" \ 8 | --add-binary="core/vrep_remoAPI/remoteApi.dll;." 9 | 10 | run: build dist\launchPyquino.exe 11 | dist\launchPyquino.exe 12 | 13 | clean: 14 | rd build /s /q 15 | rd dist /s /q 16 | del launchPyquino.spec 17 | -------------------------------------------------------------------------------- /Pyquino.e4p: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | en_US 8 | 8d8c945a40b503b8eb2f0c180a0c11995a1eaa1a 9 | Python3 10 | PyQt5 11 | 0.1 12 | you-sheng 13 | 14 | 15 | 16 | core/Ui_mainwindow.py 17 | core/__init__.py 18 | core/gcode/gcodeParser.py 19 | core/graphy/Ui_graphy.py 20 | core/graphy/__init__.py 21 | core/graphy/graphy.py 22 | core/graphy_test.py 23 | core/info.py 24 | core/mainwindow.py 25 | core/monitor/Ui_machine_mointor.py 26 | core/monitor/__init__.py 27 | core/monitor/machine_mointor.py 28 | core/serialportcontext.py 29 | core/serialportedittext.py 30 | core/vrep/Ui_vrep_setting.py 31 | core/vrep/vrep_setting.py 32 | core/vrep/vrep_test.py 33 | core/vrep_remoAPI/one_link_robot_remoteAPI_joint_position.py 34 | core/vrep_remoAPI/vrep.py 35 | core/vrep_remoAPI/vrepConst.py 36 | icons_rc.py 37 | launchPyquino.py 38 | opgl_class.py 39 | pnael.py 40 | test.py 41 | test1.py 42 | 43 | 44 |
core/gcode/mainwindow.ui
45 |
core/graphy/graphy.ui
46 |
core/mainwindow.ui
47 |
core/monitor/machine_mointor.ui
48 |
core/monitor/mainwindow.ui
49 |
core/vrep/vrep_setting.ui
50 |
51 | 52 | 53 | icons.qrc 54 | 55 | 56 | 57 | Arduino_test_file/README.md 58 | Makefile 59 | 60 | launchPyquino.py 61 | 62 | None 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Pyquino 2 | === 3 | 4 | python3 + PyQt5 + Arduino 5 | 6 | A Gui-Base tools with pyserial and PyQt5 for communcation to machine. 7 | 8 | and will control the simulation of Vrep. 9 | 10 | ![](icons/cover.png) 11 | 12 | How to use it ? 13 | --- 14 | 15 | Open GUI by Python: 16 | 17 |
18 | $pip3 install requirements.txt 
19 | 
20 | $python3 launchPyquino.py
21 | 
22 | 
23 | 24 | The vrep option is for specific machine control system on the simulation of Vrep. 25 | 26 | The .ttt file will update Recently 27 | 28 | 29 | Power By 30 | --- 31 | 32 | Made by [PyQt 5.7](http://doc.qt.io/qt-5/index.html) and [Eric 6.18](http://eric-ide.python-projects.org/). 33 | 34 | This tool is not complete. 35 | 36 | 37 | -------------------------------------------------------------------------------- /core/Ui_mainwindow.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file '/home/kmol/桌面/Pyquino/core/mainwindow.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.7.1 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_MainWindow(object): 12 | def setupUi(self, MainWindow): 13 | MainWindow.setObjectName("MainWindow") 14 | MainWindow.resize(859, 526) 15 | palette = QtGui.QPalette() 16 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 17 | brush.setStyle(QtCore.Qt.SolidPattern) 18 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush) 19 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 20 | brush.setStyle(QtCore.Qt.SolidPattern) 21 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush) 22 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 23 | brush.setStyle(QtCore.Qt.SolidPattern) 24 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Dark, brush) 25 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 26 | brush.setStyle(QtCore.Qt.SolidPattern) 27 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) 28 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 29 | brush.setStyle(QtCore.Qt.SolidPattern) 30 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.BrightText, brush) 31 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 32 | brush.setStyle(QtCore.Qt.SolidPattern) 33 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) 34 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 35 | brush.setStyle(QtCore.Qt.SolidPattern) 36 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush) 37 | brush = QtGui.QBrush(QtGui.QColor(164, 169, 173)) 38 | brush.setStyle(QtCore.Qt.SolidPattern) 39 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush) 40 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 41 | brush.setStyle(QtCore.Qt.SolidPattern) 42 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.HighlightedText, brush) 43 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 44 | brush.setStyle(QtCore.Qt.SolidPattern) 45 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush) 46 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 47 | brush.setStyle(QtCore.Qt.SolidPattern) 48 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush) 49 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 50 | brush.setStyle(QtCore.Qt.SolidPattern) 51 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Dark, brush) 52 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 53 | brush.setStyle(QtCore.Qt.SolidPattern) 54 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) 55 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 56 | brush.setStyle(QtCore.Qt.SolidPattern) 57 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.BrightText, brush) 58 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 59 | brush.setStyle(QtCore.Qt.SolidPattern) 60 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) 61 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 62 | brush.setStyle(QtCore.Qt.SolidPattern) 63 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush) 64 | brush = QtGui.QBrush(QtGui.QColor(164, 169, 173)) 65 | brush.setStyle(QtCore.Qt.SolidPattern) 66 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush) 67 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 68 | brush.setStyle(QtCore.Qt.SolidPattern) 69 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.HighlightedText, brush) 70 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 71 | brush.setStyle(QtCore.Qt.SolidPattern) 72 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush) 73 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 74 | brush.setStyle(QtCore.Qt.SolidPattern) 75 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush) 76 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 77 | brush.setStyle(QtCore.Qt.SolidPattern) 78 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Dark, brush) 79 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 80 | brush.setStyle(QtCore.Qt.SolidPattern) 81 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush) 82 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 83 | brush.setStyle(QtCore.Qt.SolidPattern) 84 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.BrightText, brush) 85 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 86 | brush.setStyle(QtCore.Qt.SolidPattern) 87 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) 88 | brush = QtGui.QBrush(QtGui.QColor(164, 169, 173)) 89 | brush.setStyle(QtCore.Qt.SolidPattern) 90 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush) 91 | brush = QtGui.QBrush(QtGui.QColor(164, 169, 173)) 92 | brush.setStyle(QtCore.Qt.SolidPattern) 93 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush) 94 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 95 | brush.setStyle(QtCore.Qt.SolidPattern) 96 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.HighlightedText, brush) 97 | MainWindow.setPalette(palette) 98 | icon = QtGui.QIcon() 99 | icon.addPixmap(QtGui.QPixmap(":/icons/usb.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 100 | MainWindow.setWindowIcon(icon) 101 | MainWindow.setAutoFillBackground(True) 102 | self.centralWidget = QtWidgets.QWidget(MainWindow) 103 | self.centralWidget.setObjectName("centralWidget") 104 | self.verticalLayout = QtWidgets.QVBoxLayout(self.centralWidget) 105 | self.verticalLayout.setObjectName("verticalLayout") 106 | self.tabWidget = QtWidgets.QTabWidget(self.centralWidget) 107 | palette = QtGui.QPalette() 108 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 109 | brush.setStyle(QtCore.Qt.SolidPattern) 110 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush) 111 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 112 | brush.setStyle(QtCore.Qt.SolidPattern) 113 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) 114 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 115 | brush.setStyle(QtCore.Qt.SolidPattern) 116 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) 117 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 118 | brush.setStyle(QtCore.Qt.SolidPattern) 119 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush) 120 | brush = QtGui.QBrush(QtGui.QColor(164, 169, 173)) 121 | brush.setStyle(QtCore.Qt.SolidPattern) 122 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush) 123 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 124 | brush.setStyle(QtCore.Qt.SolidPattern) 125 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush) 126 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 127 | brush.setStyle(QtCore.Qt.SolidPattern) 128 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) 129 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 130 | brush.setStyle(QtCore.Qt.SolidPattern) 131 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) 132 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 133 | brush.setStyle(QtCore.Qt.SolidPattern) 134 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush) 135 | brush = QtGui.QBrush(QtGui.QColor(164, 169, 173)) 136 | brush.setStyle(QtCore.Qt.SolidPattern) 137 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush) 138 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 139 | brush.setStyle(QtCore.Qt.SolidPattern) 140 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush) 141 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 142 | brush.setStyle(QtCore.Qt.SolidPattern) 143 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush) 144 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 145 | brush.setStyle(QtCore.Qt.SolidPattern) 146 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) 147 | brush = QtGui.QBrush(QtGui.QColor(164, 169, 173)) 148 | brush.setStyle(QtCore.Qt.SolidPattern) 149 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush) 150 | brush = QtGui.QBrush(QtGui.QColor(164, 169, 173)) 151 | brush.setStyle(QtCore.Qt.SolidPattern) 152 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush) 153 | self.tabWidget.setPalette(palette) 154 | self.tabWidget.setAutoFillBackground(True) 155 | self.tabWidget.setTabsClosable(False) 156 | self.tabWidget.setObjectName("tabWidget") 157 | self.tab = QtWidgets.QWidget() 158 | palette = QtGui.QPalette() 159 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 160 | brush.setStyle(QtCore.Qt.SolidPattern) 161 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) 162 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 163 | brush.setStyle(QtCore.Qt.SolidPattern) 164 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.BrightText, brush) 165 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 166 | brush.setStyle(QtCore.Qt.SolidPattern) 167 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) 168 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 169 | brush.setStyle(QtCore.Qt.SolidPattern) 170 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.HighlightedText, brush) 171 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 172 | brush.setStyle(QtCore.Qt.SolidPattern) 173 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) 174 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 175 | brush.setStyle(QtCore.Qt.SolidPattern) 176 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.BrightText, brush) 177 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 178 | brush.setStyle(QtCore.Qt.SolidPattern) 179 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) 180 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 181 | brush.setStyle(QtCore.Qt.SolidPattern) 182 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.HighlightedText, brush) 183 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 184 | brush.setStyle(QtCore.Qt.SolidPattern) 185 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush) 186 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 187 | brush.setStyle(QtCore.Qt.SolidPattern) 188 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.BrightText, brush) 189 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 190 | brush.setStyle(QtCore.Qt.SolidPattern) 191 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) 192 | brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) 193 | brush.setStyle(QtCore.Qt.SolidPattern) 194 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.HighlightedText, brush) 195 | self.tab.setPalette(palette) 196 | self.tab.setObjectName("tab") 197 | self.groupBox = QtWidgets.QGroupBox(self.tab) 198 | self.groupBox.setGeometry(QtCore.QRect(20, 20, 231, 361)) 199 | font = QtGui.QFont() 200 | font.setPointSize(10) 201 | self.groupBox.setFont(font) 202 | self.groupBox.setObjectName("groupBox") 203 | self.comboBoxPort = QtWidgets.QComboBox(self.groupBox) 204 | self.comboBoxPort.setGeometry(QtCore.QRect(90, 30, 121, 31)) 205 | self.comboBoxPort.setObjectName("comboBoxPort") 206 | self.label_2 = QtWidgets.QLabel(self.groupBox) 207 | self.label_2.setGeometry(QtCore.QRect(10, 30, 71, 21)) 208 | font = QtGui.QFont() 209 | font.setPointSize(14) 210 | self.label_2.setFont(font) 211 | self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) 212 | self.label_2.setObjectName("label_2") 213 | self.label = QtWidgets.QLabel(self.groupBox) 214 | self.label.setGeometry(QtCore.QRect(10, 80, 71, 21)) 215 | font = QtGui.QFont() 216 | font.setPointSize(14) 217 | self.label.setFont(font) 218 | self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) 219 | self.label.setObjectName("label") 220 | self.comboBoxBaud = QtWidgets.QComboBox(self.groupBox) 221 | self.comboBoxBaud.setGeometry(QtCore.QRect(90, 80, 121, 31)) 222 | self.comboBoxBaud.setObjectName("comboBoxBaud") 223 | self.label_3 = QtWidgets.QLabel(self.groupBox) 224 | self.label_3.setGeometry(QtCore.QRect(10, 130, 71, 21)) 225 | font = QtGui.QFont() 226 | font.setPointSize(14) 227 | self.label_3.setFont(font) 228 | self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) 229 | self.label_3.setObjectName("label_3") 230 | self.comboBoxCheckSum = QtWidgets.QComboBox(self.groupBox) 231 | self.comboBoxCheckSum.setGeometry(QtCore.QRect(90, 130, 121, 31)) 232 | self.comboBoxCheckSum.setObjectName("comboBoxCheckSum") 233 | self.label_4 = QtWidgets.QLabel(self.groupBox) 234 | self.label_4.setGeometry(QtCore.QRect(10, 180, 71, 21)) 235 | font = QtGui.QFont() 236 | font.setPointSize(14) 237 | self.label_4.setFont(font) 238 | self.label_4.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) 239 | self.label_4.setObjectName("label_4") 240 | self.comboBoxBits = QtWidgets.QComboBox(self.groupBox) 241 | self.comboBoxBits.setGeometry(QtCore.QRect(90, 180, 121, 31)) 242 | self.comboBoxBits.setObjectName("comboBoxBits") 243 | self.label_5 = QtWidgets.QLabel(self.groupBox) 244 | self.label_5.setGeometry(QtCore.QRect(10, 230, 71, 21)) 245 | font = QtGui.QFont() 246 | font.setPointSize(14) 247 | self.label_5.setFont(font) 248 | self.label_5.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) 249 | self.label_5.setObjectName("label_5") 250 | self.comboBoxStopBits = QtWidgets.QComboBox(self.groupBox) 251 | self.comboBoxStopBits.setGeometry(QtCore.QRect(90, 230, 121, 31)) 252 | self.comboBoxStopBits.setObjectName("comboBoxStopBits") 253 | self.pushButtonOpenSerial = QtWidgets.QPushButton(self.groupBox) 254 | self.pushButtonOpenSerial.setGeometry(QtCore.QRect(10, 280, 201, 31)) 255 | self.pushButtonOpenSerial.setObjectName("pushButtonOpenSerial") 256 | self.pushButtonSendData = QtWidgets.QPushButton(self.tab) 257 | self.pushButtonSendData.setGeometry(QtCore.QRect(740, 210, 61, 171)) 258 | self.pushButtonSendData.setAutoDefault(True) 259 | self.pushButtonSendData.setObjectName("pushButtonSendData") 260 | self.textEditReceived = QtWidgets.QTextEdit(self.tab) 261 | self.textEditReceived.setGeometry(QtCore.QRect(260, 20, 541, 181)) 262 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 263 | sizePolicy.setHorizontalStretch(0) 264 | sizePolicy.setVerticalStretch(0) 265 | sizePolicy.setHeightForWidth(self.textEditReceived.sizePolicy().hasHeightForWidth()) 266 | self.textEditReceived.setSizePolicy(sizePolicy) 267 | font = QtGui.QFont() 268 | font.setPointSize(14) 269 | self.textEditReceived.setFont(font) 270 | self.textEditReceived.setReadOnly(True) 271 | self.textEditReceived.setObjectName("textEditReceived") 272 | self.textEditSent = QtWidgets.QTextEdit(self.tab) 273 | self.textEditSent.setGeometry(QtCore.QRect(260, 210, 471, 171)) 274 | font = QtGui.QFont() 275 | font.setPointSize(14) 276 | self.textEditSent.setFont(font) 277 | self.textEditSent.setObjectName("textEditSent") 278 | self.tabWidget.addTab(self.tab, "") 279 | self.tab_2 = QtWidgets.QWidget() 280 | self.tab_2.setObjectName("tab_2") 281 | self.groupBox_2 = QtWidgets.QGroupBox(self.tab_2) 282 | self.groupBox_2.setGeometry(QtCore.QRect(20, 30, 521, 331)) 283 | self.groupBox_2.setObjectName("groupBox_2") 284 | self.yAxisup = QtWidgets.QPushButton(self.groupBox_2) 285 | self.yAxisup.setGeometry(QtCore.QRect(120, 20, 91, 61)) 286 | self.yAxisup.setText("") 287 | icon1 = QtGui.QIcon() 288 | icon1.addPixmap(QtGui.QPixmap(":/icons/arrow-up-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 289 | self.yAxisup.setIcon(icon1) 290 | self.yAxisup.setIconSize(QtCore.QSize(30, 30)) 291 | self.yAxisup.setObjectName("yAxisup") 292 | self.xAxisleft = QtWidgets.QPushButton(self.groupBox_2) 293 | self.xAxisleft.setGeometry(QtCore.QRect(0, 110, 91, 61)) 294 | self.xAxisleft.setText("") 295 | icon2 = QtGui.QIcon() 296 | icon2.addPixmap(QtGui.QPixmap(":/icons/arrow-left-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 297 | self.xAxisleft.setIcon(icon2) 298 | self.xAxisleft.setIconSize(QtCore.QSize(30, 30)) 299 | self.xAxisleft.setObjectName("xAxisleft") 300 | self.xAxisrigh = QtWidgets.QPushButton(self.groupBox_2) 301 | self.xAxisrigh.setGeometry(QtCore.QRect(230, 110, 91, 61)) 302 | self.xAxisrigh.setText("") 303 | icon3 = QtGui.QIcon() 304 | icon3.addPixmap(QtGui.QPixmap(":/icons/arrow-right-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 305 | self.xAxisrigh.setIcon(icon3) 306 | self.xAxisrigh.setIconSize(QtCore.QSize(30, 30)) 307 | self.xAxisrigh.setObjectName("xAxisrigh") 308 | self.yAxisdown = QtWidgets.QPushButton(self.groupBox_2) 309 | self.yAxisdown.setGeometry(QtCore.QRect(120, 190, 91, 61)) 310 | self.yAxisdown.setText("") 311 | icon4 = QtGui.QIcon() 312 | icon4.addPixmap(QtGui.QPixmap(":/icons/arrow-down-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 313 | self.yAxisdown.setIcon(icon4) 314 | self.yAxisdown.setIconSize(QtCore.QSize(30, 30)) 315 | self.yAxisdown.setObjectName("yAxisdown") 316 | self.zupButton = QtWidgets.QPushButton(self.groupBox_2) 317 | self.zupButton.setGeometry(QtCore.QRect(380, 20, 91, 61)) 318 | self.zupButton.setText("") 319 | icon5 = QtGui.QIcon() 320 | icon5.addPixmap(QtGui.QPixmap(":/icons/arrow-up-a.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 321 | self.zupButton.setIcon(icon5) 322 | self.zupButton.setIconSize(QtCore.QSize(30, 30)) 323 | self.zupButton.setObjectName("zupButton") 324 | self.zdownButton = QtWidgets.QPushButton(self.groupBox_2) 325 | self.zdownButton.setGeometry(QtCore.QRect(380, 220, 91, 51)) 326 | self.zdownButton.setText("") 327 | icon6 = QtGui.QIcon() 328 | icon6.addPixmap(QtGui.QPixmap(":/icons/arrow-down-a.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 329 | self.zdownButton.setIcon(icon6) 330 | self.zdownButton.setIconSize(QtCore.QSize(30, 30)) 331 | self.zdownButton.setObjectName("zdownButton") 332 | self.label_6 = QtWidgets.QLabel(self.groupBox_2) 333 | self.label_6.setGeometry(QtCore.QRect(380, 130, 81, 31)) 334 | self.label_6.setAlignment(QtCore.Qt.AlignCenter) 335 | self.label_6.setObjectName("label_6") 336 | self.unlockMachine = QtWidgets.QPushButton(self.groupBox_2) 337 | self.unlockMachine.setGeometry(QtCore.QRect(10, 290, 101, 31)) 338 | palette = QtGui.QPalette() 339 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 340 | brush.setStyle(QtCore.Qt.SolidPattern) 341 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) 342 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 343 | brush.setStyle(QtCore.Qt.SolidPattern) 344 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) 345 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 346 | brush.setStyle(QtCore.Qt.SolidPattern) 347 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) 348 | self.unlockMachine.setPalette(palette) 349 | self.unlockMachine.setObjectName("unlockMachine") 350 | self.label_7 = QtWidgets.QLabel(self.groupBox_2) 351 | self.label_7.setGeometry(QtCore.QRect(140, 130, 51, 21)) 352 | self.label_7.setObjectName("label_7") 353 | self.homeButton = QtWidgets.QPushButton(self.groupBox_2) 354 | self.homeButton.setGeometry(QtCore.QRect(130, 290, 91, 31)) 355 | palette = QtGui.QPalette() 356 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 357 | brush.setStyle(QtCore.Qt.SolidPattern) 358 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) 359 | brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) 360 | brush.setStyle(QtCore.Qt.SolidPattern) 361 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) 362 | brush = QtGui.QBrush(QtGui.QColor(30, 159, 131)) 363 | brush.setStyle(QtCore.Qt.SolidPattern) 364 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) 365 | self.homeButton.setPalette(palette) 366 | self.homeButton.setObjectName("homeButton") 367 | self.stepbox = QtWidgets.QSpinBox(self.groupBox_2) 368 | self.stepbox.setGeometry(QtCore.QRect(280, 290, 42, 20)) 369 | self.stepbox.setMaximum(100) 370 | self.stepbox.setSingleStep(0) 371 | self.stepbox.setProperty("value", 10) 372 | self.stepbox.setObjectName("stepbox") 373 | self.label_11 = QtWidgets.QLabel(self.groupBox_2) 374 | self.label_11.setGeometry(QtCore.QRect(230, 290, 51, 21)) 375 | font = QtGui.QFont() 376 | font.setPointSize(15) 377 | self.label_11.setFont(font) 378 | self.label_11.setAlignment(QtCore.Qt.AlignCenter) 379 | self.label_11.setObjectName("label_11") 380 | self.label_12 = QtWidgets.QLabel(self.groupBox_2) 381 | self.label_12.setGeometry(QtCore.QRect(320, 290, 51, 21)) 382 | font = QtGui.QFont() 383 | font.setPointSize(15) 384 | self.label_12.setFont(font) 385 | self.label_12.setAlignment(QtCore.Qt.AlignCenter) 386 | self.label_12.setObjectName("label_12") 387 | self.gridLayoutWidget = QtWidgets.QWidget(self.tab_2) 388 | self.gridLayoutWidget.setGeometry(QtCore.QRect(560, 40, 221, 141)) 389 | self.gridLayoutWidget.setObjectName("gridLayoutWidget") 390 | self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget) 391 | self.gridLayout.setContentsMargins(0, 0, 0, 0) 392 | self.gridLayout.setObjectName("gridLayout") 393 | self.label_8 = QtWidgets.QLabel(self.gridLayoutWidget) 394 | self.label_8.setAlignment(QtCore.Qt.AlignCenter) 395 | self.label_8.setObjectName("label_8") 396 | self.gridLayout.addWidget(self.label_8, 0, 0, 1, 1) 397 | self.xAxis = QtWidgets.QLCDNumber(self.gridLayoutWidget) 398 | self.xAxis.setObjectName("xAxis") 399 | self.gridLayout.addWidget(self.xAxis, 0, 1, 1, 1) 400 | self.label_9 = QtWidgets.QLabel(self.gridLayoutWidget) 401 | self.label_9.setAlignment(QtCore.Qt.AlignCenter) 402 | self.label_9.setObjectName("label_9") 403 | self.gridLayout.addWidget(self.label_9, 1, 0, 1, 1) 404 | self.yAxis = QtWidgets.QLCDNumber(self.gridLayoutWidget) 405 | self.yAxis.setObjectName("yAxis") 406 | self.gridLayout.addWidget(self.yAxis, 1, 1, 1, 1) 407 | self.zAxis = QtWidgets.QLCDNumber(self.gridLayoutWidget) 408 | self.zAxis.setObjectName("zAxis") 409 | self.gridLayout.addWidget(self.zAxis, 2, 1, 1, 1) 410 | self.label_10 = QtWidgets.QLabel(self.gridLayoutWidget) 411 | self.label_10.setAlignment(QtCore.Qt.AlignCenter) 412 | self.label_10.setObjectName("label_10") 413 | self.gridLayout.addWidget(self.label_10, 2, 0, 1, 1) 414 | self.textEditReceived2 = QtWidgets.QTextEdit(self.tab_2) 415 | self.textEditReceived2.setGeometry(QtCore.QRect(560, 190, 211, 171)) 416 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 417 | sizePolicy.setHorizontalStretch(0) 418 | sizePolicy.setVerticalStretch(0) 419 | sizePolicy.setHeightForWidth(self.textEditReceived2.sizePolicy().hasHeightForWidth()) 420 | self.textEditReceived2.setSizePolicy(sizePolicy) 421 | font = QtGui.QFont() 422 | font.setPointSize(10) 423 | self.textEditReceived2.setFont(font) 424 | self.textEditReceived2.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) 425 | self.textEditReceived2.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) 426 | self.textEditReceived2.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContentsOnFirstShow) 427 | self.textEditReceived2.setAutoFormatting(QtWidgets.QTextEdit.AutoBulletList) 428 | self.textEditReceived2.setReadOnly(True) 429 | self.textEditReceived2.setOverwriteMode(True) 430 | self.textEditReceived2.setObjectName("textEditReceived2") 431 | self.tabWidget.addTab(self.tab_2, "") 432 | self.verticalLayout.addWidget(self.tabWidget) 433 | MainWindow.setCentralWidget(self.centralWidget) 434 | self.statusBar = QtWidgets.QStatusBar(MainWindow) 435 | self.statusBar.setObjectName("statusBar") 436 | MainWindow.setStatusBar(self.statusBar) 437 | self.menuBar = QtWidgets.QMenuBar(MainWindow) 438 | self.menuBar.setGeometry(QtCore.QRect(0, 0, 859, 23)) 439 | self.menuBar.setObjectName("menuBar") 440 | self.menuFile = QtWidgets.QMenu(self.menuBar) 441 | self.menuFile.setObjectName("menuFile") 442 | self.menuMointor = QtWidgets.QMenu(self.menuBar) 443 | self.menuMointor.setObjectName("menuMointor") 444 | self.menuHelp = QtWidgets.QMenu(self.menuBar) 445 | self.menuHelp.setObjectName("menuHelp") 446 | MainWindow.setMenuBar(self.menuBar) 447 | self.actionSend = QtWidgets.QAction(MainWindow) 448 | self.actionSend.setObjectName("actionSend") 449 | self.actionExit = QtWidgets.QAction(MainWindow) 450 | self.actionExit.setObjectName("actionExit") 451 | self.actionVrep = QtWidgets.QAction(MainWindow) 452 | self.actionVrep.setObjectName("actionVrep") 453 | self.actionOpenGL = QtWidgets.QAction(MainWindow) 454 | self.actionOpenGL.setObjectName("actionOpenGL") 455 | self.actionControl = QtWidgets.QAction(MainWindow) 456 | self.actionControl.setObjectName("actionControl") 457 | self.actionPyquino_help = QtWidgets.QAction(MainWindow) 458 | self.actionPyquino_help.setObjectName("actionPyquino_help") 459 | self.menuFile.addAction(self.actionSend) 460 | self.menuFile.addAction(self.actionExit) 461 | self.menuMointor.addAction(self.actionVrep) 462 | self.menuMointor.addAction(self.actionOpenGL) 463 | self.menuMointor.addAction(self.actionControl) 464 | self.menuHelp.addAction(self.actionPyquino_help) 465 | self.menuBar.addAction(self.menuFile.menuAction()) 466 | self.menuBar.addAction(self.menuMointor.menuAction()) 467 | self.menuBar.addAction(self.menuHelp.menuAction()) 468 | 469 | self.retranslateUi(MainWindow) 470 | self.tabWidget.setCurrentIndex(0) 471 | QtCore.QMetaObject.connectSlotsByName(MainWindow) 472 | 473 | def retranslateUi(self, MainWindow): 474 | _translate = QtCore.QCoreApplication.translate 475 | MainWindow.setWindowTitle(_translate("MainWindow", "Pyqtuino")) 476 | self.groupBox.setTitle(_translate("MainWindow", "com setting")) 477 | self.label_2.setText(_translate("MainWindow", "com")) 478 | self.label.setText(_translate("MainWindow", "baurd")) 479 | self.label_3.setText(_translate("MainWindow", "first")) 480 | self.label_4.setText(_translate("MainWindow", "data")) 481 | self.label_5.setText(_translate("MainWindow", "stop")) 482 | self.pushButtonOpenSerial.setText(_translate("MainWindow", "open")) 483 | self.pushButtonSendData.setText(_translate("MainWindow", "send")) 484 | self.textEditSent.setHtml(_translate("MainWindow", "\n" 485 | "\n" 488 | "


")) 489 | self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Com")) 490 | self.groupBox_2.setTitle(_translate("MainWindow", "Axis Adjust")) 491 | self.label_6.setText(_translate("MainWindow", "Z jog")) 492 | self.unlockMachine.setText(_translate("MainWindow", "Unlock machine")) 493 | self.label_7.setText(_translate("MainWindow", "X-Y Axis")) 494 | self.homeButton.setText(_translate("MainWindow", "Home")) 495 | self.label_11.setText(_translate("MainWindow", "step")) 496 | self.label_12.setText(_translate("MainWindow", "mm")) 497 | self.label_8.setText(_translate("MainWindow", "X")) 498 | self.label_9.setText(_translate("MainWindow", "Y")) 499 | self.label_10.setText(_translate("MainWindow", "Z")) 500 | self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Control")) 501 | self.menuFile.setTitle(_translate("MainWindow", "File")) 502 | self.menuMointor.setTitle(_translate("MainWindow", "Mointor")) 503 | self.menuHelp.setTitle(_translate("MainWindow", "Help")) 504 | self.actionSend.setText(_translate("MainWindow", "send Gcode")) 505 | self.actionExit.setText(_translate("MainWindow", "exit")) 506 | self.actionVrep.setText(_translate("MainWindow", "Vrep")) 507 | self.actionOpenGL.setText(_translate("MainWindow", "OpenGL")) 508 | self.actionControl.setText(_translate("MainWindow", "Control")) 509 | self.actionPyquino_help.setText(_translate("MainWindow", "Pyquino help")) 510 | 511 | import icons_rc 512 | 513 | if __name__ == "__main__": 514 | import sys 515 | app = QtWidgets.QApplication(sys.argv) 516 | MainWindow = QtWidgets.QMainWindow() 517 | ui = Ui_MainWindow() 518 | ui.setupUi(MainWindow) 519 | MainWindow.show() 520 | sys.exit(app.exec_()) 521 | 522 | -------------------------------------------------------------------------------- /core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/core/__init__.py -------------------------------------------------------------------------------- /core/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/core/__init__.pyc -------------------------------------------------------------------------------- /core/gcode/gcodeParser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import math 4 | 5 | class GcodeParser: 6 | 7 | def __init__(self): 8 | self.model = GcodeModel(self) 9 | 10 | 11 | def parseFile(self, path): 12 | if path: 13 | with open(path, 'r') as f: 14 | # init line counter 15 | self.lineNb = 0 16 | # for all lines 17 | for line in f: 18 | self.lineNb += 1 19 | # remove trailing linefeed 20 | self.line = line.rstrip() 21 | # parse a line 22 | self.parseLine() 23 | self.model.postProcess() 24 | return self.model 25 | 26 | 27 | def parseLine(self): 28 | # strip comments: 29 | bits = self.line.split(';',1) 30 | if (len(bits) > 1): 31 | comment = bits[1] 32 | 33 | # extract & clean command 34 | command = bits[0].strip() 35 | 36 | # TODO strip logical line number & checksum 37 | # will define the GX X?? 38 | # code is fist word, then args 39 | comm = command.split(None, 1) 40 | code = comm[0] if (len(comm)>0) else None 41 | args = comm[1] if (len(comm)>1) else None 42 | 43 | if code: 44 | if hasattr(self, "parse_"+code): 45 | getattr(self, "parse_"+code)(args) 46 | else: 47 | self.warn("Unknown code '%s'"%code) 48 | 49 | def parseArgs(self, args): 50 | dic = {} 51 | if args: 52 | bits = args.split() 53 | for bit in bits: 54 | letter = bit[0] 55 | coord = float(bit[1:]) 56 | dic[letter] = coord 57 | return dic 58 | 59 | def parse_G0(self, args): 60 | # G0: Rapid move 61 | # same as a controlled move for us (& reprap FW) 62 | self.G1(args, "G0") 63 | 64 | def parse_G1(self, args, type="G1"): 65 | # G1: Controlled move 66 | self.model.do_G1(self.parseArgs(args), type) 67 | 68 | def parse_G20(self, args): 69 | # G20: Set Units to Inches 70 | self.error("Unsupported & incompatible: G20: Set Units to Inches") 71 | 72 | def parse_G21(self, args): 73 | # G21: Set Units to Millimeters 74 | # Default, nothing to do 75 | pass 76 | 77 | def parse_G28(self, args): 78 | # G28: Move to Origin 79 | self.model.do_G28(self.parseArgs(args)) 80 | 81 | def parse_G90(self, args): 82 | # G90: Set to Absolute Positioning 83 | self.model.setRelative(False) 84 | 85 | def parse_G91(self, args): 86 | # G91: Set to Relative Positioning 87 | self.model.setRelative(True) 88 | 89 | def parse_G92(self, args): 90 | # G92: Set Position 91 | self.model.do_G92(self.parseArgs(args)) 92 | 93 | def warn(self, msg): 94 | print("[WARN] Line %d: %s (Text:'%s')" % (self.lineNb, msg, self.line)) 95 | 96 | def error(self, msg): 97 | print("[ERROR] Line %d: %s (Text:'%s')" % (self.lineNb, msg, self.line)) 98 | raise Exception("[ERROR] Line %d: %s (Text:'%s')" % (self.lineNb, msg, self.line)) 99 | 100 | class BBox(object): 101 | 102 | def __init__(self, coords): 103 | self.xmin = self.xmax = coords["X"] 104 | self.ymin = self.ymax = coords["Y"] 105 | self.zmin = self.zmax = coords["Z"] 106 | 107 | def dx(self): 108 | return self.xmax - self.xmin 109 | 110 | def dy(self): 111 | return self.ymax - self.ymin 112 | 113 | def dz(self): 114 | return self.zmax - self.zmin 115 | 116 | def cx(self): 117 | return (self.xmax + self.xmin)/2 118 | 119 | def cy(self): 120 | return (self.ymax + self.ymin)/2 121 | 122 | def cz(self): 123 | return (self.zmax + self.zmin)/2 124 | 125 | def extend(self, coords): 126 | self.xmin = min(self.xmin, coords["X"]) 127 | self.xmax = max(self.xmax, coords["X"]) 128 | self.ymin = min(self.ymin, coords["Y"]) 129 | self.ymax = max(self.ymax, coords["Y"]) 130 | self.zmin = min(self.zmin, coords["Z"]) 131 | self.zmax = max(self.zmax, coords["Z"]) 132 | 133 | class GcodeModel: 134 | 135 | def __init__(self, parser): 136 | # save parser for messages 137 | self.parser = parser 138 | # latest coordinates & extrusion relative to offset, feedrate 139 | self.relative = { 140 | "X":0.0, 141 | "Y":0.0, 142 | "Z":0.0, 143 | "F":0.0, 144 | "E":0.0} 145 | # offsets for relative coordinates and position reset (G92) 146 | self.offset = { 147 | "X":0.0, 148 | "Y":0.0, 149 | "Z":0.0, 150 | "E":0.0} 151 | # if true, args for move (G1) are given relatively (default: absolute) 152 | self.isRelative = False 153 | # the segments 154 | self.segments = [] 155 | self.layers = None 156 | self.distance = None 157 | self.extrudate = None 158 | self.bbox = None 159 | self.coods=None ##test file 160 | 161 | def do_G1(self, args, type): 162 | # G0/G1: Rapid/Controlled move 163 | # clone previous coords 164 | coords = dict(self.relative) 165 | # update changed coords 166 | for axis in list(args.keys()): 167 | if axis in coords: 168 | if self.isRelative: 169 | coords[axis] += args[axis] 170 | else: 171 | coords[axis] = args[axis] 172 | else: 173 | self.warn("Unknown axis '%s'"%axis) 174 | # build segment 175 | absolute = { 176 | "X": self.offset["X"] + coords["X"], 177 | "Y": self.offset["Y"] + coords["Y"], 178 | "Z": self.offset["Z"] + coords["Z"], 179 | "F": coords["F"], # no feedrate offset 180 | "E": self.offset["E"] + coords["E"] 181 | } 182 | seg = Segment( 183 | type, 184 | absolute, 185 | self.parser.lineNb, 186 | self.parser.line) 187 | self.addSegment(seg) 188 | # update model coords 189 | self.relative = coords 190 | 191 | def do_G28(self, args): 192 | # G28: Move to Origin 193 | self.warn("G28 unimplemented") 194 | 195 | def do_G92(self, args): 196 | # G92: Set Position 197 | # this changes the current coords, without moving, so do not generate a segment 198 | 199 | # no axes mentioned == all axes to 0 200 | if not len(list(args.keys())): 201 | args = {"X":0.0, "Y":0.0, "Z":0.0, "E":0.0} 202 | # update specified axes 203 | for axis in list(args.keys()): 204 | if axis in self.offset: 205 | # transfer value from relative to offset 206 | self.offset[axis] += self.relative[axis] - args[axis] 207 | self.relative[axis] = args[axis] 208 | else: 209 | self.warn("Unknown axis '%s'"%axis) 210 | 211 | def setRelative(self, isRelative): 212 | self.isRelative = isRelative 213 | 214 | def addSegment(self, segment): 215 | self.segments.append(segment) 216 | #print segment 217 | 218 | def warn(self, msg): 219 | self.parser.warn(msg) 220 | 221 | def error(self, msg): 222 | self.parser.error(msg) 223 | 224 | 225 | def classifySegments(self): 226 | # apply intelligence, to classify segments 227 | 228 | # start model at 0 229 | coords = { 230 | "X":0.0, 231 | "Y":0.0, 232 | "Z":0.0, 233 | "F":0.0, 234 | "E":0.0} 235 | 236 | # first layer at Z=0 237 | currentLayerIdx = 0 238 | currentLayerZ = 0 239 | 240 | for seg in self.segments: 241 | # default style is fly (move, no extrusion) 242 | style = "fly" 243 | 244 | # no horizontal movement, but extruder movement: retraction/refill 245 | if ( 246 | (seg.coords["X"] == coords["X"]) and 247 | (seg.coords["Y"] == coords["Y"]) and 248 | (seg.coords["E"] != coords["E"]) ): 249 | style = "retract" if (seg.coords["E"] < coords["E"]) else "restore" 250 | 251 | # some horizontal movement, and positive extruder movement: extrusion 252 | if ( 253 | ( (seg.coords["X"] != coords["X"]) or (seg.coords["Y"] != coords["Y"]) ) and 254 | (seg.coords["E"] > coords["E"]) ): 255 | style = "extrude" 256 | 257 | # positive extruder movement in a different Z signals a layer change for this segment 258 | if ( 259 | (seg.coords["E"] > coords["E"]) and 260 | (seg.coords["Z"] != currentLayerZ) ): 261 | currentLayerZ = seg.coords["Z"] 262 | currentLayerIdx += 1 263 | 264 | # set style and layer in segment 265 | seg.style = style 266 | seg.layerIdx = currentLayerIdx 267 | 268 | 269 | #print coords 270 | #print seg.coords 271 | #print "%s (%s | %s)"%(style, str(seg.coords), seg.line) 272 | #print 273 | 274 | # execute segment 275 | coords = seg.coords 276 | 277 | 278 | def splitLayers(self): 279 | # split segments into previously detected layers 280 | 281 | # start model at 0 282 | coords = { 283 | "X":0.0, 284 | "Y":0.0, 285 | "Z":0.0, 286 | "F":0.0, 287 | "E":0.0} 288 | 289 | # init layer store 290 | self.layers = [] 291 | 292 | currentLayerIdx = -1 293 | 294 | # for all segments 295 | for seg in self.segments: 296 | # next layer 297 | if currentLayerIdx != seg.layerIdx: 298 | layer = Layer(coords["Z"]) 299 | layer.start = coords 300 | self.layers.append(layer) 301 | currentLayerIdx = seg.layerIdx 302 | 303 | layer.segments.append(seg) 304 | 305 | # execute segment 306 | coords = seg.coords 307 | 308 | self.topLayer = len(self.layers)-1 309 | 310 | def calcMetrics(self): 311 | # init distances and extrudate 312 | self.distance = 0 313 | self.extrudate = 0 314 | 315 | # init model bbox 316 | self.bbox = None 317 | 318 | # extender helper 319 | def extend(bbox, coords): 320 | if bbox is None: 321 | return BBox(coords) 322 | else: 323 | bbox.extend(coords) 324 | return bbox 325 | 326 | # for all layers 327 | for layer in self.layers: 328 | # start at layer start 329 | coords = layer.start 330 | 331 | # init distances and extrudate 332 | layer.distance = 0 333 | layer.extrudate = 0 334 | 335 | # include start point 336 | self.bbox = extend(self.bbox, coords) 337 | 338 | # for all segments 339 | for seg in layer.segments: 340 | # calc XYZ distance 341 | d = (seg.coords["X"]-coords["X"])**2 342 | d += (seg.coords["Y"]-coords["Y"])**2 343 | d += (seg.coords["Z"]-coords["Z"])**2 344 | seg.distance = math.sqrt(d) 345 | 346 | # calc extrudate 347 | seg.extrudate = (seg.coords["E"]-coords["E"]) 348 | 349 | # accumulate layer metrics 350 | layer.distance += seg.distance 351 | layer.extrudate += seg.extrudate 352 | 353 | # execute segment 354 | coords = seg.coords 355 | 356 | # include end point 357 | extend(self.bbox, coords) 358 | self.coods = coords 359 | #print(coords) 360 | 361 | # accumulate total metrics 362 | #print(coords) 363 | self.distance += layer.distance 364 | print(self.distance) 365 | self.extrudate += layer.extrudate 366 | 367 | def postProcess(self): 368 | self.classifySegments() 369 | self.splitLayers() 370 | self.calcMetrics() 371 | 372 | 373 | def __str__(self): 374 | return ""%(len(self.segments), len(self.layers), self.distance, self.extrudate, self.bbox,self.coods) 375 | 376 | 377 | class Segment: 378 | def __init__(self, type, coords, lineNb, line): 379 | self.type = type 380 | self.coords = coords 381 | self.lineNb = lineNb 382 | self.line = line 383 | self.style = None 384 | self.layerIdx = None 385 | self.distance = None 386 | self.extrudate = None 387 | def __str__(self): 388 | return ""%(self.type, self.lineNb, self.style, self.layerIdx, self.distance, self.extrudate) 389 | 390 | class Layer: 391 | def __init__(self, Z): 392 | self.Z = Z 393 | self.segments = [] 394 | self.distance = None 395 | self.extrudate = None 396 | 397 | def __str__(self): 398 | return ""%(self.Z, len(self.segments), self.distance, self.extrudate) 399 | 400 | 401 | if __name__ == '__main__': 402 | path = "test_gcode.gcode" 403 | 404 | parser = GcodeParser() 405 | model = parser.parseFile(path) 406 | #print(model) 407 | #print(Segment.__str__) 408 | #print(model) 409 | 410 | -------------------------------------------------------------------------------- /core/gcode/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 852 10 | 667 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 10 21 | 40 22 | 871 23 | 431 24 | 25 | 26 | 27 | 1 28 | 29 | 30 | 31 | Tab 1 32 | 33 | 34 | 35 | 36 | 20 37 | 20 38 | 231 39 | 361 40 | 41 | 42 | 43 | 44 | 10 45 | 46 | 47 | 48 | com setting 49 | 50 | 51 | 52 | 53 | 90 54 | 30 55 | 121 56 | 31 57 | 58 | 59 | 60 | 61 | 62 | 63 | 10 64 | 30 65 | 71 66 | 21 67 | 68 | 69 | 70 | 71 | 14 72 | 73 | 74 | 75 | com 76 | 77 | 78 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 79 | 80 | 81 | 82 | 83 | 84 | 10 85 | 80 86 | 71 87 | 21 88 | 89 | 90 | 91 | 92 | 14 93 | 94 | 95 | 96 | baurd 97 | 98 | 99 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 100 | 101 | 102 | 103 | 104 | 105 | 90 106 | 80 107 | 121 108 | 31 109 | 110 | 111 | 112 | 113 | 114 | 115 | 10 116 | 130 117 | 71 118 | 21 119 | 120 | 121 | 122 | 123 | 14 124 | 125 | 126 | 127 | first 128 | 129 | 130 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 131 | 132 | 133 | 134 | 135 | 136 | 90 137 | 130 138 | 121 139 | 31 140 | 141 | 142 | 143 | 144 | 145 | 146 | 10 147 | 180 148 | 71 149 | 21 150 | 151 | 152 | 153 | 154 | 14 155 | 156 | 157 | 158 | data 159 | 160 | 161 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 162 | 163 | 164 | 165 | 166 | 167 | 90 168 | 180 169 | 121 170 | 31 171 | 172 | 173 | 174 | 175 | 176 | 177 | 10 178 | 230 179 | 71 180 | 21 181 | 182 | 183 | 184 | 185 | 14 186 | 187 | 188 | 189 | stop 190 | 191 | 192 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 193 | 194 | 195 | 196 | 197 | 198 | 90 199 | 230 200 | 121 201 | 31 202 | 203 | 204 | 205 | 206 | 207 | 208 | 10 209 | 280 210 | 201 211 | 31 212 | 213 | 214 | 215 | open 216 | 217 | 218 | 219 | 220 | 221 | 222 | 740 223 | 210 224 | 61 225 | 171 226 | 227 | 228 | 229 | send 230 | 231 | 232 | 233 | 234 | 235 | 260 236 | 20 237 | 541 238 | 181 239 | 240 | 241 | 242 | 243 | 0 244 | 0 245 | 246 | 247 | 248 | 249 | 14 250 | 251 | 252 | 253 | true 254 | 255 | 256 | 257 | 258 | 259 | 260 260 | 210 261 | 471 262 | 171 263 | 264 | 265 | 266 | 267 | 14 268 | 269 | 270 | 271 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 272 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 273 | p, li { white-space: pre-wrap; } 274 | </style></head><body style=" font-family:'PMingLiU'; font-size:14pt; font-weight:400; font-style:normal;"> 275 | <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> 276 | 277 | 278 | pushButtonSendData 279 | groupBox 280 | textEditSent 281 | textEditReceived 282 | groupBox 283 | pushButtonSendData 284 | textEditReceived 285 | textEditSent 286 | 287 | 288 | 289 | Tab 2 290 | 291 | 292 | 293 | 294 | 20 295 | 30 296 | 521 297 | 331 298 | 299 | 300 | 301 | Axis Adjust 302 | 303 | 304 | 305 | 306 | 120 307 | 20 308 | 91 309 | 61 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | ../icon/arrow-up-b.png../icon/arrow-up-b.png 318 | 319 | 320 | 321 | 30 322 | 30 323 | 324 | 325 | 326 | 327 | 328 | 329 | 0 330 | 110 331 | 91 332 | 61 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | ../icon/arrow-left-b.png../icon/arrow-left-b.png 341 | 342 | 343 | 344 | 30 345 | 30 346 | 347 | 348 | 349 | 350 | 351 | 352 | 230 353 | 110 354 | 91 355 | 61 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | ../icon/arrow-right-b.png../icon/arrow-right-b.png 364 | 365 | 366 | 367 | 30 368 | 30 369 | 370 | 371 | 372 | 373 | 374 | 375 | 120 376 | 190 377 | 91 378 | 61 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | ../icon/arrow-down-b.png../icon/arrow-down-b.png 387 | 388 | 389 | 390 | 30 391 | 30 392 | 393 | 394 | 395 | 396 | 397 | 398 | 380 399 | 20 400 | 91 401 | 61 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | ../icon/arrow-up-a.png../icon/arrow-up-a.png 410 | 411 | 412 | 413 | 30 414 | 30 415 | 416 | 417 | 418 | 419 | 420 | 421 | 380 422 | 220 423 | 91 424 | 51 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | ../icon/arrow-down-a.png../icon/arrow-down-a.png 433 | 434 | 435 | 436 | 30 437 | 30 438 | 439 | 440 | 441 | 442 | 443 | 444 | 380 445 | 130 446 | 81 447 | 31 448 | 449 | 450 | 451 | Z jog 452 | 453 | 454 | Qt::AlignCenter 455 | 456 | 457 | 458 | 459 | 460 | 10 461 | 290 462 | 101 463 | 31 464 | 465 | 466 | 467 | Unlock machine 468 | 469 | 470 | 471 | 472 | 473 | 140 474 | 130 475 | 51 476 | 21 477 | 478 | 479 | 480 | X-Y Axis 481 | 482 | 483 | 484 | 485 | 486 | 130 487 | 290 488 | 91 489 | 31 490 | 491 | 492 | 493 | Home 494 | 495 | 496 | 497 | 498 | 499 | 500 | 560 501 | 50 502 | 211 503 | 131 504 | 505 | 506 | 507 | 508 | 509 | 510 | X 511 | 512 | 513 | Qt::AlignCenter 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | Y 524 | 525 | 526 | Qt::AlignCenter 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | Z 540 | 541 | 542 | Qt::AlignCenter 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 0 556 | 0 557 | 852 558 | 21 559 | 560 | 561 | 562 | 563 | File 564 | 565 | 566 | 567 | 568 | 569 | 570 | Mointor 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | send Gcode 582 | 583 | 584 | 585 | 586 | exit 587 | 588 | 589 | 590 | 591 | Vrep 592 | 593 | 594 | 595 | 596 | OpenGL 597 | 598 | 599 | 600 | 601 | Control 602 | 603 | 604 | 605 | 606 | 607 | 608 | -------------------------------------------------------------------------------- /core/gcode/test1.gcode: -------------------------------------------------------------------------------- 1 | 2 | G28 ; 3 | 4 | G1 Z10 ; 5 | G1 X10.0; 6 | G1 X-14.2 Y-13.2 ; -------------------------------------------------------------------------------- /core/graphy/Ui_graphy.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'Y:\eric6_workspace\Pyquino\graphy\graphy.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.7 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(751, 612) 15 | Dialog.setSizeGripEnabled(True) 16 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(Dialog) 17 | self.verticalLayout_2.setObjectName("verticalLayout_2") 18 | self.verticalLayout = QtWidgets.QVBoxLayout() 19 | self.verticalLayout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) 20 | self.verticalLayout.setContentsMargins(1, 1, 1, 1) 21 | self.verticalLayout.setObjectName("verticalLayout") 22 | self.verticalLayout_2.addLayout(self.verticalLayout) 23 | 24 | self.retranslateUi(Dialog) 25 | QtCore.QMetaObject.connectSlotsByName(Dialog) 26 | 27 | def retranslateUi(self, Dialog): 28 | _translate = QtCore.QCoreApplication.translate 29 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 30 | 31 | 32 | if __name__ == "__main__": 33 | import sys 34 | app = QtWidgets.QApplication(sys.argv) 35 | Dialog = QtWidgets.QDialog() 36 | ui = Ui_Dialog() 37 | ui.setupUi(Dialog) 38 | Dialog.show() 39 | sys.exit(app.exec_()) 40 | 41 | -------------------------------------------------------------------------------- /core/graphy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/core/graphy/__init__.py -------------------------------------------------------------------------------- /core/graphy/graphy.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Module implementing Dialog. 5 | """ 6 | from PyQt5 import QtWidgets 7 | from PyQt5.QtCore import pyqtSlot 8 | from PyQt5.QtWidgets import QDialog 9 | 10 | from .Ui_graphy import Ui_Dialog 11 | 12 | 13 | import pyqtgraph.opengl as gl 14 | 15 | import numpy as np 16 | 17 | 18 | class Dialog(QDialog, Ui_Dialog): 19 | """ 20 | Class documentation goes here. 21 | """ 22 | def __init__(self, parent=None): 23 | """ 24 | Constructor 25 | 26 | @param parent reference to the parent widget 27 | @type QWidget 28 | """ 29 | super(Dialog, self).__init__(parent) 30 | self.setupUi(self) 31 | 32 | self.openGLWidget = gl.GLViewWidget() 33 | self.verticalLayout.insertWidget(0, self.openGLWidget) 34 | self.openGLWidget.show() 35 | 36 | self.openGLWidget.setCameraPosition(distance=40) 37 | 38 | g = gl.GLGridItem() 39 | g.scale(2,2,1) 40 | self.openGLWidget.addItem(g) 41 | 42 | self.__3dtest__() 43 | #self.__test__() 44 | 45 | def __3dtest__(self): 46 | 47 | n = 6 48 | pos = np.empty((n, 3)) 49 | size = np.empty((n)) 50 | color = np.empty((n, 4)) 51 | pos[0] = (0,0,0); size[0] = 0.2; color[0] = (1.0, 0.0, 0.0, 0.5) 52 | pos[1] = (0,0,0.6); size[1] = 0.2; color[1] = (0.0, 0.0, 1.0, 0.5) 53 | pos[2] = (0,0,0.6); size[2] = 0.2; color[2] = (0.0, 1.0, 0.0, 0.5) 54 | pos[3] = (10.0,0,0.6); size[2] = 0.2; color[3] = (0.0, 1.0, 0.0, 0.5) 55 | pos[4] = (0,0,0); size[2] = 0.2; color[4] = (0.0, 1.0, 0.0, 0.5) 56 | pos[5] = (-14.2,-13.2,0.6); size[5] = 0.2; color[5] = (0.0, 1.0, 0.0, 0.5) 57 | #pos[0] = (1, 0, 1); 58 | #for i in range() 59 | sp1 = gl.GLScatterPlotItem(pos=pos, size=size, color=color, pxMode=False) 60 | sp1.translate(5,5,0) 61 | #print(sp1) 62 | self.openGLWidget.addItem(sp1) 63 | 64 | ''' 65 | #def fn(x, y): 66 | # return np.cos((x**2 + y**2)**0.5) 67 | 68 | n = 51 69 | y = np.linspace(-10,10,n) 70 | x = np.linspace(-10,10,100) 71 | for i in range(n): 72 | yi = np.array([y[i]]*100) 73 | d = (x**2 + yi**2)**0.5 74 | z = 10 * np.cos(d) / (d+1) 75 | pts = np.vstack([x,yi,z]).transpose() 76 | print(pts) 77 | plt = gl.GLLinePlotItem(pos=pts, color=pg.glColor((i,n*1.3)), width=(i+1)/10., antialias=True) 78 | self.openGLWidget.addItem(plt) 79 | ''' 80 | def __test__(self): 81 | 82 | verts = np.array([ 83 | [0, 0, 0], 84 | [2, 0, 0], 85 | [1, 2, 0], 86 | [1, 1, 1], 87 | ]) 88 | faces = np.array([ 89 | [0, 1, 2], 90 | [0, 1, 3], 91 | [0, 2, 3], 92 | [1, 2, 3] 93 | ]) 94 | colors = np.array([ 95 | [1, 0, 0, 0.3], 96 | [0, 1, 0, 0.3], 97 | [0, 0, 1, 0.3], 98 | [1, 1, 0, 0.3] 99 | ]) 100 | 101 | ## Mesh item will automatically compute face normals. 102 | m1 = gl.GLMeshItem(vertexes=verts, faces=faces, faceColors=colors, smooth=False) 103 | m1.translate(5, 5, 0) 104 | m1.setGLOptions('additive') 105 | self.openGLWidget.addItem(m1) 106 | 107 | 108 | ## Example 2: 109 | ## Array of vertex positions, three per face 110 | verts = np.empty((36, 3, 3), dtype=np.float32) 111 | theta = np.linspace(0, 2*np.pi, 37)[:-1] 112 | verts[:,0] = np.vstack([2*np.cos(theta), 2*np.sin(theta), [0]*36]).T 113 | verts[:,1] = np.vstack([4*np.cos(theta+0.2), 4*np.sin(theta+0.2), [-1]*36]).T 114 | verts[:,2] = np.vstack([4*np.cos(theta-0.2), 4*np.sin(theta-0.2), [1]*36]).T 115 | 116 | ## Colors are specified per-vertex 117 | colors = np.random.random(size=(verts.shape[0], 3, 4)) 118 | m2 = gl.GLMeshItem(vertexes=verts, vertexColors=colors, smooth=False, shader='balloon', 119 | drawEdges=True, edgeColor=(1, 1, 0, 1)) 120 | m2.translate(-5, 5, 0) 121 | self.openGLWidget.addItem(m2) 122 | 123 | 124 | 125 | ## Example 3: 126 | ## sphere 127 | 128 | md = gl.MeshData.sphere(rows=10, cols=20) 129 | #colors = np.random.random(size=(md.faceCount(), 4)) 130 | #colors[:,3] = 0.3 131 | #colors[100:] = 0.0 132 | colors = np.ones((md.faceCount(), 4), dtype=float) 133 | colors[::2,0] = 0 134 | colors[:,1] = np.linspace(0, 1, colors.shape[0]) 135 | md.setFaceColors(colors) 136 | m3 = gl.GLMeshItem(meshdata=md, smooth=False)#, shader='balloon') 137 | 138 | m3.translate(5, -5, 0) 139 | self.openGLWidget.addItem(m3) 140 | 141 | 142 | # Example 4: 143 | # wireframe 144 | 145 | md = gl.MeshData.sphere(rows=4, cols=8) 146 | m4 = gl.GLMeshItem(meshdata=md, smooth=False, drawFaces=False, drawEdges=True, edgeColor=(1,1,1,1)) 147 | m4.translate(0,10,0) 148 | self.openGLWidget.addItem(m4) 149 | 150 | # Example 5: 151 | # cylinder 152 | md = gl.MeshData.cylinder(rows=10, cols=20, radius=[1., 2.0], length=5.) 153 | md2 = gl.MeshData.cylinder(rows=10, cols=20, radius=[2., 0.5], length=10.) 154 | colors = np.ones((md.faceCount(), 4), dtype=float) 155 | colors[::2,0] = 0 156 | colors[:,1] = np.linspace(0, 1, colors.shape[0]) 157 | md.setFaceColors(colors) 158 | m5 = gl.GLMeshItem(meshdata=md, smooth=True, drawEdges=True, edgeColor=(1,0,0,1), shader='balloon') 159 | colors = np.ones((md.faceCount(), 4), dtype=float) 160 | colors[::2,0] = 0 161 | colors[:,1] = np.linspace(0, 1, colors.shape[0]) 162 | md2.setFaceColors(colors) 163 | m6 = gl.GLMeshItem(meshdata=md2, smooth=True, drawEdges=False, shader='balloon') 164 | m6.translate(0,0,7.5) 165 | 166 | m6.rotate(0., 0, 1, 1) 167 | #m5.translate(-3,3,0) 168 | self.openGLWidget.addItem(m5) 169 | self.openGLWidget.addItem(m6) 170 | -------------------------------------------------------------------------------- /core/graphy/graphy.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 751 10 | 612 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | true 18 | 19 | 20 | 21 | 22 | 23 | QLayout::SetMinAndMaxSize 24 | 25 | 26 | 1 27 | 28 | 29 | 1 30 | 31 | 32 | 1 33 | 34 | 35 | 1 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /core/graphy_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Simple examples demonstrating the use of GLMeshItem. 4 | 5 | """ 6 | 7 | ## Add path to library (just for examples; you do not need this) 8 | #import initExample 9 | 10 | from pyqtgraph.Qt import QtCore, QtGui 11 | import pyqtgraph as pg 12 | import pyqtgraph.opengl as gl 13 | 14 | app = QtGui.QApplication([]) 15 | w = gl.GLViewWidget() 16 | w.show() 17 | w.setWindowTitle('pyqtgraph example: GLMeshItem') 18 | w.setCameraPosition(distance=40) 19 | 20 | g = gl.GLGridItem() 21 | g.scale(2,2,1) 22 | w.addItem(g) 23 | 24 | import numpy as np 25 | 26 | 27 | ## Example 1: 28 | ## Array of vertex positions and array of vertex indexes defining faces 29 | ## Colors are specified per-face 30 | 31 | verts = np.array([ 32 | [0, 0, 0], 33 | [2, 0, 0], 34 | [1, 2, 0], 35 | [1, 1, 1], 36 | ]) 37 | faces = np.array([ 38 | [0, 1, 2], 39 | [0, 1, 3], 40 | [0, 2, 3], 41 | [1, 2, 3] 42 | ]) 43 | colors = np.array([ 44 | [1, 0, 0, 0.3], 45 | [0, 1, 0, 0.3], 46 | [0, 0, 1, 0.3], 47 | [1, 1, 0, 0.3] 48 | ]) 49 | 50 | ## Mesh item will automatically compute face normals. 51 | m1 = gl.GLMeshItem(vertexes=verts, faces=faces, faceColors=colors, smooth=False) 52 | m1.translate(5, 5, 0) 53 | m1.setGLOptions('additive') 54 | w.addItem(m1) 55 | 56 | """ 57 | 58 | ## Example 2: 59 | ## Array of vertex positions, three per face 60 | verts = np.empty((36, 3, 3), dtype=np.float32) 61 | theta = np.linspace(0, 2*np.pi, 37)[:-1] 62 | verts[:,0] = np.vstack([2*np.cos(theta), 2*np.sin(theta), [0]*36]).T 63 | verts[:,1] = np.vstack([4*np.cos(theta+0.2), 4*np.sin(theta+0.2), [-1]*36]).T 64 | verts[:,2] = np.vstack([4*np.cos(theta-0.2), 4*np.sin(theta-0.2), [1]*36]).T 65 | 66 | ## Colors are specified per-vertex 67 | colors = np.random.random(size=(verts.shape[0], 3, 4)) 68 | m2 = gl.GLMeshItem(vertexes=verts, vertexColors=colors, smooth=False, shader='balloon', 69 | drawEdges=True, edgeColor=(1, 1, 0, 1)) 70 | m2.translate(-5, 5, 0) 71 | w.addItem(m2) 72 | 73 | 74 | 75 | ## Example 3: 76 | ## sphere 77 | 78 | md = gl.MeshData.sphere(rows=10, cols=20) 79 | #colors = np.random.random(size=(md.faceCount(), 4)) 80 | #colors[:,3] = 0.3 81 | #colors[100:] = 0.0 82 | colors = np.ones((md.faceCount(), 4), dtype=float) 83 | colors[::2,0] = 0 84 | colors[:,1] = np.linspace(0, 1, colors.shape[0]) 85 | md.setFaceColors(colors) 86 | m3 = gl.GLMeshItem(meshdata=md, smooth=False)#, shader='balloon') 87 | 88 | m3.translate(5, -5, 0) 89 | w.addItem(m3) 90 | 91 | 92 | # Example 4: 93 | # wireframe 94 | 95 | md = gl.MeshData.sphere(rows=4, cols=8) 96 | m4 = gl.GLMeshItem(meshdata=md, smooth=False, drawFaces=False, drawEdges=True, edgeColor=(1,1,1,1)) 97 | m4.translate(0,10,0) 98 | w.addItem(m4) 99 | 100 | # Example 5: 101 | # cylinder 102 | md = gl.MeshData.cylinder(rows=10, cols=20, radius=[1., 2.0], length=5.) 103 | md2 = gl.MeshData.cylinder(rows=10, cols=20, radius=[2., 0.5], length=10.) 104 | colors = np.ones((md.faceCount(), 4), dtype=float) 105 | colors[::2,0] = 0 106 | colors[:,1] = np.linspace(0, 1, colors.shape[0]) 107 | md.setFaceColors(colors) 108 | m5 = gl.GLMeshItem(meshdata=md, smooth=True, drawEdges=True, edgeColor=(1,0,0,1), shader='balloon') 109 | colors = np.ones((md.faceCount(), 4), dtype=float) 110 | colors[::2,0] = 0 111 | colors[:,1] = np.linspace(0, 1, colors.shape[0]) 112 | md2.setFaceColors(colors) 113 | m6 = gl.GLMeshItem(meshdata=md2, smooth=True, drawEdges=False, shader='balloon') 114 | m6.translate(0,0,7.5) 115 | 116 | m6.rotate(0., 0, 1, 1) 117 | #m5.translate(-3,3,0) 118 | w.addItem(m5) 119 | w.addItem(m6) 120 | 121 | """ 122 | 123 | 124 | 125 | 126 | ## Start Qt event loop unless running in interactive mode. 127 | if __name__ == '__main__': 128 | import sys 129 | if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): 130 | QtGui.QApplication.instance().exec_() 131 | -------------------------------------------------------------------------------- /core/info.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | version1 = '0.1' 3 | parser = argparse.ArgumentParser( 4 | usage='%(prog)s [options]', #自訂使用方法外觀,預設由參數產生 5 | description='程式說明', #頂端程式說明,預設 None 6 | epilog='程式說明2', #底端程式說明,預設 None 7 | prefix_chars='-', #參數起始字串,預設 '-' 8 | ) 9 | parser.add_argument('-V', '--version', action='version', version=version1, help="Show Version") 10 | parser.add_argument('-s', action='store_true', help="s!") 11 | args = parser.parse_args() #解析 12 | 13 | def showof(): 14 | return args 15 | -------------------------------------------------------------------------------- /core/mainwindow.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from PyQt5 import QtWidgets, QtCore 4 | from PyQt5.QtCore import * 5 | from PyQt5.QtGui import * 6 | from PyQt5.QtWidgets import * 7 | from PyQt5.uic import loadUi 8 | import platform 9 | from . import serialportcontext 10 | import threading 11 | import time 12 | import serial 13 | 14 | from .Ui_mainwindow import Ui_MainWindow 15 | from .monitor.machine_mointor import Machine 16 | # from .graphy.graphy import Dialog 17 | import pnael 18 | import os 19 | import sys 20 | from .vrep.vrep_setting import vrepsetting 21 | 22 | 23 | class Thread_wait_forLNC(QThread): 24 | lnc_signal = pyqtSignal(int) 25 | 26 | def __init__(self, folder, parent=None): 27 | QThread.__init__(self, parent) 28 | self.folder = folder 29 | self.flag = True 30 | 31 | def run(self): 32 | t0 = 0 33 | while self.flag: 34 | if os.path.isfile(f'{self.folder}/START'): 35 | os.remove(f"{self.folder}/START") 36 | if t0 == 0: 37 | t0 = 1 38 | self.lnc_signal.emit(0) 39 | elif os.path.isfile(f'{self.folder}/STOP'): 40 | self.flag = False 41 | self.remove_stopflag() 42 | else: 43 | t0 = 0 44 | time.sleep(0.5) 45 | 46 | def remove_stopflag(self): 47 | os.remove(f"{self.folder}/STOP") 48 | 49 | def stop_flag(self): 50 | self.flag = False 51 | 52 | def create_end_file(self): 53 | f = open(f"{self.folder}/END", "w") 54 | f.close() 55 | 56 | class MainWindow(QMainWindow): 57 | """ 58 | Class documentation goes here. 59 | """ 60 | _receive_signal = QtCore.pyqtSignal(str) 61 | _auto_send_signal = QtCore.pyqtSignal() 62 | 63 | def __init__(self, args, parent=None): 64 | 65 | super(MainWindow, self).__init__(parent) 66 | loadUi("core/mainwindow.ui", self) 67 | # self.setupUi(self) 68 | self.show() 69 | ''' 70 | pal = QPalette() 71 | pal.setColor(QPalette.Background, QColor(125,125 ,125)) 72 | 73 | self.setAutoFillBackground(True) 74 | self.setPalette(pal) 75 | ''' 76 | self.initForms() 77 | 78 | # self.comboBoxBaud.setCurrentIndex(len(bauds) - 1) 79 | 80 | def initForms(self): 81 | 82 | if platform.system() == "Windows": 83 | ports = list() 84 | for i in range(8): 85 | ports.append("COM%d" % ((i + 1))) 86 | self.comboBoxPort.addItems(ports) 87 | print(ports) 88 | else: 89 | # todo:scan system serial port 90 | self.__scanSerialPorts__() 91 | 92 | bauds = ["50", "75", "134", "110", "150", "200", "300", "600", "1200", "2400", "4800", "9600", "14400", "19200", 93 | "38400", "56000", "57600", 94 | "115200"] 95 | self.comboBoxBaud.addItems(bauds) 96 | self.comboBoxBaud.setCurrentIndex(len(bauds) - 1) 97 | 98 | checks = ["None", "Odd", "Even", "Zero", "One"] 99 | self.comboBoxCheckSum.addItems(checks) 100 | self.comboBoxCheckSum.setCurrentIndex(len(checks) - 1) 101 | 102 | bits = ["4 Bits", "5 Bits", "6 Bits", "7 Bits", "8 Bits"] 103 | self.comboBoxBits.addItems(bits) 104 | self.comboBoxBits.setCurrentIndex(len(bits) - 1) 105 | 106 | stopbits = ["1 Bit", "1.5 Bits", "2 Bits"] 107 | self.comboBoxStopBits.addItems(stopbits) 108 | self.comboBoxStopBits.setCurrentIndex(0) 109 | 110 | # self._auto_send_signal.connect(self.__auto_send_update__) 111 | 112 | # self.xAxis 113 | 114 | port = self.comboBoxPort.currentText() 115 | baud = int("%s" % self.comboBoxBaud.currentText(), 10) 116 | self._serial_context_ = serialportcontext.SerialPortContext(port=port, baud=baud) 117 | 118 | # self.lineEditReceivedCounts.setText("0") 119 | # self.lineEditSentCounts.setText("0") 120 | self.pushButtonOpenSerial.clicked.connect(self.__open_serial_port__) 121 | # self.pushButtonClearRecvArea.clicked.connect(self.__clear_recv_area__) 122 | self.pushButtonSendData.clicked.connect(self.__send_data__) 123 | self._receive_signal.connect(self.__display_recv_data__) 124 | self._receive_signal.connect(self.__test_received__) 125 | # self.pushButtonOpenRecvFile.clicked.connect(self.__save_recv_file__) 126 | self.actionSend.triggered.connect(self.__open_send_file__) 127 | # self.actionOpenGL.triggered.connect(self.__opengl__) 128 | self.actionVrep.triggered.connect(self.__teset__) 129 | self._send_file_data = '' 130 | self.numberx = 0 131 | self.numbery = 0 132 | self.numberz = 0 133 | # self.__control__() 134 | self.actionControl.triggered.connect(self.__control__) 135 | 136 | ##machine_control button setting 137 | self.unlockMachine.clicked.connect(self.__unlockMachine__) 138 | self.yAxisup.clicked.connect(self.__yAxisup__) 139 | self.yAxisdown.clicked.connect(self.__yAxisdown__) 140 | self.xAxisrigh.clicked.connect(self.__xAxisrigh__) 141 | self.xAxisleft.clicked.connect(self.__xAxisleft__) 142 | self.zupButton.clicked.connect(self.__zupButton__) 143 | self.zdownButton.clicked.connect(self.__zdownButton__) 144 | 145 | self.tt = "" 146 | 147 | # def __auto_send_update__(self): 148 | # self.lineEditSentCounts.setText("%d" % self._serial_context_.getSendCounts()) 149 | 150 | def __teset__(self): 151 | dlg1 = vrepsetting() 152 | dlg1.show() 153 | if dlg1.exec_(): pass 154 | # self.GLWidget = QOpenGLWidget() 155 | """ 156 | self.openGLWidget = gl.GLViewWidget() 157 | self.horizontalLayout.insertWidget(0, self.openGLWidget) 158 | self.openGLWidget.show() 159 | g = gl.GLGridItem() 160 | g.scale(2,2,1) 161 | self.openGLWidget.addItem(g) 162 | #plot = pg.PlotWidget() 163 | #self.openGLWidget = QOpenGLWidget() 164 | #self.openGLWidget = gl.GLViewWidget() 165 | #self.openGLWidget.setCameraPosition(distance=40) 166 | #self.openGLWidget.addWidget(plot) 167 | #self.openGLWidget.show() 168 | #123 169 | #self.openGLWidget.setWindowTitle('pyqtgraph example: GLMeshItem') 170 | #self.openGLWidget.setCameraPosition(distance=40) 171 | """ 172 | print("I'm test") 173 | 174 | ''' 175 | def __opengl__(self): 176 | dlg2 = Dialog() 177 | dlg2.show() 178 | if dlg2.exec_(): pass 179 | ''' 180 | 181 | @pyqtSlot() 182 | def on_automode_btn_clicked(self): 183 | # run the automode wait for signal 184 | self.lnc_thread = Thread_wait_forLNC(f"C:/Users/smpss/kmol/Pyquino") 185 | self.lnc_thread.lnc_signal.connect(self.test_process) 186 | self.lnc_thread.start() 187 | 188 | def test_process(self): 189 | """auto mode send the gcode from PAON""" 190 | if os.path.isfile(f'C:/Users/smpss/kmol/Pyquino/data.txt'): 191 | f = open("C:/Users/smpss/kmol/Pyquino/data.txt", "r") 192 | # print(f"$J=G21G91Y{f.read()}F150") 193 | text = f"$J=G21G91Y{f.read()}F250" 194 | f.close() 195 | print(text) 196 | self.__test__send(text) 197 | self.qti = QTimer() 198 | self.qti.timeout.connect(self.aaa) 199 | self.qti.start(500) 200 | os.remove(f"C:/Users/smpss/kmol/Pyquino/data.txt") 201 | # check the locate 202 | # self.__test__send("?") 203 | # print(self.tt) 204 | # self.lnc_thread.create_end_file() 205 | 206 | def __control__(self): 207 | print("control open") 208 | dlg = Machine() 209 | dlg.show() 210 | if dlg.exec_(): pass 211 | 212 | def __open_send_file__(self): 213 | filename = QFileDialog.getOpenFileName(self, caption="Open Send File") 214 | print("123") 215 | try: 216 | if filename and 0: 217 | print(filename) 218 | self._send_file_ = open(filename, 'r', encoding='UTF-8') 219 | while True: 220 | print("g1", filename) 221 | line = self._send_file_.readlines() 222 | print(line) 223 | if not line: 224 | break 225 | else: 226 | self._send_file_data += line 227 | self._send_file_.close() 228 | self._send_file_ = None 229 | # self.textEditSent.clear() 230 | if len(self._send_file_data) > 0: 231 | print("123", self._send_file_data) 232 | self.textEditSent.setText(self._send_file_data) 233 | except Exception as e: 234 | print(e) 235 | # QtGui.QMessageBox.critical(self,u"打开文件",u"无法打开文件,请检查!") 236 | 237 | def __unlockMachine__(self): 238 | print("unlock") 239 | pass 240 | 241 | def __test_received__(self, data): 242 | if data.startswith(" 0: self._serial_context_.send(data, 0) 261 | pass 262 | 263 | def __yAxisdown__(self): 264 | print("yAxisdown") 265 | self.numbery = pnael.__minerse__(self.numbery, self.stepbox.value()) 266 | self.yAxis.display(self.numbery) 267 | ## do for the project to wend the gcode (-) 268 | text = str(-1 * self.stepbox.value()) 269 | print(text) 270 | data = str('G91' + '\n' + 'G01' + 'y' + text + '\n' + 'G90' + '\n') 271 | if self._serial_context_.isRunning(): 272 | if len(data) > 0: self._serial_context_.send(data, 0) 273 | pass 274 | 275 | def __xAxisrigh__(self): 276 | print("xAxisright") 277 | self.numberx = pnael.__pane__(self.numberx, self.stepbox.value()) 278 | print(self.numberx) 279 | self.xAxis.display(self.numberx) 280 | pass 281 | 282 | def __xAxisleft__(self): 283 | print("xAxisleft") 284 | self.numberx = pnael.__minerse__(self.numberx, self.stepbox.value()) 285 | self.xAxis.display(self.numberx) 286 | pass 287 | 288 | def __zupButton__(self): 289 | print("zupButton") 290 | self.numberz = pnael.__pane__(self.numberz, self.stepbox.value()) 291 | self.zAxis.display(self.numberz) 292 | pass 293 | 294 | def __zdownButton__(self): 295 | print("zdownButton") 296 | self.numberz = pnael.__minerse__(self.numberz, self.stepbox.value()) 297 | self.zAxis.display(self.numberz) 298 | pass 299 | 300 | def __handle_send_looping__(self): 301 | if self._is_auto_sending: 302 | self._is_auto_sending = False 303 | self.pushButtonSendData.setEnabled(True) 304 | 305 | def __clear_all_counts(self): 306 | # self.lineEditReceivedCounts.setText("0") 307 | # self.lineEditSentCounts.setText("0") 308 | self._serial_context_.clearAllCounts() 309 | 310 | def __clear_send_counts(self): 311 | self._serial_context_.clearSentCounts() 312 | # self.lineEditSentCounts.setText("0") 313 | 314 | def __clear_recv_counts(self): 315 | self._serial_context_.clearRecvCounts() 316 | 317 | # self.lineEditReceivedCounts.setText("0") 318 | 319 | def __set_display_hex__(self): 320 | self.textEditReceived.clear() 321 | 322 | def __display_recv_data__(self, data): 323 | # for l in range(len(data)): 324 | # hexstr = "%02X " % ord(str(data[l])) 325 | # self.textEditReceived.insertPlainText(hexstr) 326 | # print("gogog", data) 327 | for l in range(len(data)): 328 | self.textEditReceived.insertPlainText(data[l]) 329 | sb = self.textEditReceived.verticalScrollBar() 330 | sb.setValue(sb.maximum()) 331 | for c in range(len(data)): 332 | self.textEditReceived2.insertPlainText(data[c]) 333 | sb = self.textEditReceived2.verticalScrollBar() 334 | sb.setValue(sb.maximum()) 335 | # if self.checkBoxNewLine.isChecked(): 336 | # self.textEditReceived.insertPlainText("\n") 337 | # self.lineEditReceivedCounts.setText("%d" % self._serial_context_.getRecvCounts()) 338 | 339 | def __scanSerialPorts__(self): 340 | ports = [] 341 | for i in range(32): 342 | ports.append("/dev/ttyS%d" % i) 343 | for i in range(32): 344 | ports.append("/dev/ttyACM%d" % i) 345 | self.comboBoxPort.addItems(ports) 346 | 347 | def __open_serial_port__(self): 348 | if self._serial_context_.isRunning(): 349 | self._serial_context_.close() 350 | self.pushButtonOpenSerial.setText(u'open') 351 | print("open") 352 | else: 353 | try: 354 | # currentIndex() will get the number 355 | portss = self.comboBoxPort.currentText() 356 | port = self.comboBoxPort.currentText() 357 | print("the", portss) 358 | baud = int("%s" % self.comboBoxBaud.currentText(), 10) 359 | self._serial_context_ = serialportcontext.SerialPortContext(port=port, baud=baud) 360 | # print(self._serial_context_ ) 361 | self._serial_context_.recall() 362 | self._serial_context_.registerReceivedCallback(self.__data_received__) 363 | print("4") 364 | self._serial_context_.open() 365 | print("5") 366 | self.pushButtonOpenSerial.setText(u'close') 367 | except Exception as e: 368 | print("error") 369 | # QtGui.QMessageBox.critical(self,u"打开端口",u"打开端口失败,请检查!") 370 | 371 | def __clear_recv_area__(self): 372 | self.textEditReceived.clear() 373 | 374 | def __clear_send_area__(self): 375 | self.textEditSent.clear() 376 | 377 | @pyqtSlot() 378 | def on_test_btn_clicked(self): 379 | self.__test__send("G0 Y-100") 380 | time.sleep(0.5) 381 | self.qti = QTimer() 382 | self.qti.timeout.connect(self.aaa) 383 | self.qti.start(500) 384 | 385 | @pyqtSlot() 386 | def on_stop_clicked(self): 387 | self.qti.stop() 388 | 389 | def stop_timer(self): 390 | self.qti.stop() 391 | self.lnc_thread.create_end_file() 392 | 393 | def aaa(self): 394 | self.__test__send("?") 395 | 396 | def closeEvent(self, event): 397 | self._is_auto_sending = False 398 | if self._serial_context_.isRunning(): 399 | self._serial_context_.close() 400 | # if self._recv_file_ != None: 401 | # self._recv_file_.flush() 402 | # self._recv_file_.close() 403 | 404 | def __data_received__(self, data): 405 | # print('recv:%s' % data) 406 | self._receive_signal.emit(data) 407 | # if self._recv_file_ != None and self.checkBoxSaveAsFile.isChecked(): 408 | # self._recv_file_.write(data) 409 | 410 | def __test__send(self, data1): 411 | data = str(data1 + '\n') 412 | if self._serial_context_.isRunning(): 413 | if len(data) > 0: 414 | self._serial_context_.send(data, 0) 415 | 416 | def __send_data__(self): 417 | data = str(self.textEditSent.toPlainText() + '\n') 418 | print("i m data", data) 419 | if self._serial_context_.isRunning(): 420 | if len(data) > 0: 421 | self._serial_context_.send(data, 0) 422 | print(data) 423 | # self.lineEditSentCounts.setText("%d" % self._serial_context_.getSendCounts()) 424 | # if self.checkBoxEmptyAfterSent.isChecked(): 425 | # self.textEditSent.clear() 426 | 427 | # if self.checkBoxSendLooping.isChecked(): 428 | # self.pushButtonSendData.setEnabled(False) 429 | # delay = self.spinBox.value() * 100.0 / 1000.0 430 | # delay = 100.0 / 1000.0 431 | # self._auto_send_thread = threading.Thread(target=self.__auto_send__,args=(delay,)) 432 | 433 | # self._is_auto_sending = True 434 | # self._auto_send_thread.setDaemon(True) 435 | # self._auto_send_thread.start() 436 | 437 | def __auto_send__(self, delay): 438 | while self._is_auto_sending: 439 | # if self.checkBoxSendFile.isChecked(): 440 | # if len(self._send_file_data) > 0: 441 | # self._serial_context_.send(self._send_file_data, self.checkBoxSendHex.isChecked()) 442 | # self._auto_send_signal.emit() 443 | # break 444 | # else: 445 | data = str(self.textEditSent.toPlainText()) 446 | print("123gogo", data) 447 | if self._serial_context_.isRunning(): 448 | if len(data) > 0: 449 | self._serial_context_.send(data, 1) 450 | # self._auto_send_signal.emit() 451 | time.sleep(delay) 452 | 453 | @pyqtSlot() 454 | def on_homeButton_clicked(self): 455 | print("test the button") 456 | self.numberx = 0 457 | self.numbery = 0 458 | self.numberz = 0 459 | 460 | self.xAxis.display(self.numberx) 461 | self.yAxis.display(self.numbery) 462 | self.zAxis.display(self.numberz) 463 | 464 | data = str('G29' + '\n') 465 | if self._serial_context_.isRunning(): 466 | if len(data) > 0: 467 | self._serial_context_.send(data, 0) 468 | 469 | 470 | # MainWindow.__test__send(self, data) 471 | # self.__test__send(self, data) 472 | ''' 473 | if __name__ == "__main__": 474 | import sys 475 | app = QtWidgets.QApplication(sys.argv) 476 | run = MainWindow() 477 | run.show() 478 | sys.exit(app.exec_()) 479 | 480 | ''' 481 | -------------------------------------------------------------------------------- /core/mainwindow.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/core/mainwindow.pyc -------------------------------------------------------------------------------- /core/monitor/Ui_machine_mointor.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'Y:\eric6_workspace\PyQt5-pyserial\monitor/machine_mointor.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.7 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(806, 448) 15 | Dialog.setSizeGripEnabled(True) 16 | self.groupBox = QtWidgets.QGroupBox(Dialog) 17 | self.groupBox.setGeometry(QtCore.QRect(30, 30, 521, 331)) 18 | self.groupBox.setObjectName("groupBox") 19 | self.yAxisup = QtWidgets.QPushButton(self.groupBox) 20 | self.yAxisup.setGeometry(QtCore.QRect(120, 20, 91, 61)) 21 | self.yAxisup.setText("") 22 | icon = QtGui.QIcon() 23 | icon.addPixmap(QtGui.QPixmap("../icon/arrow-up-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 24 | self.yAxisup.setIcon(icon) 25 | self.yAxisup.setIconSize(QtCore.QSize(30, 30)) 26 | self.yAxisup.setObjectName("yAxisup") 27 | self.xAxisleft = QtWidgets.QPushButton(self.groupBox) 28 | self.xAxisleft.setGeometry(QtCore.QRect(0, 110, 91, 61)) 29 | self.xAxisleft.setText("") 30 | icon1 = QtGui.QIcon() 31 | icon1.addPixmap(QtGui.QPixmap("../icon/arrow-left-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 32 | self.xAxisleft.setIcon(icon1) 33 | self.xAxisleft.setIconSize(QtCore.QSize(30, 30)) 34 | self.xAxisleft.setObjectName("xAxisleft") 35 | self.xAxisrigh = QtWidgets.QPushButton(self.groupBox) 36 | self.xAxisrigh.setGeometry(QtCore.QRect(230, 110, 91, 61)) 37 | self.xAxisrigh.setText("") 38 | icon2 = QtGui.QIcon() 39 | icon2.addPixmap(QtGui.QPixmap("../icon/arrow-right-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 40 | self.xAxisrigh.setIcon(icon2) 41 | self.xAxisrigh.setIconSize(QtCore.QSize(30, 30)) 42 | self.xAxisrigh.setObjectName("xAxisrigh") 43 | self.yAxisdown = QtWidgets.QPushButton(self.groupBox) 44 | self.yAxisdown.setGeometry(QtCore.QRect(120, 190, 91, 61)) 45 | self.yAxisdown.setText("") 46 | icon3 = QtGui.QIcon() 47 | icon3.addPixmap(QtGui.QPixmap("../icon/arrow-down-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 48 | self.yAxisdown.setIcon(icon3) 49 | self.yAxisdown.setIconSize(QtCore.QSize(30, 30)) 50 | self.yAxisdown.setObjectName("yAxisdown") 51 | self.zupButton = QtWidgets.QPushButton(self.groupBox) 52 | self.zupButton.setGeometry(QtCore.QRect(380, 20, 91, 61)) 53 | self.zupButton.setText("") 54 | icon4 = QtGui.QIcon() 55 | icon4.addPixmap(QtGui.QPixmap("../icon/arrow-up-a.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 56 | self.zupButton.setIcon(icon4) 57 | self.zupButton.setIconSize(QtCore.QSize(30, 30)) 58 | self.zupButton.setObjectName("zupButton") 59 | self.zdownButton = QtWidgets.QPushButton(self.groupBox) 60 | self.zdownButton.setGeometry(QtCore.QRect(380, 220, 91, 51)) 61 | self.zdownButton.setText("") 62 | icon5 = QtGui.QIcon() 63 | icon5.addPixmap(QtGui.QPixmap("../icon/arrow-down-a.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 64 | self.zdownButton.setIcon(icon5) 65 | self.zdownButton.setIconSize(QtCore.QSize(30, 30)) 66 | self.zdownButton.setObjectName("zdownButton") 67 | self.label = QtWidgets.QLabel(self.groupBox) 68 | self.label.setGeometry(QtCore.QRect(380, 130, 81, 31)) 69 | self.label.setAlignment(QtCore.Qt.AlignCenter) 70 | self.label.setObjectName("label") 71 | self.unlockMachine = QtWidgets.QPushButton(self.groupBox) 72 | self.unlockMachine.setGeometry(QtCore.QRect(10, 290, 101, 31)) 73 | self.unlockMachine.setObjectName("unlockMachine") 74 | self.label_2 = QtWidgets.QLabel(self.groupBox) 75 | self.label_2.setGeometry(QtCore.QRect(140, 130, 51, 21)) 76 | self.label_2.setObjectName("label_2") 77 | self.homeButton = QtWidgets.QPushButton(self.groupBox) 78 | self.homeButton.setGeometry(QtCore.QRect(130, 290, 91, 31)) 79 | self.homeButton.setObjectName("homeButton") 80 | self.gridLayoutWidget = QtWidgets.QWidget(Dialog) 81 | self.gridLayoutWidget.setGeometry(QtCore.QRect(560, 40, 211, 131)) 82 | self.gridLayoutWidget.setObjectName("gridLayoutWidget") 83 | self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget) 84 | self.gridLayout.setContentsMargins(0, 0, 0, 0) 85 | self.gridLayout.setObjectName("gridLayout") 86 | self.label_3 = QtWidgets.QLabel(self.gridLayoutWidget) 87 | self.label_3.setAlignment(QtCore.Qt.AlignCenter) 88 | self.label_3.setObjectName("label_3") 89 | self.gridLayout.addWidget(self.label_3, 0, 0, 1, 1) 90 | self.xAxis = QtWidgets.QLCDNumber(self.gridLayoutWidget) 91 | self.xAxis.setObjectName("xAxis") 92 | self.gridLayout.addWidget(self.xAxis, 0, 1, 1, 1) 93 | self.label_4 = QtWidgets.QLabel(self.gridLayoutWidget) 94 | self.label_4.setAlignment(QtCore.Qt.AlignCenter) 95 | self.label_4.setObjectName("label_4") 96 | self.gridLayout.addWidget(self.label_4, 1, 0, 1, 1) 97 | self.yAxis = QtWidgets.QLCDNumber(self.gridLayoutWidget) 98 | self.yAxis.setObjectName("yAxis") 99 | self.gridLayout.addWidget(self.yAxis, 1, 1, 1, 1) 100 | self.zAxis = QtWidgets.QLCDNumber(self.gridLayoutWidget) 101 | self.zAxis.setObjectName("zAxis") 102 | self.gridLayout.addWidget(self.zAxis, 2, 1, 1, 1) 103 | self.label_5 = QtWidgets.QLabel(self.gridLayoutWidget) 104 | self.label_5.setAlignment(QtCore.Qt.AlignCenter) 105 | self.label_5.setObjectName("label_5") 106 | self.gridLayout.addWidget(self.label_5, 2, 0, 1, 1) 107 | 108 | self.retranslateUi(Dialog) 109 | QtCore.QMetaObject.connectSlotsByName(Dialog) 110 | 111 | def retranslateUi(self, Dialog): 112 | _translate = QtCore.QCoreApplication.translate 113 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 114 | self.groupBox.setTitle(_translate("Dialog", "Axis Adjust")) 115 | self.label.setText(_translate("Dialog", "Z jog")) 116 | self.unlockMachine.setText(_translate("Dialog", "Unlock machine")) 117 | self.label_2.setText(_translate("Dialog", "X-Y Axis")) 118 | self.homeButton.setText(_translate("Dialog", "Home")) 119 | self.label_3.setText(_translate("Dialog", "X")) 120 | self.label_4.setText(_translate("Dialog", "Y")) 121 | self.label_5.setText(_translate("Dialog", "Z")) 122 | 123 | 124 | if __name__ == "__main__": 125 | import sys 126 | app = QtWidgets.QApplication(sys.argv) 127 | Dialog = QtWidgets.QDialog() 128 | ui = Ui_Dialog() 129 | ui.setupUi(Dialog) 130 | Dialog.show() 131 | sys.exit(app.exec_()) 132 | 133 | -------------------------------------------------------------------------------- /core/monitor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/core/monitor/__init__.py -------------------------------------------------------------------------------- /core/monitor/machine_mointor.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Module implementing Machine. 5 | """ 6 | 7 | from PyQt5.QtCore import pyqtSlot 8 | from PyQt5.QtWidgets import QDialog 9 | 10 | from .Ui_machine_mointor import Ui_Dialog 11 | from PyQt5 import QtCore, QtGui, QtWidgets 12 | #from mainwindow import MainWindow 13 | from .. import serialportcontext 14 | 15 | 16 | class Machine(QDialog, Ui_Dialog): 17 | """ 18 | Class documentation goes here. 19 | """ 20 | def __init__(self, parent=None): 21 | """ 22 | Constructor 23 | 24 | @param parent reference to the parent widget 25 | @type QWidget 26 | """ 27 | super(Machine, self).__init__(parent) 28 | self.setupUi(self) 29 | 30 | self._serial_context_ = serialportcontext.SerialPortContext(port = 'COM4',baud = 115200) 31 | #self.initdaForms() 32 | 33 | 34 | 35 | # def initdaForms(self): 36 | 37 | #self.homeButton.clicked.connect(self.__test__send) 38 | 39 | def __test__send(self): 40 | data = str("G29"+'\n') 41 | print('0') 42 | #if self._serial_context_.isRunning(): 43 | print("1") 44 | if len(data) > 0: 45 | print("2") 46 | self._serial_context_.send(data, 0) 47 | print(data) 48 | 49 | 50 | # def __run__(self): 51 | # import sys 52 | # print("123") 53 | # app = QtWidgets.QApplication(sys.argv) 54 | # Dialog = QtWidgets.QDialog() 55 | # ui = Ui_Dialog() 56 | # ui.setupUi(Dialog) 57 | # Dialog.show() 58 | # sys.exit(app.exec_()) 59 | 60 | @pyqtSlot() 61 | def on_homeButton_clicked(self): 62 | print("test the button") 63 | data = 'G29' 64 | # MainWindow.__test__send(self, data) 65 | # self.__test__send() 66 | #raise NotImplementedError 67 | 68 | 69 | -------------------------------------------------------------------------------- /core/monitor/machine_mointor.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 806 10 | 448 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | true 18 | 19 | 20 | 21 | 22 | 30 23 | 30 24 | 521 25 | 331 26 | 27 | 28 | 29 | Axis Adjust 30 | 31 | 32 | 33 | 34 | 120 35 | 20 36 | 91 37 | 61 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ../icon/arrow-up-b.png../icon/arrow-up-b.png 46 | 47 | 48 | 49 | 30 50 | 30 51 | 52 | 53 | 54 | 55 | 56 | 57 | 0 58 | 110 59 | 91 60 | 61 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | ../icon/arrow-left-b.png../icon/arrow-left-b.png 69 | 70 | 71 | 72 | 30 73 | 30 74 | 75 | 76 | 77 | 78 | 79 | 80 | 230 81 | 110 82 | 91 83 | 61 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | ../icon/arrow-right-b.png../icon/arrow-right-b.png 92 | 93 | 94 | 95 | 30 96 | 30 97 | 98 | 99 | 100 | 101 | 102 | 103 | 120 104 | 190 105 | 91 106 | 61 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | ../icon/arrow-down-b.png../icon/arrow-down-b.png 115 | 116 | 117 | 118 | 30 119 | 30 120 | 121 | 122 | 123 | 124 | 125 | 126 | 380 127 | 20 128 | 91 129 | 61 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | ../icon/arrow-up-a.png../icon/arrow-up-a.png 138 | 139 | 140 | 141 | 30 142 | 30 143 | 144 | 145 | 146 | 147 | 148 | 149 | 380 150 | 220 151 | 91 152 | 51 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | ../icon/arrow-down-a.png../icon/arrow-down-a.png 161 | 162 | 163 | 164 | 30 165 | 30 166 | 167 | 168 | 169 | 170 | 171 | 172 | 380 173 | 130 174 | 81 175 | 31 176 | 177 | 178 | 179 | Z jog 180 | 181 | 182 | Qt::AlignCenter 183 | 184 | 185 | 186 | 187 | 188 | 10 189 | 290 190 | 101 191 | 31 192 | 193 | 194 | 195 | Unlock machine 196 | 197 | 198 | 199 | 200 | 201 | 140 202 | 130 203 | 51 204 | 21 205 | 206 | 207 | 208 | X-Y Axis 209 | 210 | 211 | 212 | 213 | 214 | 130 215 | 290 216 | 91 217 | 31 218 | 219 | 220 | 221 | Home 222 | 223 | 224 | 225 | 226 | 227 | 228 | 560 229 | 40 230 | 211 231 | 131 232 | 233 | 234 | 235 | 236 | 237 | 238 | X 239 | 240 | 241 | Qt::AlignCenter 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | Y 252 | 253 | 254 | Qt::AlignCenter 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | Z 268 | 269 | 270 | Qt::AlignCenter 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | -------------------------------------------------------------------------------- /core/monitor/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 852 10 | 667 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 260 21 | 220 22 | 471 23 | 171 24 | 25 | 26 | 27 | 28 | 14 29 | 30 | 31 | 32 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 33 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 34 | p, li { white-space: pre-wrap; } 35 | </style></head><body style=" font-family:'PMingLiU'; font-size:14pt; font-weight:400; font-style:normal;"> 36 | <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> 37 | 38 | 39 | 40 | 41 | 42 | 20 43 | 30 44 | 231 45 | 361 46 | 47 | 48 | 49 | 50 | 10 51 | 52 | 53 | 54 | com setting 55 | 56 | 57 | 58 | 59 | 90 60 | 30 61 | 121 62 | 31 63 | 64 | 65 | 66 | 67 | 68 | 69 | 10 70 | 30 71 | 71 72 | 21 73 | 74 | 75 | 76 | 77 | 14 78 | 79 | 80 | 81 | com 82 | 83 | 84 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 85 | 86 | 87 | 88 | 89 | 90 | 10 91 | 80 92 | 71 93 | 21 94 | 95 | 96 | 97 | 98 | 14 99 | 100 | 101 | 102 | baurd 103 | 104 | 105 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 106 | 107 | 108 | 109 | 110 | 111 | 90 112 | 80 113 | 121 114 | 31 115 | 116 | 117 | 118 | 119 | 120 | 121 | 10 122 | 130 123 | 71 124 | 21 125 | 126 | 127 | 128 | 129 | 14 130 | 131 | 132 | 133 | first 134 | 135 | 136 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 137 | 138 | 139 | 140 | 141 | 142 | 90 143 | 130 144 | 121 145 | 31 146 | 147 | 148 | 149 | 150 | 151 | 152 | 10 153 | 180 154 | 71 155 | 21 156 | 157 | 158 | 159 | 160 | 14 161 | 162 | 163 | 164 | data 165 | 166 | 167 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 168 | 169 | 170 | 171 | 172 | 173 | 90 174 | 180 175 | 121 176 | 31 177 | 178 | 179 | 180 | 181 | 182 | 183 | 10 184 | 230 185 | 71 186 | 21 187 | 188 | 189 | 190 | 191 | 14 192 | 193 | 194 | 195 | stop 196 | 197 | 198 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 199 | 200 | 201 | 202 | 203 | 204 | 90 205 | 230 206 | 121 207 | 31 208 | 209 | 210 | 211 | 212 | 213 | 214 | 10 215 | 280 216 | 201 217 | 31 218 | 219 | 220 | 221 | open 222 | 223 | 224 | 225 | 226 | 227 | 228 | 260 229 | 30 230 | 541 231 | 181 232 | 233 | 234 | 235 | 236 | 0 237 | 0 238 | 239 | 240 | 241 | 242 | 14 243 | 244 | 245 | 246 | true 247 | 248 | 249 | 250 | 251 | 252 | 740 253 | 220 254 | 61 255 | 171 256 | 257 | 258 | 259 | send 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 0 268 | 0 269 | 852 270 | 21 271 | 272 | 273 | 274 | 275 | File 276 | 277 | 278 | 279 | 280 | 281 | 282 | Mointor 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | send Gcode 294 | 295 | 296 | 297 | 298 | exit 299 | 300 | 301 | 302 | 303 | Vrep 304 | 305 | 306 | 307 | 308 | OpenGL 309 | 310 | 311 | 312 | 313 | Control 314 | 315 | 316 | 317 | 318 | 319 | 320 | -------------------------------------------------------------------------------- /core/serialportcontext.py: -------------------------------------------------------------------------------- 1 | import serial 2 | import threading 3 | import time 4 | import platform 5 | import signal 6 | from PyQt5 import QtCore 7 | import binascii 8 | 9 | 10 | class SerialPortContext(QtCore.QObject, object): 11 | _recvSignal_ = QtCore.pyqtSignal(str, name="recvsignal") 12 | _test_ = QtCore.pyqtSignal(str) 13 | 14 | def __init__(self, port=None, baud=115200, bits=8, stop_bits=1, check=None): 15 | super(SerialPortContext, self).__init__() 16 | self._port_ = port 17 | if self._port_ == None: 18 | if platform.system() == "Windows": 19 | self._port_ = 1 20 | else: 21 | self._port_ = "/dev/ttyUSB0" 22 | 23 | self._baud_ = baud 24 | if self._baud_ <= 50 or self._baud_ > 115200: 25 | self._baud_ = 115200 26 | 27 | self._is_running_ = False 28 | self._all_counts_ = 0 29 | self._recv_counts_ = 0 30 | self._sent_counts_ = 0 31 | self._serial_port_ = None 32 | self.recev = None 33 | 34 | def getAllCounts(self): 35 | return self._all_counts_ 36 | 37 | def getSendCounts(self): 38 | return self._sent_counts_ 39 | 40 | def getRecvCounts(self): 41 | return self._recv_counts_ 42 | 43 | def clearAllCounts(self): 44 | self._all_counts_ = 0 45 | self._recv_counts_ = 0 46 | self._sent_counts_ = 0 47 | 48 | def clearRecvCounts(self): 49 | self._recv_counts_ = 0 50 | 51 | def clearSentCounts(self): 52 | self._sent_counts_ = 0 53 | 54 | def setRXD(self, value): 55 | self._RXD_ = value 56 | if self._serial_port_ == None: 57 | self._RXD_ = value 58 | else: 59 | self._serial_port_.setRTS(value) 60 | 61 | def setCD(self, value): 62 | self._CD_ = value 63 | if self._serial_port_ == None: 64 | self._CD_ = value 65 | else: 66 | self._serial_port_.setDTR(value) 67 | 68 | def setDTR(self, value=True): 69 | self._DTR_ = value 70 | if self._serial_port_ == None: 71 | self._DTR_ = value 72 | else: 73 | self._serial_port_.setDTR(value) 74 | 75 | def setRTS(self, value=True): 76 | self._RTS_ = value 77 | if self._serial_port_ == None: 78 | self._RTS_ = value 79 | else: 80 | self._serial_port_.setRTS(value) 81 | 82 | def __recv_func__(self, context): 83 | # print("start serial port") 84 | while context.isRunning(): 85 | line = context._serial_port_.readline().decode('utf-8') 86 | context._recvSignal_.emit(line) 87 | self._test_.emit(line) 88 | buf_len = len(line) 89 | self._recv_counts_ += buf_len 90 | self._all_counts_ += self._recv_counts_ + self._recv_counts_ 91 | # print(self._all_counts_) 92 | 93 | print("close serial port") 94 | 95 | def registerReceivedCallback(self, callback): 96 | self._recvSignal_.connect(callback) 97 | 98 | def recall(self): 99 | print("test") 100 | 101 | def open(self): 102 | print("i am the", self._port_) 103 | # self._port_ = 'COM4' 104 | print(self._baud_) 105 | # print("the open") 106 | self._serial_port_ = serial.Serial(self._port_, int(self._baud_)) 107 | print("thread") 108 | # self._serial_port_.setRTS(self._RTS_) 109 | # self._serial_port_.setDTR(self._DTR_) 110 | self._received_thread_ = threading.Thread(target=self.__recv_func__, args=(self,)) 111 | # print("thread") 112 | self._is_running_ = True 113 | # print("thread1") 114 | self._received_thread_.setDaemon(True) 115 | # print("thread2") 116 | self._received_thread_.setName("SerialPortRecvThread") 117 | 118 | self._received_thread_.start() 119 | 120 | def close(self): 121 | print("serial context is running: %s" % self.isRunning()) 122 | self._is_running_ = False 123 | self._serial_port_.close() 124 | 125 | # def send_and_end(self, data, isHex): 126 | # if not self.isRunning(): 127 | # return 128 | # if not isHex: 129 | # buff = data.encode("utf-8") 130 | # self._serial_port_.write(buff) 131 | # # print(self.recev) 132 | # buf_len = len(data) 133 | # self._sent_counts_ += buf_len 134 | # self._all_counts_ += self._recv_counts_ + self._recv_counts_ 135 | 136 | # 137 | # ok 138 | 139 | # 140 | # ok 141 | 142 | # 143 | # ok 144 | 145 | def send(self, data, isHex): 146 | if not self.isRunning(): 147 | return 148 | if not isHex: 149 | buff = data.encode("utf-8") 150 | self._serial_port_.write(buff) 151 | buf_len = len(data) 152 | self._sent_counts_ += buf_len 153 | self._all_counts_ += self._recv_counts_ + self._recv_counts_ 154 | else: 155 | hex_datas = data.split(' ') 156 | buffer = '' 157 | for d in hex_datas: 158 | buffer += d 159 | buf_len = len(buffer) 160 | self._sent_counts_ += buf_len 161 | self._all_counts_ += self._recv_counts_ + self._recv_counts_ 162 | self._serial_port_.write(buffer.decode("hex")) 163 | 164 | def isRunning(self): 165 | return self._is_running_ and self._serial_port_.isOpen() 166 | -------------------------------------------------------------------------------- /core/serialportedittext.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import QtCore, QtGui, QtWidgets 2 | #from PyQt5.QtWidgets import (QApplication, QWidget) 3 | 4 | class SerialPortInput(QtWidgets.QTextEdit): 5 | def __init__(self,parent = None): 6 | super(SerialPortInput,self).__init__(parent) 7 | self._is_hex = False 8 | 9 | def keyPressEvent(self, event): 10 | if self._is_hex: 11 | #event.setText("%2dX " % (ord(str(event.text())))) 12 | hex_data = "%02X " % (ord(str(event.text()))) 13 | qhex_data = QtCore.QString("%s" % hex_data) 14 | #print('hex_data = %s' % hex_data) 15 | new_event = QtWidgets.QKeyEvent(event.type(),event.key(),event.modifiers(), 16 | qhex_data, 17 | event.isAutoRepeat(),event.count()) 18 | return super(SerialPortInput,self).keyPressEvent(new_event) 19 | else: 20 | return super(SerialPortInput,self).keyPressEvent(event) 21 | 22 | def setIsHex(self,isHex): 23 | self._is_hex = isHex 24 | -------------------------------------------------------------------------------- /core/vrep/Ui_vrep_setting.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file '/home/kmol/桌面/Pyquino/core/vrep/vrep_setting.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.7.1 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(797, 512) 15 | Dialog.setSizeGripEnabled(True) 16 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout(Dialog) 17 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 18 | self.widget = QtWidgets.QWidget(Dialog) 19 | self.widget.setMaximumSize(QtCore.QSize(420, 16777215)) 20 | self.widget.setObjectName("widget") 21 | self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.widget) 22 | self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) 23 | self.verticalLayout_3.setObjectName("verticalLayout_3") 24 | self.gridLayout = QtWidgets.QGridLayout() 25 | self.gridLayout.setObjectName("gridLayout") 26 | spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 27 | self.gridLayout.addItem(spacerItem, 2, 2, 1, 1) 28 | spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 29 | self.gridLayout.addItem(spacerItem1, 0, 2, 1, 1) 30 | spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 31 | self.gridLayout.addItem(spacerItem2, 2, 0, 1, 1) 32 | self.xAxisrigh = QtWidgets.QPushButton(self.widget) 33 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 34 | sizePolicy.setHorizontalStretch(0) 35 | sizePolicy.setVerticalStretch(0) 36 | sizePolicy.setHeightForWidth(self.xAxisrigh.sizePolicy().hasHeightForWidth()) 37 | self.xAxisrigh.setSizePolicy(sizePolicy) 38 | self.xAxisrigh.setMinimumSize(QtCore.QSize(125, 50)) 39 | self.xAxisrigh.setText("") 40 | icon = QtGui.QIcon() 41 | icon.addPixmap(QtGui.QPixmap(":/icons/arrow-right-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 42 | self.xAxisrigh.setIcon(icon) 43 | self.xAxisrigh.setIconSize(QtCore.QSize(30, 30)) 44 | self.xAxisrigh.setObjectName("xAxisrigh") 45 | self.gridLayout.addWidget(self.xAxisrigh, 1, 2, 1, 1) 46 | spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 47 | self.gridLayout.addItem(spacerItem3, 0, 0, 1, 1) 48 | spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 49 | self.gridLayout.addItem(spacerItem4, 1, 1, 1, 1) 50 | self.yAxisup = QtWidgets.QPushButton(self.widget) 51 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 52 | sizePolicy.setHorizontalStretch(0) 53 | sizePolicy.setVerticalStretch(0) 54 | sizePolicy.setHeightForWidth(self.yAxisup.sizePolicy().hasHeightForWidth()) 55 | self.yAxisup.setSizePolicy(sizePolicy) 56 | self.yAxisup.setMinimumSize(QtCore.QSize(125, 50)) 57 | self.yAxisup.setText("") 58 | icon1 = QtGui.QIcon() 59 | icon1.addPixmap(QtGui.QPixmap(":/icons/arrow-up-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 60 | self.yAxisup.setIcon(icon1) 61 | self.yAxisup.setIconSize(QtCore.QSize(30, 30)) 62 | self.yAxisup.setObjectName("yAxisup") 63 | self.gridLayout.addWidget(self.yAxisup, 0, 1, 1, 1) 64 | self.yAxisdown = QtWidgets.QPushButton(self.widget) 65 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 66 | sizePolicy.setHorizontalStretch(0) 67 | sizePolicy.setVerticalStretch(0) 68 | sizePolicy.setHeightForWidth(self.yAxisdown.sizePolicy().hasHeightForWidth()) 69 | self.yAxisdown.setSizePolicy(sizePolicy) 70 | self.yAxisdown.setMinimumSize(QtCore.QSize(125, 50)) 71 | self.yAxisdown.setText("") 72 | icon2 = QtGui.QIcon() 73 | icon2.addPixmap(QtGui.QPixmap(":/icons/arrow-down-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 74 | self.yAxisdown.setIcon(icon2) 75 | self.yAxisdown.setIconSize(QtCore.QSize(30, 30)) 76 | self.yAxisdown.setObjectName("yAxisdown") 77 | self.gridLayout.addWidget(self.yAxisdown, 2, 1, 1, 1) 78 | self.xAxisleft = QtWidgets.QPushButton(self.widget) 79 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 80 | sizePolicy.setHorizontalStretch(0) 81 | sizePolicy.setVerticalStretch(0) 82 | sizePolicy.setHeightForWidth(self.xAxisleft.sizePolicy().hasHeightForWidth()) 83 | self.xAxisleft.setSizePolicy(sizePolicy) 84 | self.xAxisleft.setMinimumSize(QtCore.QSize(125, 50)) 85 | self.xAxisleft.setText("") 86 | icon3 = QtGui.QIcon() 87 | icon3.addPixmap(QtGui.QPixmap(":/icons/arrow-left-b.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 88 | self.xAxisleft.setIcon(icon3) 89 | self.xAxisleft.setIconSize(QtCore.QSize(30, 30)) 90 | self.xAxisleft.setObjectName("xAxisleft") 91 | self.gridLayout.addWidget(self.xAxisleft, 1, 0, 1, 1) 92 | self.verticalLayout_3.addLayout(self.gridLayout) 93 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 94 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 95 | self.label_11 = QtWidgets.QLabel(self.widget) 96 | font = QtGui.QFont() 97 | font.setPointSize(15) 98 | self.label_11.setFont(font) 99 | self.label_11.setAlignment(QtCore.Qt.AlignCenter) 100 | self.label_11.setObjectName("label_11") 101 | self.horizontalLayout_2.addWidget(self.label_11) 102 | self.stepbox = QtWidgets.QSpinBox(self.widget) 103 | self.stepbox.setMaximum(100) 104 | self.stepbox.setSingleStep(0) 105 | self.stepbox.setProperty("value", 10) 106 | self.stepbox.setObjectName("stepbox") 107 | self.horizontalLayout_2.addWidget(self.stepbox) 108 | self.label_12 = QtWidgets.QLabel(self.widget) 109 | font = QtGui.QFont() 110 | font.setPointSize(15) 111 | self.label_12.setFont(font) 112 | self.label_12.setAlignment(QtCore.Qt.AlignCenter) 113 | self.label_12.setObjectName("label_12") 114 | self.horizontalLayout_2.addWidget(self.label_12) 115 | spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 116 | self.horizontalLayout_2.addItem(spacerItem5) 117 | self.verticalLayout_3.addLayout(self.horizontalLayout_2) 118 | spacerItem6 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) 119 | self.verticalLayout_3.addItem(spacerItem6) 120 | self.horizontalLayout_4 = QtWidgets.QHBoxLayout() 121 | self.horizontalLayout_4.setObjectName("horizontalLayout_4") 122 | self.verticalLayout = QtWidgets.QVBoxLayout() 123 | self.verticalLayout.setObjectName("verticalLayout") 124 | self.tx = QtWidgets.QDoubleSpinBox(self.widget) 125 | self.tx.setObjectName("tx") 126 | self.verticalLayout.addWidget(self.tx) 127 | self.ty = QtWidgets.QDoubleSpinBox(self.widget) 128 | self.ty.setObjectName("ty") 129 | self.verticalLayout.addWidget(self.ty) 130 | self.tz = QtWidgets.QDoubleSpinBox(self.widget) 131 | self.tz.setObjectName("tz") 132 | self.verticalLayout.addWidget(self.tz) 133 | self.horizontalLayout_4.addLayout(self.verticalLayout) 134 | self.translate = QtWidgets.QPushButton(self.widget) 135 | self.translate.setObjectName("translate") 136 | self.horizontalLayout_4.addWidget(self.translate) 137 | self.translateShow = QtWidgets.QListWidget(self.widget) 138 | self.translateShow.setObjectName("translateShow") 139 | self.horizontalLayout_4.addWidget(self.translateShow) 140 | self.verticalLayout_3.addLayout(self.horizontalLayout_4) 141 | self.unlockMachine = QtWidgets.QPushButton(self.widget) 142 | self.unlockMachine.setObjectName("unlockMachine") 143 | self.verticalLayout_3.addWidget(self.unlockMachine) 144 | self.horizontalLayout_3.addWidget(self.widget) 145 | self.verticalLayout_2 = QtWidgets.QVBoxLayout() 146 | self.verticalLayout_2.setObjectName("verticalLayout_2") 147 | self.horizontalLayout = QtWidgets.QHBoxLayout() 148 | self.horizontalLayout.setObjectName("horizontalLayout") 149 | self.openGcodeFile = QtWidgets.QPushButton(Dialog) 150 | self.openGcodeFile.setObjectName("openGcodeFile") 151 | self.horizontalLayout.addWidget(self.openGcodeFile) 152 | spacerItem7 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 153 | self.horizontalLayout.addItem(spacerItem7) 154 | self.verticalLayout_2.addLayout(self.horizontalLayout) 155 | self.progressBar = QtWidgets.QProgressBar(Dialog) 156 | self.progressBar.setObjectName("progressBar") 157 | self.verticalLayout_2.addWidget(self.progressBar) 158 | self.gcodeList = QtWidgets.QListWidget(Dialog) 159 | self.gcodeList.setObjectName("gcodeList") 160 | self.verticalLayout_2.addWidget(self.gcodeList) 161 | spacerItem8 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) 162 | self.verticalLayout_2.addItem(spacerItem8) 163 | self.horizontalLayout_3.addLayout(self.verticalLayout_2) 164 | 165 | self.retranslateUi(Dialog) 166 | QtCore.QMetaObject.connectSlotsByName(Dialog) 167 | 168 | def retranslateUi(self, Dialog): 169 | _translate = QtCore.QCoreApplication.translate 170 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 171 | self.label_11.setText(_translate("Dialog", "step")) 172 | self.label_12.setText(_translate("Dialog", "mm")) 173 | self.translate.setText(_translate("Dialog", "translate")) 174 | self.unlockMachine.setText(_translate("Dialog", "connect")) 175 | self.openGcodeFile.setText(_translate("Dialog", "Open")) 176 | 177 | import icons_rc 178 | 179 | if __name__ == "__main__": 180 | import sys 181 | app = QtWidgets.QApplication(sys.argv) 182 | Dialog = QtWidgets.QDialog() 183 | ui = Ui_Dialog() 184 | ui.setupUi(Dialog) 185 | Dialog.show() 186 | sys.exit(app.exec_()) 187 | 188 | -------------------------------------------------------------------------------- /core/vrep/vrep_setting.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from PyQt5.QtCore import * 3 | from PyQt5.QtGui import * 4 | from PyQt5.QtWidgets import * 5 | import sys, math, time 6 | from .Ui_vrep_setting import Ui_Dialog 7 | from ..vrep_remoAPI import vrep 8 | from ..gcode.gcodeParser import * 9 | import math 10 | import time 11 | 12 | 13 | la = 347 14 | to = 30 15 | pa = 40 16 | sp = 235 17 | 18 | class readingGcode(QThread): 19 | def __init__(self,getProgress, layers, parent=None): 20 | super(readingGcode, self).__init__(parent) 21 | self.getProgress = getProgress 22 | self.layers = layers 23 | self.mutex = QMutex() 24 | self.stoped = False 25 | 26 | def run(self): 27 | with QMutexLocker(self.mutex): self.stoped = False 28 | self.getProgress.setValue(0) 29 | self.getProgress.setMaximum(len([e for e in self.layers[0].segments])) 30 | self.layer_vertices = list() 31 | for layer in self.layers: 32 | ''' 33 | x = layer.start["X"] 34 | y = layer.start["Y"] 35 | z = layer.start["Z"] 36 | ''' 37 | for seg in layer.segments: 38 | seg_x = seg.coords["X"] 39 | seg_y = seg.coords["Y"] 40 | seg_z = seg.coords["Z"] 41 | self.layer_vertices.append([seg_x, seg_y, seg_z]) 42 | self.getProgress.setValue(self.getProgress.value()+1) 43 | def stop(self): 44 | with QMutexLocker(self.mutex): self.stoped = True 45 | 46 | 47 | class vrepsetting(QDialog, Ui_Dialog): 48 | def __init__(self, parent=None): 49 | super(vrepsetting, self).__init__(parent) 50 | self.setupUi(self) 51 | self.initForms() 52 | # child threaded script: 53 | # 內建使用 port 19997 若要加入其他 port, 在 serve 端程式納入 54 | #simExtRemoteApiStart(19999) 55 | 56 | def initForms(self): 57 | self.openGcodeFile.clicked.connect(self.__open_file__) 58 | self.translate.clicked.connect(self.ik_transform) 59 | 60 | 61 | 62 | def ik_transform(self): 63 | 64 | tx = self.tx.value() 65 | ty = self.ty.value() 66 | tz = self.tz.value() 67 | 68 | a1x = tx+pa 69 | a1y = ty 70 | a1z = tz+to 71 | 72 | #pivot B 73 | b1x = tx + pa * math.cos(math.radians(120)) 74 | b1y = ty + pa * math.sin(math.radians(120)) 75 | b1z = tz + to 76 | ##pivotC 77 | c1x = tx + pa * math.cos(math.radians(240)) 78 | c1y = ty + pa * math.sin(math.radians(240)) 79 | c1z = tz + to 80 | ##carriage 81 | a2x = sp 82 | a2y = 0 83 | #a2z = tz+to+ha 84 | ##Cb 85 | b2x = sp*math.cos(math.radians(120)) 86 | b2y = sp*math.sin(math.radians(120)) 87 | ##carriage C2x = sp*cos(240) 88 | c2x = sp*math.cos(math.radians(240)) 89 | c2y = sp*math.sin(math.radians(240)) 90 | 91 | aa = math.sqrt((a2x-a1x)*(a2x-a1x)+(a2y-a1y)*(a2y-a1y)) 92 | ha = math.sqrt(la*la-aa*aa) 93 | 94 | ab = math.sqrt((b2x-b1x)*(b2x-b1x)+(b2y-b1y)*(b2y-b1y)) 95 | hb = math.sqrt(la*la-ab*ab) 96 | 97 | ac = math.sqrt((c2x-c1x)*(c2x-c1x)+(c2y-c1y)*(c2y-c1y)) 98 | #print(ac) 99 | hc = math.sqrt(la*la-ac*ac) 100 | 101 | a2z = tz+to+ha 102 | b2z = tz+to+hb 103 | c2z = tz+to+hc 104 | 105 | print(a2z,"/n",b2z,"/n",c2z) 106 | self.translateShow.addItem("(X: {:.04f},Y: {:.04f},Z: {:.04f})".format(a2z, b2z, c2z)) 107 | 108 | 109 | def __open_file__(self): 110 | filename, _ = QFileDialog.getOpenFileName(self, "Open Files", '..', 'GCode(*.gcode)') 111 | if filename: 112 | 113 | #path = 'test_gcode.gcode' 114 | parser = GcodeParser() 115 | self.model = parser.parseFile(filename) 116 | print("Done! %s"%self.model) 117 | 118 | self.renderVertices() 119 | get = [] 120 | for i in range(len(self.layer_vertices)): 121 | x, y, z = self.parsePostion(i) 122 | get = str(x),str(y), str(z) 123 | self.gcodeList.addItem(str(get) ) 124 | self.sendPoisiontoVrep(x, y, z) 125 | #print(x, y, z) 126 | else: 127 | print("No file") 128 | 129 | def sendPoisiontoVrep(self, e, r, t): 130 | 131 | vrep.simxFinish(-1) 132 | clientID = vrep.simxStart('127.0.0.1', 19998, True, True, 5000, 5) 133 | if clientID!= -1: 134 | #print("Connected to remote server") 135 | time.sleep(0.5) 136 | errorCode,plate=vrep.simxGetObjectHandle(clientID,'plate',vrep.simx_opmode_oneshot_wait) 137 | 138 | 139 | if errorCode == -1: 140 | #print('Can not find plate') 141 | sys.exit() 142 | errorCode=vrep.simxSetObjectPosition(clientID,plate,-1,[e/1000,r/1000,t/1000+0.1165],vrep.simx_opmode_oneshot_wait) 143 | #print(e/1000,r/1000,t/1000) 144 | else: 145 | print('Connection not successful') 146 | sys.exit('Could not connect') 147 | ''' 148 | time.sleep(0.5) 149 | errorCode,plate=vrep.simxGetObjectHandle(clientID,'plate',vrep.simx_opmode_streaming) 150 | 151 | 152 | if errorCode == -1: 153 | #print('Can not find plate') 154 | sys.exit() 155 | errorCode=vrep.simxSetObjectPosition(clientID,plate,-1,[e/1000,r/1000,t/1000+0.1165], vrep.simx_opmode_streaming) 156 | #print(e/1000,r/1000,t/1000) 157 | ''' 158 | 159 | def renderVertices(self): 160 | work = readingGcode(self.progressBar, self.model.layers) 161 | work.run() 162 | self.layer_vertices = work.layer_vertices 163 | 164 | def parsePostion(self, pos): 165 | row = self.layer_vertices[pos] 166 | return row[0], row[1], row[2] 167 | 168 | @pyqtSlot() 169 | def on_xAxisleft_clicked(self): 170 | test = [] 171 | vrep.simxFinish(-1) 172 | clientID = vrep.simxStart('127.0.0.1', 19999, True, True, 5000, 5) 173 | deg = math.pi/180 174 | if clientID!=-1: print("Connected to remote server") 175 | else: 176 | print('Connection not successful') 177 | sys.exit('Could not connect') 178 | 179 | errorCode, test = vrep.simxGetObjectPosition(clientID,'STL_Imported_sub14',0, vrep.simx_opmode_streaming) 180 | #errorCode, Xaxis_joint = vrep.simxSetObjectPosition(clientID, 'Xaxis_joint', vrep.simx_opmode_oneshot_wait) 181 | 182 | if errorCode==-1: 183 | print('Can not find left or right motor') 184 | sys.exit() 185 | 186 | 187 | print(test) 188 | print("test") 189 | #i =360 190 | #for i in range(360): 191 | # errorCode = vrep.simxSetJointPosition(clientID, Xaxis_joint,i*deg, vrep.simx_opmode_oneshot_wait) 192 | #def setJointPosition(incAngle, steps): 193 | # for i in range(steps): errorCode = vrep.simxSetJointPosition(clientID, jointx, i*incAngle*deg, vrep.simx_opmode_oneshot_wait) 194 | 195 | #setJointPosition(10, 720) 196 | 197 | 198 | ''' 199 | -- Put some initialization code here: 200 | simSetThreadSwitchTiming(2) -- Default timing for automatic thread switching 201 | simExtRemoteApiStart(19999) 202 | 203 | 204 | -- Here we execute the regular thread code: 205 | res,err=xpcall(threadFunction,function(err) return debug.traceback(err) end) 206 | if not res then 207 | simAddStatusbarMessage('Lua runtime error: '..err) 208 | end 209 | 210 | -- Put some clean-up code here: 211 | ''' 212 | 213 | -------------------------------------------------------------------------------- /core/vrep/vrep_setting.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 797 10 | 512 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | 420 25 | 16777215 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Qt::Horizontal 35 | 36 | 37 | 38 | 40 39 | 20 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Qt::Horizontal 48 | 49 | 50 | 51 | 40 52 | 20 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | Qt::Horizontal 61 | 62 | 63 | 64 | 40 65 | 20 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 0 75 | 0 76 | 77 | 78 | 79 | 80 | 125 81 | 50 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | :/icons/arrow-right-b.png:/icons/arrow-right-b.png 90 | 91 | 92 | 93 | 30 94 | 30 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | Qt::Horizontal 103 | 104 | 105 | 106 | 40 107 | 20 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | Qt::Horizontal 116 | 117 | 118 | 119 | 40 120 | 20 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 0 130 | 0 131 | 132 | 133 | 134 | 135 | 125 136 | 50 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | :/icons/arrow-up-b.png:/icons/arrow-up-b.png 145 | 146 | 147 | 148 | 30 149 | 30 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 0 159 | 0 160 | 161 | 162 | 163 | 164 | 125 165 | 50 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | :/icons/arrow-down-b.png:/icons/arrow-down-b.png 174 | 175 | 176 | 177 | 30 178 | 30 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 0 188 | 0 189 | 190 | 191 | 192 | 193 | 125 194 | 50 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | :/icons/arrow-left-b.png:/icons/arrow-left-b.png 203 | 204 | 205 | 206 | 30 207 | 30 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 15 221 | 222 | 223 | 224 | step 225 | 226 | 227 | Qt::AlignCenter 228 | 229 | 230 | 231 | 232 | 233 | 234 | 100 235 | 236 | 237 | 0 238 | 239 | 240 | 10 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 15 249 | 250 | 251 | 252 | mm 253 | 254 | 255 | Qt::AlignCenter 256 | 257 | 258 | 259 | 260 | 261 | 262 | Qt::Horizontal 263 | 264 | 265 | 266 | 40 267 | 20 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | Qt::Vertical 278 | 279 | 280 | 281 | 20 282 | 40 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | translate 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | connect 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | Open 332 | 333 | 334 | 335 | 336 | 337 | 338 | Qt::Horizontal 339 | 340 | 341 | 342 | 40 343 | 20 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | Qt::Vertical 360 | 361 | 362 | 363 | 20 364 | 40 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | -------------------------------------------------------------------------------- /core/vrep/vrep_test.py: -------------------------------------------------------------------------------- 1 | 2 | from ..vrep_remoAPI import vrep 3 | -------------------------------------------------------------------------------- /core/vrep_remoAPI/one_link_robot_remoteAPI_joint_position.py: -------------------------------------------------------------------------------- 1 | import vrep 2 | import sys, math 3 | # child threaded script: 4 | # 內建使用 port 19997 若要加入其他 port, 在 serve 端程式納入 5 | #simExtRemoteApiStart(19999) 6 | 7 | vrep.simxFinish(-1) 8 | 9 | clientID = vrep.simxStart('127.0.0.1', 19997, True, True, 5000, 5) 10 | 11 | if clientID!= -1: 12 | print("Connected to remote server") 13 | else: 14 | print('Connection not successful') 15 | sys.exit('Could not connect') 16 | 17 | errorCode,Revolute_joint_handle=vrep.simxGetObjectHandle(clientID,'Revolute_joint',vrep.simx_opmode_oneshot_wait) 18 | 19 | if errorCode == -1: 20 | print('Can not find left or right motor') 21 | sys.exit() 22 | 23 | deg = math.pi/180 24 | 25 | #errorCode=vrep.simxSetJointTargetVelocity(clientID,Revolute_joint_handle,2, vrep.simx_opmode_oneshot_wait) 26 | 27 | def setJointPosition(incAngle, steps): 28 | for i in range(steps): 29 | errorCode=vrep.simxSetJointPosition(clientID, Revolute_joint_handle, i*incAngle*deg, vrep.simx_opmode_oneshot_wait) 30 | 31 | # 每步 10 度, 轉兩圈 32 | setJointPosition(10, 72) 33 | # 每步 1 度, 轉兩圈 34 | #setJointPosition(1, 720) 35 | # 每步 0.1 度, 轉720 步 36 | #setJointPosition(0.1, 720) 37 | 38 | ''' 39 | 三軸同動時 40 | simxPauseCommunication(clientID,1); 41 | simxSetJointPosition(clientID,joint1Handle,joint1Value,simx_opmode_oneshot); 42 | simxSetJointPosition(clientID,joint2Handle,joint2Value,simx_opmode_oneshot); 43 | simxSetJointPosition(clientID,joint3Handle,joint3Value,simx_opmode_oneshot); 44 | simxPauseCommunication(clientID,0); 45 | ''' 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /core/vrep_remoAPI/remoteApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/core/vrep_remoAPI/remoteApi.dll -------------------------------------------------------------------------------- /core/vrep_remoAPI/remoteApi.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/core/vrep_remoAPI/remoteApi.so -------------------------------------------------------------------------------- /data.txt: -------------------------------------------------------------------------------- 1 | -1 -------------------------------------------------------------------------------- /icons.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icons/arrow-down-a.png 5 | icons/arrow-down-b.png 6 | icons/arrow-left-b.png 7 | icons/arrow-right-b.png 8 | icons/arrow-up-a.png 9 | icons/arrow-up-b.png 10 | icons/serialport.png 11 | icons/usb.png 12 | 13 | 14 | -------------------------------------------------------------------------------- /icons/END: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/END -------------------------------------------------------------------------------- /icons/START: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/START -------------------------------------------------------------------------------- /icons/arduino_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/arduino_example.png -------------------------------------------------------------------------------- /icons/arrow-down-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/arrow-down-a.png -------------------------------------------------------------------------------- /icons/arrow-down-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/arrow-down-b.png -------------------------------------------------------------------------------- /icons/arrow-left-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/arrow-left-b.png -------------------------------------------------------------------------------- /icons/arrow-right-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/arrow-right-b.png -------------------------------------------------------------------------------- /icons/arrow-up-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/arrow-up-a.png -------------------------------------------------------------------------------- /icons/arrow-up-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/arrow-up-b.png -------------------------------------------------------------------------------- /icons/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/cover.png -------------------------------------------------------------------------------- /icons/serialport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/serialport.png -------------------------------------------------------------------------------- /icons/usb.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/usb.ico -------------------------------------------------------------------------------- /icons/usb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmolLin/Pyquino/435a66db3efdd469fc574404b6867a2f1212a6af/icons/usb.png -------------------------------------------------------------------------------- /launchPyquino.py: -------------------------------------------------------------------------------- 1 | # Start Pyquino 2 | # Use PyQt5 communcation with serial port and vitural machine with Vrep 3 | # Including Python module: PyQt5, pygraphy, pyopengl 4 | # Copyright (C) 2017 you shang [smpss91341@gmail.com] 5 | 6 | from core.mainwindow import MainWindow 7 | from PyQt5.QtWidgets import QApplication 8 | from core.info import showof 9 | from sys import argv, exit 10 | 11 | if __name__=='__main__': 12 | QApplication.setStyle('fusion') 13 | app = QApplication(argv) 14 | run = MainWindow(showof()) 15 | run.show() 16 | exit(app.exec_()) 17 | -------------------------------------------------------------------------------- /pnael.py: -------------------------------------------------------------------------------- 1 | 2 | def __pane__(first, step): 3 | # print(first) 4 | impovert = first +step 5 | return impovert 6 | 7 | 8 | def __minerse__(first, step): 9 | # print(first) 10 | impovert1 = first -step 11 | return impovert1 12 | 13 | 14 | def __updateui__(x, y, z): 15 | x=0 16 | y=0 17 | z=0 18 | return x, y, z 19 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyopengl 2 | PyQtGraph 3 | pyserial 4 | 5 | --------------------------------------------------------------------------------