/Gimbal/_BruGi/GUI/blg-tool.tcl

https://github.com/macressler/x-VTOLdrone · TCL · 1526 lines · 1287 code · 178 blank · 61 comment · 175 complexity · 5b304ea674d39b3e1d1dc23c970fed76 MD5 · raw file

Large files are truncated click here to view the full file

  1. #!/usr/bin/wish
  2. #
  3. # Copyright by Oliver Dippel <oliver@multixmedia.org>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # any later version. see <http://www.gnu.org/licenses/>
  9. #
  10. set VERSION 49
  11. #####################################################################################
  12. # Big hexdata
  13. #####################################################################################
  14. set HEXDATA ""
  15. image create photo logo -data {
  16. R0lGODlhyAA2APcAAFxbV1tbW3RsX3hsX2NjY25uZ25sbH9nZ3NsZnpuZXJra3tsanlxZXZzbXty
  17. a21tc21sfHFrc3BsfmxxdWxze3Nzc3t1cnR6d314cXN0fHV5e3x7e4JtZoNtaY5sbod2Z4RzbYlx
  18. bod7aIt8bZB4bo1vcYlxc4R5cYp+dIN+e5V+dZR+eo6FdI6EeZKEdZyBd5eIcZGFepWKfp2Me6yP
  19. c6qQc6SSfmxtgXJqgW91g2x9hG16iHR2gnZ7hHp9g3V6inl9i3yBhneBiHyDjH6Ij3qIkHmGmn6M
  20. mYSEhYiFgoSDi4GMj42NjZeHgpWMhJyMhJCLip2ThZSRi5yUiJ+ejIKHlYmHl4SJkoiNkISGmoOM
  21. m4qJm4WRnoyUnJWVlZuYk5OXnJubnKGUg66TgKSYh62ag6Wai62cjaWblKedma+gj7Clj66ikayl
  22. ma+pmbWik7qlkreqlbqplbWlm7qnmLapm7iqnrGwmIKNoIiNpIaSpIiQoo6Zp4SQqJKUo5Sdq5Kf
  23. spOkrZqhrZ2msJurtpumupqsu52yvamloKGkq6Wqr6mrrLiqoryxorSzrb2+rqWqsKqtsqOtvKqv
  24. v66xtaKwurKztrO1ubW5vL29v8Ctnca1mMKxpMq5psCzqcO9rMy9rc2+sdC/stTEr9LEs9jHsdvI
  25. tNXMut7PuOHUvKevwqS1xqy2xKe5wqu6xaOzy6e/zKq7yrC8xru+wq7Cz77AxavI1rPF07DI0r3P
  26. 3b7R1cLExcLEyc3Nz9HR0ePWxOjXxOPaxOnbxM7i3+zgxOvizfDkzu7l0PHo1s7j6tHj5dHm69Ho
  27. 6/385f776eP0+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  28. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  29. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAANAALAAAAADIADYA
  30. AAj+AKEJHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3Mixo8ePIEOKHEmypMmTKFOqXMmypcuX
  31. MGPKnEmzps2bOHPq3Mmzp8+fQIMKHUq0qNGjSJMqXcq0qdOnODNBW7TBAAECBgwEgcp1YyZLvbwE
  32. ABCgrNkABph0XTsRk6Ja0AgAIHv2bAW1bPMyVEQJWoUAWNESMEu3bAW9iA9SUjQLWtaCTP7WBewj
  33. sWVoihQJJJBQct0NlxFnFnhYoeexAAyEzgsJEi9oYRgiGVyWbOnVXCHxhXg6wG3cTjP35X0WwG+E
  34. HRQgUKAga5ePHiLIOlgHwRaRbRAYiGAQxAOJHL7+R0wgvuKl0RF7HzfYIauB5ggebOXYLLqrg3QU
  35. 5Al5woD2+DkQ5IABq4xnACwQpdLAA7dYFIkikAxH3FmgJdRBBM8J5AQDBvxBnwkQqIKfAll8dMoB
  36. D0wgkAwWKBCgRQPGkiB5DVqUGSQT9eaFhRGwQtAYBhRRECMGXNGQBQYUcMFAzZjwwCDQKPAAFgPV
  37. QSJBGCgwQWwEtVjAeg4w1wNBLSxg5EClOPBAIAoNWKEUBlhAEAcGyOKEAQ0IUtAGERjQwkCpqFlj
  38. RZS0hkmOZ6mGXASSEDRChwLJoUAVAw4BzQoGNApNKAdIkAw0bTTnHwIvNonABctJ6YdAVmoh0Cf+
  39. CTAXn6XQkOJAAcxJaYhAU8T3gHZCCDSKlpUoBIICr0BTQwJA9PceEi34p0AGAyUQgQbvaekhNGss
  40. oNyvGegCTSrxDUoRJq1pNpEBZ+HFngEPwBtBAxGcCY2kEQyBAJSYalrKATcsAw0LBiQikAUPWOqM
  41. CQZoAAY0LigAhEBvXAkNCgZY+okDExQCjRkGXAdNrxND40ADBkODJCD3KrDDQg5EUCANzY15Rlbc
  42. nTFgKwIxEMGS0DiBwMvQwKAAH9DYgUAEPKfCwAS4YFTobhPRVhZy72W93JiRGnCbMyswKtApCdyg
  43. DDQfPKCEQc2EACk0oChwg0BnWAfNJgjwMBD+GwYcAc0ZWq5HHhEGzYGADgMxwtwDCuwhUJgzI0At
  44. NMTE6zHEChDy+NvAxCciNI4M5F2jqdCYUbpwSbTBWUiwfaGeA7lgwA8UK2AEQSpEUCw0pywggUA2
  45. xPeeBipC40wIPQokCgK/Q1NdiWUkUMEES7foKie3ZlXB5NDM0FxzFZwJhwKIC6T4cgbo8bgCBQZf
  46. 4TFaxm6A5tCQF7VAJCgwnYYVgPDeIeMSVEYsoRt1SYRdZeEMex4wCYIA4z2NuhkeCLKCB1zuRDhg
  47. hkDuYIEGNEdt0Ghb8mqlgOZZqUQ2kF4FEACB91RhICdwAPo0MBAzNCBW8XIcKbR0H4JEoQD+6jOZ
  48. zKCRwvkYI34CkR39BoQg/NUJGmJAQAUe8IUBkc50GVlMayhyFi4RpAMP8NFAfrEdGbWKIDFQgKbi
  49. doNhFOQRYjCA3kQoRlIsAAcCyc91OjEA7iWkVwqwhUFkgAAhQWMECuBCQWBQgP2YjEBEHEDJjGGA
  50. 4kEsAktMpECCQR5akOtFaIsAAEvHoI1EojU4OqBZgPbFCHhxYNPqmt8G8oIBjKkNJ5CbQD4QgSUI
  51. hAz5Ml4JIiCjTTHvGc5TgBWgcQwUPICG0MBA8aJgAK6hYQEQyAUqElAkgcTAAK6ChiYWkDGBSMFb
  52. BujD5tqHAFpR0pJKFAh5KlCZGCCAdqb+gNfEmtCcXQFjAaXUCC8gpIhISIQJZqkQQdCZLQUUIAJs
  53. gkZ+FDkQOGTLAD5IAA4+1Ygwfa88IQijQOJmQot5woPMwajycpnSB4QzDdaSlt4G8oRb9WlxlXnc
  54. EIM3n2NUciDfpJ/0LpArCGiKYNp5QBLSB41fYFEjs0iXQSNiFkUJ6Kai8uMTEEDRgdghBQqojHcI
  55. goYKKGA+ArnQ/jjBPFY9wJECScF2DMIED3KnIFBwz0FC9ZiCIOk+arBA66CBDHjVsAG7A8FhZHAB
  56. CBQEDQqgoScsMKZinMCSG3ELhKb6EA2UxarAcQq6WsPZhiAUAKwMrVN4kS7GOCQFZUlmrWqd0tpL
  57. NGQw65ltUxaTGUUcKiGry61um0LA3kbitwPhxSK+INzhPqVQkHiQIi7RGIP4wrl6ieopMxMJS0Ti
  58. u5ewLXYRUwtMUEK6BaXELsbL3va6973wja9850vf+tr3vvhFSUAAADs=
  59. }
  60. image create photo sensor -data {
  61. R0lGODlheABmAOf8ACQlJiUmKScoKysrLSgpJy4wLzExLi0uMjEvMy8wMy4yOTIzNTY4Nzk5NjU2
  62. OTc4Ozo7PTk3OjEvLBwdH0c9PFg9OFI6L3I6Mz5BPz5GN0FBPklFOlhEOlVRPWRIO3RLOz0+QTg7
  63. Q0I+REk+ST9BQz1IRzlVVEJDRUtEREVJRkpKRkVFSUpFS0ZJTEpLTVNFQ1JNTFhKR05RTkdSSlJS
  64. TVlTSkZMUkxNUkpJVlJNU1ZMVk5RU0xTW0hVV1NTVFpUVFZYVlpZVlRVWVtUW1ZZW1tbXGVKR2dT
  65. SXdVSmNcW2hYV3ZbWHJNRl1hXlVlXEZgX2JiXmpjXXhjW21gTktaYl1eYVZZY2JdZGpeZ3Jeal5h
  66. Y11laltoaFZsbmNjZGtkZGVpZmtqZmVlaWpla2Vpa2trbHJsbHdoZ25xbmVxbHJybnlybWVtcmxt
  67. cmhpdHJtdHdqdW5xdG1zemh0dXNzdHp0c3Z4dXt6dXR1eXd4e3t7fHp1fJ1YNdBnPYhZSo5dU61c
  68. T4hkW5hnWJJqVKlpWLVpV7hzWbBoT4dpZpdsZ4h0bpd1a4J+e4V4dZZ6dotscad4aLh4Z614co1f
  69. YchqVsh1V9FvTMZ5Zcp1a8BeQ36AfXiDd4KCfoqFe5yLfrWGebSGdMqKdOWHZ31+gXR3hGdugYh9
  70. gn+AgoODhIuKhYWGiYeIiouLjIiHhJGOipWKhI6RjpOSjZmVjI2OkY+QkpOUlJualZWWmZeYmpuc
  71. nJiXlJeMkLWKhbiVi6Obl7aal6ePiZ6gnqSinauhmbmhmp2eoZ+goqOjpKusq6iop7iqp7S0s7q5
  72. uLGvrsiViNWVicicls+RjMijmdanl9KtlcSrp9m3qse7uM6zreS4ruSjmc7EuerIu8jIx9TSzdTU
  73. 09zc3NnY1tXMx+jVyPjYyufb2PDRy9zi3Prm2e/q2uTk4+zs6+vo5vjr5+vz7PXz7f707P777Pv4
  74. 5u39/O369/X19Pz29PT79fz79fX1+/32/PX8/f////nu9t/g5MC/wSH+EUNyZWF0ZWQgd2l0aCBH
  75. SU1QACH5BAEKAP0ALAAAAAB4AGYAAAj+APsJHEiwoMGDCBMqXMiwocOHECNKnEixosWLGBOq+5ax
  76. o8ePCsNx8oEhD8iTKC+GW5UiRQMNGvS4S0mzpkJvqVycOMGgAQSXumwKtRmvWxgVGjCAeMDgAYQH
  77. D0jgGkoVJDgwEBowWLpggYMFUJ1COFa1rEVvqFRAWLvgwAMHDqDGZXqCBTKzeB9+24OBxAOvJw44
  78. SOA1RNwITHu6+Je3McJuXjRA+OrgQIQQERAgUOD1a1ixKc45Ht2PGR0SC3wq+BqirQMFCA54jcA5
  79. hAKoDCDQWEca7zIyEMA+SMAAQQS4giO0Nfx1dQgQCwiTwPBlZu+hy4qcWAu1LQTacB3+DLDMWbZz
  80. B9+hZiXhhfd1mtlPNFiwdnLwB5cRDBAv+8CB/ayBFQJm6p3QxnsoBQNEAxgwwABh3AXHwGuvebUA
  81. AgsosFplC0QAXVgRNAUBIwh25M4xRUAgn1eELXVACMNBAMJzGT4Qgn//DRDBZIiFF5cDCDRwQisl
  82. XsQMECCc8FdWCzAAowMhKCkYCJUhQKECboV3WXgQ4LjagygYU+REpp0gAgi55dakf0D+FcEAELT2
  83. lo0wKkCgYA+AcICVD9wWGwQDgCBCM2M+hEsLK6QQIgRqMtDkA24J1lVXG/oHwox/iQCWA4gdd2FX
  84. +nkYIgPLFKqQOrBoF1x6ECQQwZ7+D2h6AJUvxumhAjoi8ICVHToVAgKt2ZcAC2KcQGV3C6TQjakG
  85. raPHdi5hwNNTbp3glWyvDejAUhG8GteGCjwVl65wwfgAEaqoogVUhg33oAvgMCsQOHSgwFMJf5GQ
  86. AJR6lqeccRvCFZtsbR23bbdP/lpZAjeg4sWDEgS3gAGTRnACO6aG8wYJuTHKgAINGCBjjbIpZ3Br
  87. z+Up4IU9dueUXCHs4MMJdqS4wswaftVVBCIU4R6C4YCxQIPKgVUClhhoyG5sOiuHLa8vtoahZ5zG
  88. 6cAKo5iCRxD07eHFKntwbNtcUFEABYL+eJFCVms5gMNSRytQgIYH4IoluSuEIIL+YXw/lRmUfT53
  89. 4wMnqFIFAmuBMIAMerSwwIwtsHGA3xFIQIEdvZ3jhQspYFDZjz++CCSQz0E5wF/+DWjuZyB8Z6xT
  90. M+KwghDF8IDDFXmMokoRaOBxghCo1EIGWCpmNnQsjp1TxHwYvLxpl5d2hiN9xp4J1QEnoGzjrBLH
  91. uQKVKzjggyoPiDHKKGIwusIxJ5DByig3JACBFrWcggagPTXgCl7eNOEX7HmClI5gJADk2AZYq6kb
  92. hSzTIdjYCConQNil8CAHH6wGD6QIgcQSgAAZGOMpXUlAAryAihVE7GMLoAAENJCMqrBDDa1bUnDy
  93. 9rkBDcCGT9pWluxUGeZYCFf+ULmU+EjhAC0UAxm0GIMDWCGHBIBgZnpghRDa0gK1OUAVdOiKC7wg
  94. BCEkQCsaYIZQuiEDFTFlUm/pz1f2RKs9PSlS+4nSAwawGhAo4Dgaah0OVEGLFEQnDqrwgSloMYpi
  95. yKFwozjcA1awh1nQgVEn0EMrRrE5EMTBC39hAAbCQRNm7KRVunLiX2wEJaelDjaRwlScBoesuSCm
  96. K7NihQ9kkwBrhWEVlynC+/QksQfUT0LiqSVhoCIEMtDyJ5wESTdokIICbIcBtVpLAjCDrScN4ELi
  97. WcqvPBQo/MwISl7hjAJWUAUhDKANxvSBF8DCgFmMgkMswM3kFjCLdTJABif++IoEonMCGWhiBRdi
  98. IA0+8g0XiIB5DCCB1QxAHKdcszNr9MpboDSXQBXQP5uZ6ALGpwor4CA1raADLVwAFsHgARVLuQ0p
  99. aJEMVCxvFV7AQy1WAELg2cEJXemT8Qxwgox8AwprGw59+qQAjjVgAEdtUEndMgA6ns4wHeqK1HQ2
  100. J/SIABVVaNI191OLUT5ACzdw0V/EQItAnaAYLiDB7hhAsdwoDjataWoaIUCBMFzkGAzCQKsY9ZoB
  101. JGAGXmiFHcIQBgP4RXBf2cyOZqSAMwGLNiLYT5Zw4AIIFMMLvAueKuwghDakQKReAME0fWAYHqwi
  102. OAlIQTFOUIQ9HFUIs2j+A2J0BZXTiUA8aznBDyyCih+wxTuTWwsnkiEMW9jiDmGYj2EGYKXKZAlK
  103. GOrRNZcigEuB4BYrKEIbTIHJAUiAFlWYBS7M+bEqkOEGpxvAKnYQKAjIYBUB0EMqUEGG4XxGTQMS
  104. DAT0o4GzTWQddWCFkrojP6eEQRiu8IUnZCGLVKhAPMYB0niONaA8xcYwViJDBd2ihVmczon/8aXj
  105. mAKVNoyCWuGzASoC8zhWLCUwbPnLpLgTQaYAyieqoMgb1KAH+UFzLQNwQSpk0YlOENkVsmiC/G50
  106. oxfBBi5wGoxbvDCKETYjF7RIURvy0BU8CEEMtyBDAubYlgGcFQ97wMP+KPIQAhyswgo+qMIqFuDd
  107. PEngQW7ZgQvGzK7TOcXHpZLIG+KABztwBVIYaIAPXJEKIxdZFxpAwKU8BB06K4dqCDBfEYZDgh3k
  108. gQRVuIUqcKEHAKihDDtw1APwwApRO2oFZAhBAA6wglNACgRiyOoCAgAX+UVAfhAIaYoSEFklATsB
  109. KjgBYyJCBzXQAQ9lmA8DEAOoFBQ3FZqwhQYIE5fWZWtWOxJqG3QRRLckgA65GM4JjnGLHUAgAF0J
  110. AANQMUci4ALDUCngLAzDlYGN5z83aIGifXGMMgSHZ2PT01IaEIRlQYQObShDG/CAz8ppaAAEmFgG
  111. tOIoKg2ubrHBjwD+RvgXXAyvDXMeABBQMYqXOVRF1gJBfSUQADKs4gAC+PIJyrCHpkYXAdXVVQhc
  112. MIpTJKUBDaAFLFYwtT4toF0DkMzPGqIGNchBDmOwAw7OA5fHGeZFi7RRl2B0aTpDQA1cBkEtVlEM
  113. MYAdBLTAQ4gdIIJjzEIMT6eFQxMQB014xQ1agJF/6JgAwQygJ1CAARA64QUYQ+AUX0A6lYxzAFdJ
  114. SANTX8ganN0GNzj7TTjSz+Tm2K3JWDeIIMBi4UGgC8J4gRY3Qs8bWEGCEOQtQ7kYA6QSoPKuBqcB
  115. rJDNfpQkMAXsq1XNTsUd7tCJWCBJfgUoQx7+YsenP0gsDVjDQ9T+EAY6yCHiZUBF6fMEuB52Zksz
  116. uoKMUEGHv6xiJwhw5w6ucIxRRDYuIvjPLPAAglPcIhcQQATFQAYqoAp5gCWjsyvjsYCaAQKogArC
  117. IAvMZwd+kXELoAtakB7BFACroiMw4BDIRQd70AZyAG0thyXBIQEIcGdDBSJPEVj+oVpkUASzMDkK
  118. MAu50AaFtx9zlE8O0AK0cAteMAACcAvRoQeogAZuASk4wlwLQxgPRQuu8AqyoAupYAcLUAAEQBgt
  119. IACQgh+VR2zJshZ2xRCcYAZnsAdvUArgVwb+0SRtsSRLkgBFQAfisQBJCIV6sHYpwAArkE8RdAMy
  120. gCUFxFij4Dv+EEACq+BQ15Q6soEAxPEUG9IqJ+ACDWALwtAKKCAMLjUAJPAiC0AEVeADIiRa1yRC
  121. E8MAasAQ3cAIvtAIo0AGYiAHZNAGQhAWjLIWAdAS+zQK7IYHLXACGDgAASABJ0AL6TMg0RMBJbQC
  122. qyEGqIAHAzBIWkB0Y+ZXetIWKAgEQBAcIeBXJxAGV0AHEUMHyzdvRXA6CyABeKAJoxBxejJmdkRH
  123. CiABDZALDDEMyuAIZ3AK34cHZIAHKTIfH/Z6udA8CXALo3ACmlAMqIALWVF5dxYcbxAWuEYLB3AD
  124. ejALNgAAnHECPrADAVAA0UFnHCIbBoALs6AFZSYEtyAGd6P+GXugBmszZm+oB5vQVCAgARTSGgmg
  125. IY6SAoSyENUgDY2QZm2QlG0QBw3wFQRAkmw1C7VgZiXACmHQFmRAC7SQWgfAABIgGLSQCz7HWrfA
  126. VBQCJ3RGGAYgAeNxPfthALOQCqkgBHyzI0kjGwyQAkTQKnAxRwNQBJogAxM2HrFhAIa1AgdAAEjn
  127. cAoxC2igBnOQB3uQBVzQBaYQAmPWFjOyAKQGJxAwCy6gMj24AnhwDFh1ALSgg5CCh3RgJRqCGXyW
  128. G3BiAMtjAAfQAGMWB6wQBKhAAxEjIzDSFQ0gAasRAJhJYhBAB3ZwAmuJBmjAQWBxKXREGxCgDgyh
  129. BmPwBnj+gAdtAAZpIAZqMBjHEighAAuoUAJBtgoy4BT0UQyqoBMnUAt+lAtF4EQp8ACsACS0sR8i
  130. dAASkAASIAAkgAaacJ8P4gAu4AoaEAZq4AW+xZNxER1+USPbEh2EUQZVoAIEEAa2cAI3dENMcymK
  131. yRDsYAZwMGhp0AZj4AVlgAejtAJzBCO1QAc0IEJAVgA00FX0sQC1sJ4QYAyjsGt5oAoBIGnkgook
  132. 0IcJQASaoAuGZi1OlAtloAuMYAdKeAK4AgFA0Aq2EAbZE4dNdU0IsAdgAARIaCxeiHPtAgIUgAFA
  133. wBDhgAi8cAZq0Hlt4AWy+Dl/gR6wQAZ2wHsHIAam0FT+tIAKIXkMbfAAEtA6ecBSRVAcr2ElYegC
  134. ZIBJickABaAJVdAqcJIEdqAHKcAIX5AaATAAPpAKUAAEwtAJkDg9YfoATZAHmkACAhByk2EZ+cQA
  135. FAAEgaYQ20ANznAGcnAFcUAGxUoE5mZ4wpGIC7AHspQnuUAHtyACjaJQXQlVS4I4KkIGLlCqNpga
  136. eiBmdDY5FDBtTJIaYYAKGyABuvAKNLCCcuVc6CE/jchc/xEbINACDMACQVCGChEP2vAMkwAGbvAG
  137. ZFAFLUoEr7Ira4EBWoABBsAgyZAL93kCxkCOPNGCKjhKMsJTakMAPCYDaJAHP9AgDfAAbaB+O+oo
  138. JzD+BnsQBkCwlrGgC5wQBKngCuzlV5X3GgmgL4HDKSjDKywgAzQgA6jQEPAgDYiQBmzgBm0gBmKw
  139. ZW4nGJVHArmgB8/ZALUgBCemJKcwoU3SMRMiQOKRArXwMAxgCntQBrUAqvThXl6wqb+CAAxQBaxQ
  140. BDSgC2pQAANgs6j6BbpABK5BN6vxAPBGR/8RAl4IAkLwhy2gAkTSEOvwCGvABmQgi2JQBObjob8G
  141. IceQDLCQAqggBGWgCpB0H63SlSLkhQuwAyRwAi2gB6NKZwSgmHgQB+7mlTsQQcbxOF5gBxQwAHeg
  142. BjIwbbrQCgNgAMKgCwAAhbaBK9fUGgIgGyCwAjL+EFY3wAIqkAO28BDscAaP8AZWsAVt8AZjEAab
  143. wBlwcrJNEAxhUAu4oAsQ4AVBoEE6MjmPGAGRZlZlgAZhAAvIWwCJwxR2AAZfCCk0EATDqSvXJAF2
  144. QAe6kI4ugAzylQwpYBx09I0S8JXWAgESQAAQYAMi3AI2IAMsoGdD6RDgEAWpcAboJHFeAAZ0sCgB
  145. IAAKYG8FoAd6wCj3CyM/eYe76gPc0SRAsAlpIAPNQwJ3qgd3UEYfcwAsEJdQwJYYTK0aQAet0AIA
  146. WgRBoKixsRrEiCF0y7ItkAInsAJo3AIt4AIq4AIp7BDb8AuSEAZmgAdbQAZjkARj4B1dMgCokAf+
  147. MlB5TjErCVAAqgYCEWC0rCC4KaBQDdAETioG4YMAZYypuNkVMqcLwhAYG0wfYdCHM7oCInC4chWm
  148. HBQABCABKaATIsA5KOACKBCMSeIFjOkQ8ZANz8CPYrAFYnAFY1AGdiAW8rMAsvUXvPIXtfQ4FPAA
  149. LqAK3tnBXJEqPpADVdAauXECa/MU08YAaJAKLRAA2CwCdTALAIwCF4KNTSUeCgACKygCEOACSWJQ
  150. nKMCKrADfwiSQSAaEjENvLAEXiAHbuAGYsAFZQBQlJg4xxEVXwEBP0AHdcCtwRGxZeAF8xEdDnCn
  151. caI4s0bMWoBJswagCKAGe+DBTDcAahwx8Kr+IXckHgsIASywAixQFyfQxilAwitgAyXQAjLwA5nn
  152. EEm7BHBQggbLBlpABzB6H14CASQ5AHoABXtwBXVQC0VAMXNkB9OXUiowS6tJJ2/QCqeQAhu8NvCm
  153. B17AM2EqVY1YGfxZGSTAAjoR0yzAAmbcAiSgxi3wAyOQwEFQEe0gBWoQkGAABmJwuW9gLA7goYFC
  154. AvMKAi7QClCAGkFABzLQAEXFHolaN5UHFtF5HAdgAFygCUAAS5BIAYwwhG5RZv5BG7HnGcF4AhSw
  155. E9gc12e8AjcAAxzABIIQBDDwBRahDmYgBmBgB2LwBmVwBWIgd1RyG9cSHQMgAk0gCzQgI23+4Aoy
  156. YC4n0ARDwCIjAymEeId24HeF17t++KGtsye0ERiysQLJVsY7wd5nwgKyswIwUAGQYAiVUANmgBH+
  157. sATQsAQDfQXopAVcFhzOpSFekSRNoAlOkGh50Ab75CsUIFobPBy8toDfiD2rUF+z8hZU8lAo7UQJ
  158. EAAGoAEu0AI4MAIjwAIaMAItsHEjkAI9YAKz0wIcEAqDEAbxkhHKAA2SAAds8AYCLQZeIAZvsTe3
  159. EXQgMJxekAopYAB0oAX2aNHd8p8Q4xZ3cyO3EQFVsAO7QmcaAizDoY5dAgEq8NKIUgIrUAIpIAIr
  160. 0AAmzgO76wI7sANHgATkABLYEA1/MAb+Qb4FVSDkN+QjkvJFwGcHUKAJaBCxlnMAVUAD1zQYDvI5
  161. lAEds0JTERoeGjShDkACLoDGIiDX01ECJWADK+ACtsMCHAAJTEADQPAF45AS07AIZxC1W0C+VVAF
  162. X4BzU4JHMOo5dpAKabCWDa0pLrAKP1DR4zphq7nh2BMral0Z/YLGMvCHpC4CKIACcc0COUADOUAF
  163. L/AHltAHg+AEHEET7QAMUVCLUXsFVaAFbYADnzNPIdACN5SFGacBecsJlxwEedDkBSAYDvDvffIa
  164. CoADb3Ecp6Mr9hECQnADaOwC047mKRDXOMADRPADPEAFHFAJfSAK5jAU7BAGc/AGdEz+BmDABcft
  165. Am5xW+MBJYRMkjerAsToXXSoBySQcWzpV0zzFmsRLnLyHOMkA4iCAzewA7JzAzdgAztA10LgAz2g
  166. AzsgA4MgCtNQFu0ABXXwCFkQw5XqyzeiJKK1hS9SeQ1ABpxAAw0w8YAiAWCQBxiQADKQqF9Jfacj
  167. AF+HHA5wA2cMu6WeAy0gBDtwAz7wAzIQA0cgBVDgAkVQA9bQDnghDksADFhwBlrgBldQBH++X8NR
  168. yHJ1AAqVAGrQCVCgCrUAKAHQAJrwqbqABmjyH9AEKeIhNQtgvSb+PWeMA0Zv6j1ABDrwAn4QCaHA
  169. AVeQ4wIRD2axDc4QCkjwnVcQ2FD++43nfEOzwhoSgAquAAUMhQClWgCzsGm8d1TY8ipsIgI4oMYr
  170. gAMlMAIigAEl8DsvoARDQAVU4AEcXwmSUMuOAQ3RcARpcMdQAAYAcUWMDwcREDhYUPDAgxAHIEDQ
  171. g2oBAxFCGgw4MCBBggEQIhyI8ADBAAciWqwYceJEChAsgJRYgYNEiR5CtPTIweSSIWvx+v0EGlTo
  172. UKJFjQ6FJiUMG1JtxLjBQobGAwcHFCw4APLAggUSVrAqg0pPmwENEizgiDHhAQcDHsRMgaFFihQn
  173. XIigUQIHjhMtaAAJ8+PHlGztfB5FnFjxUERrmpQZI+bKlSRhZChAcJWkgBAPMib+SIGmFQkSbSEU
  174. GBAgYVUFD27cwNECQwocd+uSmGHFCowjfiRVMKLE22LixRWDgUKZjBYtyL3IgNBwgAIBBxmg1Tjd
  175. AISzCx4U6AriBI4VVly44OtDL4oVNmzg0JHiiCFKmB4NN55fv9B0URop+YIL5rwY4goQqjpgJAUM
  176. 2iiBjCAwy60BJlzghBUurIu8FliwwYoVWGChhx54aKEGPyo5JJv9VmTxG2J4QeIMMsqoYrI3GnJA
  177. gayoS0gBBxyMEKsEILhwhRLEwyGF81qwIQQWggtCBRZI2MCPZ+SRh0Ut9ePmGUmUwGKLN6rQYosr
  178. QshRgQEQQAArks5q4IEEGLD+0IUWLFyBhJjQS2GHFVKowYgllHhhAxWY2TLR/Z4JRYpSspjCiyrE
  179. 8IKGAyRgSwCuHAhgABBGQmEBF1hYwQUUNBABgxJgoMBCHdCDwY9MLAllE3YUxTU/eaZZQg48zLjC
  180. Ci+08GIHg1ZbK4QICiJSJZUgIOEE92zQgbwedGjBAkIqqWScXL81Dh5E6OjCCzdq9MILMVbg6iPP
  181. 3IIAhBXwBEHeeWfIYS8ZdMihCys0OCKSULIEt2DiwiDjiyqwSDfdK1iIYIGDWiNBJiPnxeG9HVpw
  182. QQcdYOBgiSFwUCEGYgxGmTh2pOhlCjPIoNSLIrw4YQEF6s3zQhBKgOmGC3f+uLaIDf445JMjiLgm
  183. ZaUXE8cZZ7B4ow11JZUBhBBWOGkF8bCuDT0fhCCChyopocSZYZZGWzFuQplEDDxi9oIIO7GOKSYa
  184. dsBBhh9uEGIHK54wwpBLnCE4bcONmgaUN8SA2wsf5j3B3hVu2EEGF3JIQoYhbsACCWrQOTz0o3wJ
  185. gxEynOCCC+SquHODF0Zg4YYhgOjgD1A8gAIKZETnvSh44KkD2CHIaOILKB6PVjwehKCCBkEqiUSR
  186. bnqn3qgv4Ijiii/irovnk3ZowgQjADFkmurPL+qVX5ZYwose/tQgBRiAIGKHGJD4pHD09/+pnF5e
  187. AVAPyGMBJjhCCTGwQiNJ2sE/BgalGsBYwhf8NIJAgOITSGCEOhq4QaD4Yg1R2NsLFDGJQCyQgyfs
  188. Ryq+QIMw1EARJkQhCpHhBVSsI4Y3xGEOdbhDHholIAA7
  189. }
  190. #####################################################################################
  191. # Tooltip
  192. #####################################################################################
  193. proc setTooltip {widget text} {
  194. if { $text != "" } {
  195. bind $widget <Any-Enter> [list .helptext configure -text "$text"]
  196. # bind $widget <Any-Enter> [list after 500 [list showTooltip %W $text]]
  197. # bind $widget <Any-Leave> [list after 500 [list destroy %W.tooltip]]
  198. # bind $widget <Any-KeyPress> [list after 500 [list destroy %W.tooltip]]
  199. # bind $widget <Any-Button> [list after 500 [list destroy %W.tooltip]]
  200. }
  201. }
  202. proc showTooltip {widget text} {
  203. global tcl_platform
  204. if { [string match $widget* [winfo containing [winfo pointerx .] [winfo pointery .]] ] == 0 } {
  205. return
  206. }
  207. catch { destroy $widget.tooltip }
  208. set scrh [winfo screenheight $widget] ; # 1) flashing window fix
  209. set scrw [winfo screenwidth $widget] ; # 1) flashing window fix
  210. set tooltip [toplevel $widget.tooltip -bd 1 -bg black]
  211. wm geometry $tooltip +$scrh+$scrw ; # 1) flashing window fix
  212. wm overrideredirect $tooltip 1
  213. if {$tcl_platform(platform) == {windows}} { ; # 3) wm attributes...
  214. wm attributes $tooltip -topmost 1 ; # 3) assumes...
  215. } ; # 3) Windows
  216. pack [label $tooltip.label -bg lightyellow -fg black -text $text -justify left]
  217. set width [winfo reqwidth $tooltip.label]
  218. set height [winfo reqheight $tooltip.label]
  219. set pointer_below_midline [expr [winfo pointery .] > [expr [winfo screenheight .] / 2.0]] ; # b.) Is the pointer in the bottom half of the screen?
  220. set positionX [expr [winfo pointerx .] - round($width / 2.0)] ; # c.) Tooltip is centred horizontally on pointer.
  221. set positionY [expr [winfo pointery .] + 35 * ($pointer_below_midline * -2 + 1) - round($height / 2.0)] ; # b.) Tooltip is displayed above or below depending on pointer Y position.
  222. if {[expr $positionX + $width] > [winfo screenwidth .]} {
  223. set positionX [expr [winfo screenwidth .] - $width]
  224. } elseif {$positionX < 0} {
  225. set positionX 0
  226. }
  227. wm geometry $tooltip [join "$width x $height + $positionX + $positionY" {}]
  228. raise $tooltip
  229. bind $widget.tooltip <Any-Enter> {destroy %W}
  230. bind $widget.tooltip <Any-Leave> {destroy %W}
  231. }
  232. #####################################################################################
  233. # Menu
  234. #####################################################################################
  235. menu .menu -tearoff 0
  236. menu .menu.file -tearoff 0
  237. .menu add cascade -label "File" -menu .menu.file -underline 0
  238. .menu.file add command -label "Connect" -command {
  239. connect_serial
  240. }
  241. .menu.file add command -label "Close" -command {
  242. close_serial
  243. }
  244. .menu.file add command -label "Open file..." -command {
  245. load_values_from_file
  246. }
  247. .menu.file add command -label "Save file..." -command {
  248. save_values2file
  249. }
  250. .menu.file add separator
  251. .menu.file add command -label "Exit" -command {
  252. exit 0
  253. }
  254. menu .menu.options -tearoff 0
  255. .menu add cascade -label "Options" -menu .menu.options -underline 0
  256. .menu.options add command -label "set Defaults" -command {
  257. set_defaults
  258. }
  259. .menu.options add command -label "Load from Board" -command {
  260. send_par
  261. }
  262. .menu.options add command -label "Save to Board" -command {
  263. save_values
  264. }
  265. .menu.options add command -label "Load from Flash" -command {
  266. load_from_flash
  267. }
  268. .menu.options add command -label "Save to Flash" -command {
  269. save_to_flash
  270. }
  271. .menu.options add command -label "Gyro-Cal" -command {
  272. gyro_cal
  273. }
  274. if {$HEXDATA != ""} {
  275. menu .menu.firmware -tearoff 0
  276. .menu add cascade -label "Firmware" -menu .menu.firmware -underline 0
  277. .menu.firmware add command -label "Upload" -command {
  278. close_serial
  279. set device [.device.spin get]
  280. set ArduinoSerial [ArduinoSerial_Init [.device.spin get] 57600]
  281. ArduinoReset
  282. ArduinoSerial_SendCMD $defs(STK_GET_SIGN_ON)
  283. if {$ArduinoTimeout != 0} {
  284. .bottom.info configure -text "ERROR: upload firmware"
  285. .bottom.info configure -background red
  286. update
  287. after 1000
  288. } else {
  289. .bottom.info configure -text "start uploading firmware"
  290. ArduinoSendData "0x0000" $HEXDATA
  291. ArduinoReset
  292. }
  293. after 500
  294. connect_serial
  295. }
  296. }
  297. menu .menu.help -tearoff 0
  298. .menu add cascade -label "Help" -menu .menu.help -underline 0
  299. .menu.help add command -label "Tuning" -command {
  300. show_help_tuning
  301. }
  302. .menu.help add separator
  303. .menu.help add command -label "Homepage" -command {
  304. launchBrowser "http://brushlessgimbal.de/"
  305. }
  306. .menu.help add command -label "Documentation" -command {
  307. launchBrowser "http://brushlessgimbal.de/brugi-v1/software/"
  308. }
  309. .menu.help add separator
  310. .menu.help add command -label "About..." -command {
  311. show_help_about
  312. }
  313. . configure -menu .menu
  314. #####################################################################################
  315. # serialports
  316. #####################################################################################
  317. if {[string match "*Linux*" $tcl_platform(os)]} {
  318. set comports ""
  319. set device ""
  320. catch {
  321. set comports "[glob /dev/ttyUSB*] [glob /dev/ttyACM*]"
  322. set device "[lindex $comports end]"
  323. }
  324. } elseif {[string match "*Windows*" $tcl_platform(os)]} {
  325. set comports {"com1:" "com2:" "com3:" "com4:" "com5:" "com6:" "com7:" "com8:" "com9:" "com10:" "com11:" "com12:" "com13:" "com14:" "com15:"}
  326. catch {
  327. set serial_base "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM"
  328. set values [registry values $serial_base]
  329. set res {}
  330. # foreach valueName $values {
  331. # set PortName "[registry get $serial_base $valueName]"
  332. # lappend res "$PortName"
  333. # }
  334. foreach valueName $values {
  335. set PortName "//./[registry get $serial_base $valueName]"
  336. lappend res "$PortName"
  337. }
  338. set comports $res
  339. }
  340. set device "[lindex $comports end]"
  341. } elseif {[string match "*Darwin*" $tcl_platform(os)] || [string match "*MacOS*" $tcl_platform(os)]} {
  342. set comports ""
  343. set device ""
  344. catch {
  345. set comports [glob /dev/cu.usbserial-*]
  346. set device "[lindex $comports end]"
  347. }
  348. }
  349. #####################################################################################
  350. # Global variables
  351. #####################################################################################
  352. set Serial 0
  353. set LastValX 0
  354. set LastValY 0
  355. set chart 0
  356. set params "gyroPitchKp gyroPitchKi gyroPitchKd gyroRollKp gyroRollKi gyroRollKd accTimeConstant mpuLPF angleOffsetPitch angleOffsetRoll dirMotorPitch dirMotorRoll motorNumberPitch motorNumberRoll maxPWMmotorPitch maxPWMmotorRoll minRCPitch maxRCPitch minRCRoll maxRCRoll rcGain rcLPF rcModePPM rcChannelPitch rcChannelRoll rcMid rcAbsolute accOutput enableGyro enableACC axisReverseZ axisSwapXY"
  357. foreach var $params {
  358. if {$var == "vers"} {
  359. } elseif {! [string match "*,*" $var]} {
  360. set par($var) 0
  361. set par($var,scale) 1
  362. set par($var,offset) 0
  363. }
  364. }
  365. set par(gyroPitchKp,scale) 1000.0
  366. set par(gyroPitchKi,scale) 1000.0
  367. set par(gyroPitchKd,scale) 1000.0
  368. set par(gyroRollKp,scale) 1000.0
  369. set par(gyroRollKi,scale) 1000.0
  370. set par(gyroRollKd,scale) 1000.0
  371. set par(angleOffsetPitch,scale) 100.0
  372. set par(angleOffsetRoll,scale) 100.0
  373. set par(rcLPF,scale) 10.0
  374. set par(maxPWMmotorPitch,scale) 2.5
  375. set par(maxPWMmotorRoll,scale) 2.5
  376. set par(rcChannelPitch,offset) 1
  377. set par(rcChannelRoll,offset) 1
  378. set par(motorNumberPitch,offset) 1
  379. set par(motorNumberRoll,offset) 1
  380. set CHART_SCALE 0.5
  381. set buffer ""
  382. set count 0
  383. set chart_count 0
  384. #####################################################################################
  385. # Serial-Functions
  386. #####################################################################################
  387. proc Serial_Init {ComPort ComRate} {
  388. global Serial
  389. catch {close $Serial}
  390. catch {fileevent $Serial readable ""}
  391. set iChannel 0
  392. if {[catch {
  393. set iChannel [open $ComPort w+]
  394. fconfigure $iChannel -mode $ComRate,n,8,1 -ttycontrol {RTS 1 DTR 0} -blocking FALSE
  395. fileevent $iChannel readable [list rd_chid $iChannel]
  396. .bottom.version configure -text "Serial-Ok: $ComPort @ $ComRate"
  397. .bottom.info configure -text "Serial-Ok: $ComPort @ $ComRate"
  398. .device.connect configure -text "Reconnect"
  399. }]} {
  400. .bottom.version configure -text "Serial-Error: $ComPort @ $ComRate"
  401. .bottom.version configure -background red
  402. .bottom.info configure -text "Serial-Error: $ComPort @ $ComRate"
  403. .device.connect configure -text "Connect"
  404. return 0
  405. }
  406. return $iChannel
  407. }
  408. proc close_serial {} {
  409. global Serial
  410. catch {close $Serial}
  411. .device.connect configure -text "Connect"
  412. }
  413. #####################################################################################
  414. # CLI-Functions
  415. #####################################################################################
  416. proc connect_serial {} {
  417. global Serial
  418. global count
  419. global device
  420. global buffer
  421. # .bottom.info configure -background yellow
  422. set device [.device.spin get]
  423. set Serial [Serial_Init $device 115200]
  424. set count 0
  425. if {$Serial == 0} {
  426. .bottom.info configure -background red
  427. .bottom.info configure -text "not connected"
  428. return
  429. } else {
  430. .bottom.info configure -background green
  431. .bottom.info configure -text "connected"
  432. }
  433. after 6000 send_par
  434. }
  435. proc draw_chart {} {
  436. global Serial
  437. global chart
  438. if {$Serial == 0} {
  439. .bottom.info configure -background red
  440. .bottom.info configure -text "not connected"
  441. return
  442. }
  443. if {$chart == 1} {
  444. set chart 0
  445. .bottom.info configure -text "SEND: oac 0"
  446. puts -nonewline $Serial "oac 0\n"
  447. flush $Serial
  448. .note.general.chart.fr1.button configure -text "Start"
  449. } else {
  450. set chart 1
  451. .bottom.info configure -text "SEND: oac 1"
  452. puts -nonewline $Serial "oac 1\n"
  453. flush $Serial
  454. .note.general.chart.fr1.button configure -text "Stop"
  455. }
  456. }
  457. proc send_parvar {n1 n2 op} {
  458. global Serial
  459. global par
  460. if {$Serial == 0} {
  461. .bottom.info configure -background red
  462. .bottom.info configure -text "not connected"
  463. return
  464. }
  465. if {$n2 == "vers"} {
  466. } elseif {$n2 == "dirMotorPitch" || $n2 == "dirMotorRoll"} {
  467. if {$par($n2) == 1} {
  468. .bottom.info configure -text "SEND: par $n2 -1"
  469. puts -nonewline $Serial "par $n2 -1\n"
  470. } else {
  471. .bottom.info configure -text "SEND: par $n2 1"
  472. puts -nonewline $Serial "par $n2 1\n"
  473. }
  474. } else {
  475. .bottom.info configure -text "SEND: par $n2 [expr $par($n2) * $par($n2,scale) - $par($n2,offset)]"
  476. puts -nonewline $Serial "par $n2 [expr $par($n2) * $par($n2,scale) - $par($n2,offset)]\n"
  477. }
  478. flush $Serial
  479. after 20
  480. }
  481. proc send_par {} {
  482. global Serial
  483. global count
  484. global device
  485. global buffer
  486. set count 0
  487. set buffer ""
  488. if {$Serial == 0} {
  489. .bottom.info configure -background red
  490. .bottom.info configure -text "not connected"
  491. return
  492. }
  493. .bottom.info configure -text "PAR: reading values..."
  494. puts -nonewline $Serial "par\n"
  495. flush $Serial
  496. }
  497. proc save_values {} {
  498. global Serial
  499. global count
  500. global device
  501. global par
  502. .bottom.info configure -text "saving values"
  503. .bottom.info configure -background yellow
  504. update
  505. if {$Serial == 0} {
  506. .bottom.info configure -background red
  507. .bottom.info configure -text "not connected"
  508. return
  509. }
  510. foreach var [array names par] {
  511. if {$var == "vers"} {
  512. } elseif {! [string match "*,*" $var]} {
  513. send_parvar "par" $var "w"
  514. after 20
  515. }
  516. }
  517. .bottom.info configure -text "saving values done"
  518. .bottom.info configure -background green
  519. }
  520. proc load_values_from_file {} {
  521. global Serial
  522. set types {
  523. {"Text files" {.txt} }
  524. {"Text files" {} TEXT}
  525. {"All files" *}
  526. }
  527. global selected_type
  528. if {![info exists selected_type]} {
  529. set selected_type "Tcl Scripts"
  530. }
  531. set file [tk_getOpenFile -filetypes $types -parent . -typevariable selected_type]
  532. if {$file != ""} {
  533. set fp [open $file r]
  534. if {$fp > 0} {
  535. set file_data [read $fp]
  536. close $fp
  537. foreach line "[split $file_data "\n"]" {
  538. if {$line != ""} {
  539. puts $Serial "$line"
  540. flush $Serial
  541. after 20
  542. }
  543. }
  544. .bottom.info configure -text "load: done"
  545. update
  546. connect_serial
  547. } else {
  548. .bottom.info configure -text "load: error, reading file: $file"
  549. update
  550. }
  551. }
  552. after 200 send_par
  553. }
  554. proc save_values2file {} {
  555. global Serial
  556. global device
  557. global par
  558. set types {
  559. {"Text files" {.txt} }
  560. {"Text files" {} TEXT}
  561. {"All files" *}
  562. }
  563. set file [tk_getSaveFile -filetypes $types -parent . -initialfile blg-gimbal -defaultextension .txt]
  564. if {$file != ""} {
  565. set fp [open $file w]
  566. foreach var [array names par] {
  567. if {$var == "vers"} {
  568. } elseif {! [string match "*,*" $var]} {
  569. if {$var == "dirMotorPitch" || $var == "dirMotorRoll"} {
  570. if {$par($var) == 1} {
  571. puts -nonewline $fp "par $var -1\n"
  572. } else {
  573. puts -nonewline $fp "par $var 1\n"
  574. }
  575. } else {
  576. puts -nonewline $fp "par $var [expr $par($var) * $par($var,scale) - $par($var,offset)]\n"
  577. }
  578. }
  579. }
  580. close $fp
  581. }
  582. }
  583. proc gyro_cal {} {
  584. global Serial
  585. global count
  586. global device
  587. set count 0
  588. if {$Serial == 0} {
  589. .bottom.info configure -background red
  590. .bottom.info configure -text "not connected"
  591. return
  592. }
  593. .bottom.info configure -background red
  594. .bottom.info configure -text "gyro recalibration"
  595. update
  596. puts -nonewline $Serial "GC\n"
  597. flush $Serial
  598. }
  599. proc save_to_flash {} {
  600. global Serial
  601. global count
  602. global device
  603. set count 0
  604. if {$Serial == 0} {
  605. .bottom.info configure -background red
  606. .bottom.info configure -text "not connected"
  607. return
  608. }
  609. puts -nonewline $Serial "WE\n"
  610. flush $Serial
  611. }
  612. proc load_from_flash {} {
  613. global Serial
  614. global count
  615. global device
  616. set count 0
  617. .bottom.info configure -text "loading from flash"
  618. update
  619. if {$Serial == 0} {
  620. .bottom.info configure -background red
  621. .bottom.info configure -text "not connected"
  622. return
  623. }
  624. puts -nonewline $Serial "RE\n"
  625. flush $Serial
  626. after 200 send_par
  627. }
  628. proc set_defaults {} {
  629. global Serial
  630. global count
  631. global device
  632. set count 0
  633. .bottom.info configure -text "setting defaults"
  634. update
  635. if {$Serial == 0} {
  636. .bottom.info configure -background red
  637. .bottom.info configure -text "not connected"
  638. return
  639. }
  640. puts -nonewline $Serial "SD\n"
  641. flush $Serial
  642. after 200 send_par
  643. }
  644. #####################################################################################
  645. # Serial-Calback
  646. #####################################################################################
  647. proc rd_chid {chid} {
  648. global buffer
  649. global count
  650. global chart_count
  651. global VERSION
  652. global par
  653. if {$chid == 0} {
  654. return
  655. }
  656. # catch {
  657. set ch [read $chid 1]
  658. if {$ch == "\r"} {
  659. } elseif {$ch == "\n"} {
  660. if {1 == 1} {
  661. .bottom.info configure -text "INFO: $buffer"
  662. # update
  663. set var [lindex $buffer 0]
  664. set val [lindex $buffer 1]
  665. if {$var == "vers"} {
  666. set par(vers) "$val"
  667. .bottom.version configure -text "Firmware-Version: $par(vers)"
  668. .bottom.version configure -background lightgray
  669. } elseif {$var == "dirMotorPitch" || $var == "dirMotorRoll"} {
  670. if {$val == -1} {
  671. set par($var) 1
  672. } else {
  673. set par($var) 0
  674. }
  675. } elseif {[info exists par($var,scale)]} {
  676. set par($var) [expr ($val + $par($var,offset)) / $par($var,scale)]
  677. } elseif {[string match "* ACC *" $buffer]} {
  678. set chart 1
  679. .bottom.info configure -text "OAC: $buffer"
  680. global LastValX
  681. global LastValY
  682. global CHART_SCALE
  683. set ValX [expr [lindex $buffer 0] / 1000.0]
  684. set TEST [lindex $buffer 1]
  685. set ValY [expr [lindex $buffer 2] / 1000.0]
  686. if {($TEST == "ACC" || $TEST == "DMP") && [string is double -strict $ValX] && [string is double -strict $ValY]} {
  687. incr chart_count 1
  688. if {$chart_count >= 450} {
  689. set chart_count 0
  690. }
  691. .note.general.chart.chart1 delete "line_$chart_count"
  692. .note.general.chart.chart1 create line $chart_count [expr 100 - ($LastValX / 2 * $CHART_SCALE + 50)] [expr $chart_count + 1] [expr 100 - ($ValX * $CHART_SCALE / 2 + 50)] -fill orange -tags "line_$chart_count"
  693. .note.general.chart.chart1 create line $chart_count [expr 100 - ($LastValY / 2 * $CHART_SCALE + 50)] [expr $chart_count + 1] [expr 100 - ($ValY * $CHART_SCALE / 2 + 50)] -fill green -tags "line_$chart_count"
  694. .note.general.chart.chart1 delete "pos"
  695. .note.general.chart.chart1 create line [expr $chart_count + 1] 0 [expr $chart_count + 1] 100 -fill yellow -tags "pos"
  696. .note.general.chart.chart1 create text 5 10 -text "Pitch: $ValX" -anchor w -fill orange -tags "pos"
  697. .note.general.chart.chart1 create text 5 25 -text "Roll: $ValY" -anchor w -fill green -tags "pos"
  698. .note.general.chart.chart1 create text 5 90 -text "Scale: $CHART_SCALE" -anchor w -fill green -tags "pos"
  699. set LastValX $ValX
  700. set LastValY $ValY
  701. }
  702. } elseif {[string match "*recalibration: done*" $buffer]} {
  703. #tk_messageBox -icon info -message "Gyro-Recalibration done" -type ok -parent .
  704. .bottom.info configure -text "Gyro-Recalibration done"
  705. .bottom.info configure -background green
  706. update
  707. } elseif {[string match "* ddddd *" $buffer]} {
  708. .bottom.info configure -text "READY!"
  709. .bottom.info configure -background green
  710. } else {
  711. }
  712. }
  713. set buffer ""
  714. } else {
  715. append buffer $ch
  716. }
  717. # }
  718. }
  719. #####################################################################################
  720. # Arduino-Flashloader
  721. #####################################################################################
  722. set defs(STK_OK) "0x10"
  723. set defs(STK_INSYNC) "0x14"
  724. set defs(STK_GET_SIGN_ON) "0x30"
  725. set defs(STK_LOAD_ADDRESS) "0x55"
  726. set defs(STK_READ_PAGE) "0x74"
  727. set defs(STK_WRITE_PAGE) "0x64"
  728. set defs(CRC_EOP) "0x20"
  729. set ArduinoTimeout 0
  730. proc ArduinoSerial_Init {ComPort ComRate} {
  731. global ArduinoSerial
  732. catch {close $ArduinoSerial}
  733. set iChannel 0
  734. if {[catch {
  735. set iChannel [open $ComPort w+]
  736. fconfigure $iChannel -mode $ComRate,n,8,2 -translation binary -ttycontrol {RTS 1 DTR 0} -blocking FALSE
  737. .bottom.info configure -text "ArduinoSerial-OK: $ComPort @ $ComRate"
  738. update
  739. }]} {
  740. .bottom.info configure -text "ArduinoSerial-Error: $ComPort @ $ComRate"
  741. update
  742. }
  743. return $iChannel
  744. }
  745. proc ArduinoWait_reply {} {
  746. global ArduinoSerial
  747. global ArduinoTimeout
  748. global defs
  749. set num 0
  750. set num2 0
  751. set ch [read $ArduinoSerial 1]
  752. binary scan $ch c num
  753. set counter 0
  754. while {$num == 0 && $counter < 1000} {
  755. set ch [read $ArduinoSerial 1]
  756. binary scan $ch c num
  757. after 10
  758. incr counter
  759. }
  760. if {$counter >= 1000} {
  761. .bottom.info configure -text "#### timeout ####"
  762. update
  763. set ArduinoTimeout 1
  764. after 1000
  765. return
  766. }
  767. binary scan $ch c num
  768. set ch2 [read $ArduinoSerial 1]
  769. binary scan $ch2 c num2
  770. set counter 0
  771. while {$num2 == 0 && $counter < 1000} {
  772. set ch2 [read $ArduinoSerial 1]
  773. binary scan $ch2 c num2
  774. after 10
  775. incr counter
  776. }
  777. if {$counter >= 1000} {
  778. .bottom.info configure -text "#### timeout ####"
  779. update
  780. set ArduinoTimeout 1
  781. after 1000
  782. return
  783. }
  784. binary scan $ch2 c num2
  785. set ret "[format 0x%02x $num]"
  786. set ret2 "[format 0x%02x $num2]"
  787. if {$ret == $defs(STK_INSYNC) && $ret2 == $defs(STK_OK)} {
  788. # puts " STK_INSYNC"
  789. } else {
  790. puts "Error: "
  791. puts " < $ret"
  792. puts " < $ret2"
  793. .bottom.info configure -text "Flash-Error"
  794. update
  795. after 1000
  796. # return
  797. }
  798. }
  799. proc ArduinoSerial_SendCMD {CMD} {
  800. global ArduinoSerial
  801. global defs
  802. puts -nonewline $ArduinoSerial "[binary format c $CMD]"
  803. flush $ArduinoSerial
  804. puts -nonewline $ArduinoSerial "[binary format c $defs(CRC_EOP)]"
  805. flush $ArduinoSerial
  806. ArduinoWait_reply
  807. }
  808. proc ArduinoReset {} {
  809. global ArduinoSerial
  810. fconfigure $ArduinoSerial -ttycontrol {RTS 0}
  811. flush $ArduinoSerial
  812. after 200
  813. fconfigure $ArduinoSerial -ttycontrol {RTS 1}
  814. flush $ArduinoSerial
  815. after 200
  816. }
  817. proc ArduinoSendWORD {WORD} {
  818. global ArduinoSerial
  819. global defs
  820. set WORD [expr $WORD / 2]
  821. set WORD_BYTE2 "0x[string range [format %04x $WORD] 2 3]"
  822. set WORD_BYTE1 "0x[string range [format %04x $WORD] 0 1]"
  823. puts -nonewline $ArduinoSerial "[binary format c $WORD_BYTE2]"
  824. flush $ArduinoSerial
  825. puts -nonewline $ArduinoSerial "[binary format c $WORD_BYTE1]"
  826. flush $ArduinoSerial
  827. }
  828. proc ArduinoSetAddr {ADDR} {
  829. global ArduinoSerial
  830. global defs
  831. puts -nonewline $ArduinoSerial "[binary format c $defs(STK_LOAD_ADDRESS)]"
  832. flush $ArduinoSerial
  833. ArduinoSendWORD "$ADDR"
  834. puts -nonewline $ArduinoSerial "[binary format c $defs(CRC_EOP)]"
  835. flush $ArduinoSerial
  836. ArduinoWait_reply
  837. }
  838. proc ArduinoSendData {START_ADDR file_data} {
  839. global ArduinoSerial
  840. global defs
  841. set BUFFER ""
  842. set COUNT 0
  843. if {$file_data != ""} {
  844. set MAX_ADDR [expr [llength $file_data]]
  845. foreach BYTE $file_data {
  846. lappend BUFFER "$BYTE"
  847. if {$COUNT == 127} {
  848. .bottom.info configure -text "write: [format 0x%02x $START_ADDR] ([expr [format 0x%x $START_ADDR] * 100 / [format 0x%x $MAX_ADDR]]%)"
  849. update
  850. ArduinoSetAddr "[format 0x%x $START_ADDR]"
  851. puts -nonewline $ArduinoSerial "[binary format c $defs(STK_WRITE_PAGE)]"
  852. flush $ArduinoSerial
  853. puts -nonewline $ArduinoSerial "[binary format c "0x0"]"
  854. flush $ArduinoSerial
  855. puts -nonewline $ArduinoSerial "[binary format c "0x80"]"
  856. flush $ArduinoSerial
  857. puts -nonewline $ArduinoSerial "F"
  858. flush $ArduinoSerial
  859. foreach SEND_BYTE $BUFFER {
  860. puts -nonewline $ArduinoSerial "[binary format c $SEND_BYTE]"
  861. flush $ArduinoSerial
  862. }
  863. puts -nonewline $ArduinoSerial "[binary format c $defs(CRC_EOP)]"
  864. flush $ArduinoSerial
  865. ArduinoWait_reply
  866. incr START_ADDR 128
  867. set BUFFER ""
  868. set COUNT 0
  869. } else {
  870. incr COUNT
  871. }
  872. }
  873. set NUM 0
  874. while {$NUM < [expr 128 - $COUNT]} {
  875. lappend BUFFER "0xFF"
  876. incr NUM
  877. }
  878. .bottom.info configure -text "write: [format 0x%02x $START_ADDR] ([expr [format 0x%x $START_ADDR] * 100 / [format 0x%x $MAX_ADDR]]%)"
  879. update
  880. ArduinoSetAddr "[format 0x%x $START_ADDR]"
  881. puts -nonewline $ArduinoSerial "[binary format c $defs(STK_WRITE_PAGE)]"
  882. flush $ArduinoSerial
  883. puts -nonewline $ArduinoSerial "[binary format c "0x0"]"
  884. flush $ArduinoSerial
  885. puts -nonewline $ArduinoSerial "[binary format c "0x80"]"
  886. flush $ArduinoSerial
  887. puts -nonewline $ArduinoSerial "F"
  888. flush $ArduinoSerial
  889. foreach SEND_BYTE $BUFFER {
  890. puts -nonewline $ArduinoSerial "[binary format c $SEND_BYTE]"
  891. flush $ArduinoSerial
  892. }
  893. puts -nonewline $ArduinoSerial "[binary format c $defs(CRC_EOP)]"
  894. flush $ArduinoSerial
  895. ArduinoWait_reply
  896. .bottom.info configure -text "write: done (100%)"
  897. update
  898. } else {
  899. .bottom.info configure -text "error no data found"
  900. update
  901. after 1000
  902. }
  903. }
  904. proc ArduinoConvertData {file_data} {
  905. global ArduinoSerial
  906. global defs
  907. set BUFFER ""
  908. if {$file_data != ""} {
  909. foreach BYTE [split $file_data ""] {
  910. binary scan $BYTE c num
  911. if {$num < 0} {
  912. set num [expr $num + 256]
  913. }
  914. lappend BUFFER "[format 0x%x $num]"
  915. }
  916. return $BUFFER
  917. } else {
  918. .bottom.info configure -text "error no data found"
  919. update
  920. after 1000
  921. }
  922. }
  923. proc ArduinoSendBIN {START_ADDR BINFILE} {
  924. global ArduinoSerial
  925. set binfile [open $BINFILE r]
  926. fconfigure $binfile -translation binary
  927. set file_data [read $binfile]
  928. close $binfile
  929. if {$file_data != ""} {
  930. ArduinoSendData $START_ADDR [ArduinoConvertData $file_data]
  931. } else {
  932. .bottom.info configure -text "error loading BIN-File"
  933. update
  934. after 1000
  935. }
  936. }
  937. proc ArduinoExportBIN {BINFILE} {
  938. set binfile [open $BINFILE r]
  939. fconfigure $binfile -translation binary
  940. set file_data [read $binfile]
  941. close $binfile
  942. if {$file_data != ""} {
  943. return "[ArduinoConvertData $file_data]"
  944. } else {
  945. .bottom.info configure -text "error loading BIN-File"
  946. update
  947. after 1000
  948. }
  949. }
  950. #####################################################################################
  951. # GUI-Helper-Functions
  952. #####################################################################################
  953. set tline 0
  954. proc show_textline {wid line} {
  955. global tline
  956. label $wid.tline_$tline -anchor nw -text "$line"
  957. pack $wid.tline_$tline -side top -expand yes -fill x
  958. incr tline
  959. }
  960. proc motorNumberPitch_check {n1 n2 op} {
  961. global par
  962. catch {
  963. if {$par(motorNumberPitch) == 1} {
  964. set par(motorNumberRoll) 2
  965. } else {
  966. set par(motorNumberRoll) 1
  967. }
  968. }
  969. }
  970. trace variable par(motorNumberPitch) w motorNumberPitch_check
  971. proc motorNumberRoll_check {n1 n2 op} {
  972. global par
  973. catch {
  974. if {$par(motorNumberRoll) == 1} {
  975. set par(motorNumberPitch) 2
  976. } else {
  977. set par(motorNumberPitch) 1
  978. }
  979. }
  980. }
  981. trace variable par(motorNumberRoll) w motorNumberRoll_check
  982. proc show_help {helptext} {
  983. tk_messageBox -icon info -message "$helptext" -type ok -parent .
  984. }
  985. proc gui_slider {wid variable min max step title tooltiptext helptext} {
  986. global par
  987. label $wid
  988. pack $wid -side top -expand yes -fill x
  989. setTooltip $wid "$tooltiptext"
  990. label $wid.label -text "$title" -width 14 -anchor w
  991. pack $wid.label -side left -expand no -fill x
  992. frame $wid.frame
  993. pack $wid.frame -side left -expand yes -fill x
  994. eval button $wid.frame.help -text \"?\" -width 1 -command \{show_help \"$helptext\"\}
  995. pack $wid.frame.help -side right -expand no -fill none
  996. spinbox $wid.frame.spin -from $min -to $max -increment $step -width 10 -textvariable par($variable) -width 4
  997. pack $wid.frame.spin -side right -expand yes -fill x
  998. scale $wid.frame.scale -orient horizontal -from $min -to $max -showvalue 0 -resolution $step -variable par($variable)
  999. pack $wid.frame.scale -side right -expand yes -fill x
  1000. }
  1001. proc gui_spin {wid variable min max step title tooltiptext helptext} {
  1002. global par
  1003. frame $wid
  1004. pack $wid -side top -expand yes -fill x
  1005. setTooltip $wid "$tooltiptext"
  1006. label $wid.label -text "$title" -width 14 -anchor w
  1007. pack $wid.label -side left -expand no -fill x
  1008. frame $wid.frame
  1009. pack $wid.frame -side left -expand yes -fill x
  1010. eval button $wid.frame.help -text \"?\" -width 1 -command \{show_help \"$helptext\"\}
  1011. pack $wid.frame.help -side right -expand no -fill none
  1012. set diff [expr $max - $min]
  1013. if {$diff <= 8} {
  1014. set options ""
  1015. set num $min
  1016. while {$num <= $max} {
  1017. set options "$options $num"
  1018. incr num
  1019. }
  1020. ttk::combobox $wid.frame.spin -textvariable par($variable) -state readonly -values $options
  1021. } else {
  1022. spinbox $wid.frame.spin -from $min -to $max -increment $step -width 10 -textvariable par($variable) -width 4
  1023. }
  1024. pack $wid.frame.spin -side right -expand yes -fill x
  1025. }
  1026. proc gui_check {wid variable title title2 tooltiptext helptext} {
  1027. global par
  1028. frame $wid
  1029. pack $wid -side top -expand yes -fill x
  1030. setTooltip $wid "$tooltiptext"
  1031. label $wid.label -text "$title" -width 14 -anchor w
  1032. pack $wid.label -side left -expand no -fill x
  1033. frame $wid.frame
  1034. pack $wid.frame -side left -expand yes -fill x
  1035. checkbutton $wid.frame.check -text "$title2" -variable par($variable) -relief flat -anchor w
  1036. pack $wid.frame.check -side left -expand yes -fill x
  1037. eval button $wid.frame.help -text \"?\" -width 1 -command \{show_help \"$helptext\"\}
  1038. pack $wid.frame.help -side left -expand no -fill none
  1039. }
  1040. proc gui_radio {wid variable options title tooltiptext helptext} {
  1041. global par
  1042. frame $wid
  1043. pack $wid -side top -expand yes -fill x
  1044. setTooltip $wid "$tooltiptext"
  1045. label $wid.label -text "$title" -width 14 -anchor w
  1046. pack $wid.label -side left -expand no -fill x
  1047. frame $wid.frame
  1048. pack $wid.frame -side left -expand yes -fill x
  1049. foreach option $options {
  1050. set option_title [lindex $option 0]
  1051. set option_value [lindex $option 1]
  1052. radiobutton $wid.frame.check_$option -text "$option_title" -value $option_value -variable par($variable) -relief flat
  1053. pack $wid.frame.check_$option -side left -expand yes -fill x
  1054. }
  1055. eval button $wid.frame.help -text \"?\" -width 1 -command \{show_help \"$helptext\"\}
  1056. pack $wid.frame.help -side left -expand no -fill none
  1057. }
  1058. proc gui_button {wid title tooltiptext command} {
  1059. eval button $wid -text \"$title\" -width 14 -command $command
  1060. pack $wid -side left -expand yes -fill x
  1061. setTooltip $wid "$tooltiptext"
  1062. }
  1063. proc disable_all {path} {
  1064. catch {$path configure -state disabled}
  1065. foreach child [winfo children $path] {
  1066. disable_all $child
  1067. }
  1068. }
  1069. proc enable_all {path} {
  1070. catch {$path configure -state normal}
  1071. foreach child [winfo children $path] {
  1072. enable_all $child
  1073. }
  1074. }
  1075. proc launchBrowser url {
  1076. global tcl_platform
  1077. switch $tcl_platform(os) {
  1078. Darwin {
  1079. set command [list open $url]
  1080. }
  1081. HP-UX -
  1082. Linux -
  1083. SunOS {
  1084. foreach executable {firefox mozilla netscape iexplorer opera lynx w3m links epiphany galeon konqueror mosaic amaya browsex elinks} {
  1085. set executable [auto_execok $executable]
  1086. if [string length $executable] {
  1087. set command [list $executable $url &]
  1088. set command [list $executable $url]
  1089. break
  1090. }
  1091. }
  1092. }
  1093. {Windows 95} -
  1094. {Windows NT} {
  1095. set command "[auto_execok start] {} [list $url]"
  1096. }
  1097. }
  1098. if [info exists command] {
  1099. if [catch {exec {*}$command &} err] {
  1100. tk_messageBox -icon error -message "error '$err' with '$command'"
  1101. }
  1102. } else {
  1103. tk_messageBox -icon error -message "Please tell CL that ($tcl_platform(os), $tcl_platform(platform)) is not yet ready for browsing."
  1104. }
  1105. }
  1106. #####################################################################################
  1107. # the GUI
  1108. #####################################################################################
  1109. wm title . "Brushless-Gimbal-Tool (for v$VERSION)"
  1110. proc update_mpu {n1 n2 op} {
  1111. global par
  1112. .note.general.settings.sensor.img.canv delete "arrows"
  1113. if {$par(axisSwapXY) == 1} {
  1114. .note.general.settings.sensor.img.canv create line 18 38 60 15 -fill green -arrow last -tag arrows
  1115. .note.general.settings.sensor.img.canv create line 18 38 50 75 -fill red -arrow last -tag arrows
  1116. .note.general.settings.sensor.img.canv create text 55 75 -text "X" -fill red -tag arrows
  1117. .note.general.settings.sensor.img.canv create text 65 15 -text "Y" -fill green -tag arrows
  1118. } else {
  1119. .note.general.settings.sensor.img.canv create line 18 38 60 15 -fill red -arrow last -tag arrows
  1120. .note.general.settings.sensor.img.canv create line 18 38 50 75 -fill green -arrow last -tag arrows
  1121. .note.general.settings.sensor.img.canv create text 65 15 -text "X" -fill red -tag arrows
  1122. .note.general.settings.sensor.img.canv create text 55 75 -text "Y" -fill green -tag arrows
  1123. }
  1124. if {$par(axisReverseZ) == 1} {
  1125. .note.general.settings.sensor.img.canv create line 18 38 18 100 -fill blue -arrow last -tag arrows
  1126. .note.general.settings.sensor.img.canv create text 23 100 -text "Z" -fill blue -tag arrows
  1127. } else {
  1128. .note.general.settings.sensor.img.canv create line 18 38 18 5 -fill blue -arrow last -tag arrows
  1129. .note.general.settings.sensor.img.canv create text 23 7 -text "Z" -fill blue -tag arrows
  1130. }
  1131. }
  1132. trace variable par(axisReverseZ) w update_mpu
  1133. trace variable par(axisSwapXY) w update_mpu
  1134. ttk::notebook .note
  1135. pack .note -fill both -expand yes -fill both -padx 2 -pady 3
  1136. ttk::frame .note.general
  1137. .note add .note.general -text "Settings"
  1138. label .note.general.image -relief flat -anchor center -image "logo"
  1139. pack .note.general.image -side top -fill none -expand no
  1140. labelframe .note.general.settings -text "General"
  1141. pack .note.general.settings -side top -expand yes -fill both
  1142. labelframe .note.general.settings.rc -text "RC"
  1143. pack .note.general.settings.rc -side left -expand yes -fill both
  1144. gui_check .note.general.settings.rc.rcModePPM rcModePPM "RC PPM/PWM" "PPM" "Mode of RC input, PPM sum oder single PWM RC inputs on A1/A2" "config.rcModePPM: PPM sum oder single PWM RC inputs on A0/A1/A2: PPM sum input on A2 or single RC PWM inputs on A2=Ch0, A1=Ch1, A0=Ch3"
  1145. gui_check .note.general.settings.rc.rcAbsolute rcAbsolute "RC Abs/Prop" "Absolute" "Absolute or Incremental RC control" "config.rcAbsolute: Absolute or Incremental RC control, Absolute: gimbal postion follows RC transmitters directly, Proportional: RC controls the gimbal speed, thus in RC stick in center position (1500us) gimbal stops moving, where as the gimbal starts moving if stick is moved"
  1146. gui_slider .note.general.settings.rc.rcGain rcGain -200 200.0 0.1 "RC Gain" "RC gain" "config.rcGain: RC Gain in Proportional mode: specifies the gain of the RC channel, larger values increas the speed of the gimbal movement"
  1147. gui_slider .note.general.settings.rc.rcLPF rcLPF 1 20 0.1 "RC Low Pass" "RC low pass filter" "config.rcLPF: RC low pass filter in Absolute mode: specifies speed of gimbal movement (sec)"
  1148. gui_slider .note.general.settings.rc.rcMid rcMid 1000 2000 1 "RC middle" "RC middle position" "config.rcMid: RC middle position: specifies the PWM time of the RC center position in us (default=1500)"
  1149. labelframe .note.general.settings.sensor -text "Sensor"
  1150. pack .note.general.settings.sensor -side left -expand yes -fill both
  1151. frame .note.general.settings.sensor.set
  1152. pack .note.general.settings.sensor.set -side left -expand yes -fill both
  1153. gui_check .note.general.settings.sensor.set.axisReverseZ axisReverseZ "Reverse Z-axis" "reversed" "config.axisReverseZ: Set Sensor Orientation: 0=sensor mounted with component side up, 1=sensor mounted upside down" "Set Sensor Orientation Z-Axis: 0=sensor mounted with component side up, 1=sensor mounted upside down"
  1154. gui_check .note.general.settings.sensor.set.axisSwapXY axisSwapXY "Swap XY-axis" "swapped" "config.axisSwapXY: Set Sensor Orientation XY-Axis: 0=normal, 1=swap X/Y axis" "Set Sensor Orientation XY-Axis: 0=normal, 1=functions of X/Y axis are exchanged"
  1155. gui_slider .note.general.settings.sensor.set.accTimeConstant accTimeConstant 1 20 1 "ACC Time Const" "ACC Time Constant(sec)" "tconfig.accTimeConstant: time constant of ACC complementary filter. Controls how fast the gimbal follows ACC (sec)"
  1156. gui_slider .note.general.settings.sensor.set.mpuLPF mpuLPF 0 6 1 "MPU LPF" "low pass filter of gyro" "config.mpuLPF: low pass filter of gyro (DLPFMode) legal values are 0...6, 0=fastest(default) 6=slowest use slow values if high frequency oscillations occur (still experimental)"
  1157. gui_check .note.general.settings.sensor.set.enableGyro enableGyro "Gyro Update" "enabled" "Gyro update" "config.enableGyro: enable gyro update: 0=do not use gyro for attitude calcualtion, just for test and adjustment purposes"
  1158. gui_check .note.general.settings.sensor.set.enableACC enableACC "ACC Update" "enabled" "ACC update" "config.enableACC: enable ACC update: 0=do not use ACC for attitude calculation, just for test and adjustment purposes"
  1159. frame .note.general.settings.sensor.img
  1160. pack .note.general.settings.sensor.img -side left -expand no -fill none
  1161. canvas .note.general.settings.sensor.img.canv -relief raised -width 120 -height 120
  1162. pack .note.general.settings.sensor.img.canv -side left
  1163. .note.general.settings.sensor.img.canv create image 0 0 -anchor nw -image sensor
  1164. update_mpu 0 0 0
  1165. labelframe .note.general.chart -text "Chart"
  1166. pack .note.general.chart -side top -expand no -fill both
  1167. canvas .note.general.chart.chart1 -relief raised -width 450 -height 100
  1168. pack .note.general.chart.chart1 -side left
  1169. .note.general.chart.chart1 create rec 1 1 450 100 -fill black
  1170. .note.general.chart.chart1 create line 0 50 450 50 -fill white
  1171. setTooltip .note.general.chart.chart1 "acc chart"
  1172. frame .note.general.chart.fr1
  1173. pack .note.general.chart.fr1 -side left -expand yes -fill both
  1174. button .note.general.chart.fr1.button -text "Start" -width 5 -relief raised -command {
  1175. draw_chart
  1176. }
  1177. pack .note.general.chart.fr1.button -side top -expand yes -fill both
  1178. setTooltip .note.general.chart.fr1.button "start/stop chart drawing"
  1179. frame .note.general.chart.fr1.scale
  1180. pack .note.general.chart.fr1.scale -side top -expand no -fill x
  1181. scale .note.general.chart.fr1.scale.slider -orient horizontal -from 0.1 -to 10.0 -showvalue 0 -resolution 0.1 -variable CHART_SCALE
  1182. pack .note.general.chart.fr1.scale.slider -side left -expand yes -fill x
  1183. setTooltip .note.general.chart.fr1.scale.slider "Y-Scale for the chart"
  1184. button .note.general.chart.fr1.scale.help -text "?" -width 1 -command {
  1185. show_help "Y-Scale for the chart"
  1186. }
  1187. pack .note.general.chart.fr1.scale.help -side right -expand no -fill none
  1188. ttk::frame .note.pitch
  1189. .note add .note.pitch -text "Pitch"
  1190. labelframe .note.pitch.pid -text "PID" -padx 10 -pady 10
  1191. pack .note.pitch.pid -side top -expand no -fill x
  1192. gui_slider .note.pitch.pid.p gyroPitch