├── .gitignore ├── ControlSoftware ├── .cproject ├── .project ├── CMakeLists.txt ├── Toolchain_Win32.cmake ├── Toolchain_Win64.cmake ├── firmware │ └── firmware_openrtms_h09_20130202.binary ├── i18n │ └── de │ │ ├── Open-rTMS.mo │ │ └── Open-rTMS.po └── src │ ├── 3D │ ├── AffineTransformMatrix.cpp │ ├── AffineTransformMatrix.h │ ├── CMakeLists.txt │ ├── FileDXF.cpp │ ├── FileDXF.h │ ├── Geometry.cpp │ ├── Geometry.h │ ├── GeometryFileAbstract.cpp │ ├── GeometryFileAbstract.h │ ├── Triangle.cpp │ ├── Triangle.h │ ├── Vector3.cpp │ └── Vector3.h │ ├── CMakeLists.txt │ ├── Config.h │ ├── Open-rTMS.cpp │ ├── Open-rTMS.h │ ├── StdInclude.h │ ├── gui │ ├── AboutDialog.cpp │ ├── AboutDialog.h │ ├── CMakeLists.txt │ ├── DialogCurrentControl.cpp │ ├── DialogCurrentControl.h │ ├── MainCanvas.cpp │ ├── MainCanvas.h │ ├── MainFrame.cpp │ ├── MainFrame.h │ ├── SerialSetupDialog.cpp │ ├── SerialSetupDialog.h │ ├── gui.cpp │ ├── gui.h │ └── open-rtms.fbp │ ├── hardware │ ├── CMakeLists.txt │ ├── ParallaxPropeller.cpp │ ├── ParallaxPropeller.h │ ├── SerialPort.cpp │ └── SerialPort.h │ ├── icon │ └── logo.xpm │ └── languages.h ├── README.md └── SignalGenerator ├── eagle ├── Generator_V0.9.brd └── Generator_V0.9.sch └── spin ├── EightChannelDAC.spin ├── Testbench_VGAOverlay.spin ├── TextDriver16x16.spin ├── TextDriver16x32.spin ├── firmware_openrtms_h09_20130202.binary └── firmware_openrtms_h09_20130202.spin /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | build/ 35 | -------------------------------------------------------------------------------- /ControlSoftware/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 31 | 32 | 33 | 34 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 87 | 88 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | -------------------------------------------------------------------------------- /ControlSoftware/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ControlSoftware 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/ControlSoftware/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | 73 | 74 | 75 | 76 | 77 | org.eclipse.cdt.core.ccnature 78 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 80 | org.eclipse.cdt.core.cnature 81 | 82 | 83 | -------------------------------------------------------------------------------- /ControlSoftware/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(Open-rTMS_Control_Software) 4 | 5 | find_package(wxWidgets COMPONENTS gl core base REQUIRED) 6 | include( "${wxWidgets_USE_FILE}" ) 7 | 8 | add_subdirectory(src) 9 | 10 | if(MINGW) 11 | 12 | add_executable(openrtmscontrol.exe src/Open-rTMS.cpp) 13 | 14 | target_link_libraries(openrtmscontrol.exe 15 | 3D 16 | gui 17 | hardware 18 | ${wxWidgets_LIBRARIES} 19 | opengl32 20 | glu32 21 | ) 22 | 23 | elseif(APPLE) 24 | 25 | find_package(OpenGL REQUIRED) 26 | add_executable(openrtmscontrol src/Open-rTMS.cpp) 27 | 28 | target_link_libraries(openrtmscontrol 29 | 3D 30 | gui 31 | hardware 32 | ${wxWidgets_LIBRARIES} 33 | ${OPENGL_gl_LIBRARY} 34 | ${OPENGL_glu_LIBRARY} 35 | ) 36 | 37 | else() 38 | 39 | add_executable(openrtmscontrol src/Open-rTMS.cpp) 40 | 41 | target_link_libraries(openrtmscontrol 42 | 3D 43 | gui 44 | hardware 45 | ${wxWidgets_LIBRARIES} 46 | GL 47 | GLU 48 | ) 49 | 50 | endif() 51 | 52 | file(COPY i18n DESTINATION ${CMAKE_BINARY_DIR}) 53 | file(COPY firmware DESTINATION ${CMAKE_BINARY_DIR}) 54 | 55 | -------------------------------------------------------------------------------- /ControlSoftware/Toolchain_Win32.cmake: -------------------------------------------------------------------------------- 1 | # this one is important 2 | SET(CMAKE_SYSTEM_NAME Linux) 3 | #this one not so much 4 | SET(CMAKE_SYSTEM_VERSION 1) 5 | 6 | # specify the cross compiler 7 | SET(CMAKE_C_COMPILER /usr/bin/i586-mingw32msvc-gcc) 8 | SET(CMAKE_CXX_COMPILER /usr/bin/i586-mingw32msvc-g++) 9 | SET(CMAKE_RC_COMPILER /usr/bin/i586-mingw32msvc-windres) 10 | 11 | 12 | SET(wxWidgets_CONFIG_EXECUTABLE /usr/local/i586-mingw32/bin/wx-config) 13 | SET(wxWidgets_ROOT_DIR /usr/local/i586-mingw32) 14 | SET(wxWidgets_LIB_DIR /usr/local/i586-mingw32/lib) 15 | 16 | # where is the target environment 17 | SET(CMAKE_FIND_ROOT_PATH /usr/local/i586-mingw32 /usr/local/i586-mingw32/bin) 18 | 19 | # adjust the default behaviour of the FIND_XXX() commands: 20 | # search headers and libraries in the target environment, search 21 | # programs in the host environment 22 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM FIRST) 23 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 24 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 25 | -------------------------------------------------------------------------------- /ControlSoftware/Toolchain_Win64.cmake: -------------------------------------------------------------------------------- 1 | 2 | # this one is important 3 | SET(CMAKE_SYSTEM_NAME Windows) 4 | #this one not so much 5 | SET(CMAKE_SYSTEM_VERSION 1) 6 | 7 | # specify the cross compiler 8 | SET(CMAKE_C_COMPILER /usr/bin/i686-w64-mingw32-gcc) 9 | SET(CMAKE_CXX_COMPILER /usr/bin/i686-w64-mingw32-g++) 10 | SET(CMAKE_RC_COMPILER /usr/bin/i686-w64-mingw32-windres) 11 | 12 | # where is the target environment 13 | SET(CMAKE_FIND_ROOT_PATH /usr/amd64-mingw32msvc /usr/local/i586-mingw32 /usr/local/i586-mingw32/bin) 14 | 15 | # adjust the default behaviour of the FIND_XXX() commands: 16 | # search headers and libraries in the target environment, search 17 | # programs in the host environment 18 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 19 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 20 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 21 | 22 | -------------------------------------------------------------------------------- /ControlSoftware/firmware/firmware_openrtms_h09_20130202.binary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/ControlSoftware/firmware/firmware_openrtms_h09_20130202.binary -------------------------------------------------------------------------------- /ControlSoftware/i18n/de/Open-rTMS.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/ControlSoftware/i18n/de/Open-rTMS.mo -------------------------------------------------------------------------------- /ControlSoftware/i18n/de/Open-rTMS.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: Open rTMS V 0.2\n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 2013-02-23 17:54+0100\n" 6 | "PO-Revision-Date: 2014-01-19 15:35+0100\n" 7 | "Last-Translator: Tobias Schaefer \n" 8 | "Language-Team: Tobias Schaefer \n" 9 | "Language: \n" 10 | "MIME-Version: 1.0\n" 11 | "Content-Type: text/plain; charset=UTF-8\n" 12 | "Content-Transfer-Encoding: 8bit\n" 13 | "X-Poedit-KeywordsList: _;gettext;gettext_noop\n" 14 | "X-Poedit-Basepath: .\n" 15 | "X-Poedit-Language: German\n" 16 | "X-Poedit-Country: GERMANY\n" 17 | "X-Poedit-SourceCharset: utf-8\n" 18 | "X-Poedit-SearchPath-0: ./../../src\n" 19 | 20 | #: ../../src/gui/SerialSetupDialog.cpp:44 21 | msgid "Connected!\n" 22 | msgstr "Verbunden!\n" 23 | 24 | #: ../../src/gui/SerialSetupDialog.cpp:59 25 | msgid "Port could not be opened!\n" 26 | msgstr "Port konnte nicht geöffnet werden!\n" 27 | 28 | #: ../../src/gui/SerialSetupDialog.cpp:64 29 | msgid "" 30 | "Connected...\n" 31 | "Searching for Parallax Propeller...\n" 32 | msgstr "" 33 | "Verbinde...\n" 34 | "Suche nach einem Parallax Propeller...\n" 35 | 36 | #: ../../src/gui/SerialSetupDialog.cpp:74 37 | msgid "No Parallax Propeller found on this port!\n" 38 | msgstr "Kein Parallax Propeller an diesem Port gefunden!\n" 39 | 40 | #: ../../src/gui/SerialSetupDialog.cpp:77 41 | #, c-format 42 | msgid "Parallax Propeller (Version %d) found!\n" 43 | msgstr "Parallax Propeller (Version %d) gefunden!\n" 44 | 45 | #: ../../src/gui/SerialSetupDialog.cpp:80 46 | msgid "Finished searching!" 47 | msgstr "Suche abgeschlossen!" 48 | 49 | #: ../../src/gui/SerialSetupDialog.cpp:98 50 | msgid "Programming...\n" 51 | msgstr "Programmiere...\n" 52 | 53 | #: ../../src/gui/SerialSetupDialog.cpp:108 54 | msgid "Scope loaded and started!\n" 55 | msgstr "Scope loaded and started!\n" 56 | 57 | #: ../../src/gui/SerialSetupDialog.cpp:130 58 | msgid "Disconnected!" 59 | msgstr "Getrennt!" 60 | 61 | #: ../../src/gui/MainFrame.cpp:78 62 | msgid "Hardware: Connected" 63 | msgstr "Hardware: Verbunden" 64 | 65 | #: ../../src/gui/MainFrame.cpp:88 66 | msgid "Hardware: Disconnected" 67 | msgstr "Hardware: Getrennt" 68 | 69 | #: ../../src/gui/MainFrame.cpp:131 70 | msgid "Connection to hardware" 71 | msgstr "Mit der Hardware verbinden" 72 | 73 | #: ../../src/gui/MainFrame.cpp:37 74 | msgid "Open-rTMS - log window" 75 | msgstr "Open-rTMS - Protokollfenster" 76 | 77 | #: ../../src/gui/gui.cpp:20 78 | msgid "&Connect" 79 | msgstr "&Verbinden" 80 | 81 | #: ../../src/gui/gui.cpp:24 82 | msgid "&Control currents" 83 | msgstr "&Ströme einstellen" 84 | 85 | #: ../../src/gui/gui.cpp:29 86 | msgid "&Disconnect" 87 | msgstr "&Trennen" 88 | 89 | #: ../../src/gui/gui.cpp:29 90 | msgid "Disconnect from hardware" 91 | msgstr "Von der Hardware trennen" 92 | 93 | #: ../../src/gui/gui.cpp:37 94 | msgid "&Quit" 95 | msgstr "&Beenden" 96 | 97 | #: ../../src/gui/gui.cpp:20 98 | msgid "Quit the program." 99 | msgstr "Das Programm beenden." 100 | 101 | #: ../../src/gui/gui.cpp:23 102 | msgid "&Project" 103 | msgstr "&Projekt" 104 | 105 | #: ../../src/gui/gui.cpp:44 106 | msgid "&Setup and program hardware" 107 | msgstr "&Einstellungen und Hardware programmieren" 108 | 109 | #: ../../src/gui/gui.cpp:44 110 | msgid "Setup the serial port and program the hardware." 111 | msgstr "Einstellungen der seriellen Schnittstelle und Programierung der Hardware." 112 | 113 | #: ../../src/gui/gui.cpp:27 114 | msgid "&Change the language" 115 | msgstr "&Sprache ändern (Change language)" 116 | 117 | #: ../../src/gui/gui.cpp:27 118 | msgid "Change the language of the program." 119 | msgstr "Übersetzung des Programms auswählen." 120 | 121 | #: ../../src/gui/gui.cpp:30 122 | msgid "&Settings" 123 | msgstr "&Einstellungen" 124 | 125 | #: ../../src/gui/gui.cpp:34 126 | msgid "&About" 127 | msgstr "&Über..." 128 | 129 | #: ../../src/gui/gui.cpp:58 130 | msgid "&Help" 131 | msgstr "&Hilfe" 132 | 133 | #: ../../src/gui/gui.cpp:74 134 | #: ../../src/gui/gui.cpp:178 135 | msgid "Connect" 136 | msgstr "Verbinden" 137 | 138 | #: ../../src/gui/gui.cpp:80 139 | msgid "Control currents" 140 | msgstr "Ströme einstellen" 141 | 142 | #: ../../src/gui/gui.cpp:88 143 | #: ../../src/gui/gui.cpp:181 144 | msgid "Disconnect" 145 | msgstr "Trennen" 146 | 147 | #: ../../src/gui/gui.cpp:71 148 | msgid "" 149 | "Open rTMS Control Center\n" 150 | "\n" 151 | "(C) Tobias Schäfer 2011\n" 152 | "\n" 153 | "GNU General Public License version 3.0 (GPLv3)\n" 154 | "\n" 155 | "This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n" 156 | "This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n" 157 | "\n" 158 | "You should have received a copy of the GNU General Public License along with this program. If not, see ." 159 | msgstr "" 160 | "Open rTMS Control Center\n" 161 | "\n" 162 | "(C) Tobias Schäfer 2011\n" 163 | "\n" 164 | "GNU General Public License version 3.0 (GPLv3)\n" 165 | "\n" 166 | "This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n" 167 | "This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n" 168 | "\n" 169 | "You should have received a copy of the GNU General Public License along with this program. If not, see ." 170 | 171 | #: ../../src/gui/gui.cpp:74 172 | msgid "Ok" 173 | msgstr "OK" 174 | 175 | #: ../../src/gui/gui.h:61 176 | msgid "Open-rTMS Control Center" 177 | msgstr "Open-rTMS Control Center" 178 | 179 | #: ../../src/gui/gui.h:79 180 | msgid "Open-rTMS About" 181 | msgstr "Über diese Anwendung..." 182 | 183 | #: ../../src/gui/gui.h:131 184 | msgid "Open-rTMS Setup Serial Connection" 185 | msgstr "Open-rTMS - Serielle Verbindung konfigurieren" 186 | 187 | #: ../../src/gui/gui.h:188 188 | msgid "Current Control" 189 | msgstr "Ströme einstellen" 190 | 191 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/AffineTransformMatrix.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : AffineTransformMatrix.cpp 3 | // Purpose : A class to store a 3D affine transform matrix and provide operations upon. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : -lm 7 | // Author : Tobias Schaefer, Samy Kamkar 8 | // Updated : 2020/02/20 9 | // Created : 22.07.2009 10 | // Copyright : (C) 2009 Tobias Schaefer 11 | // Licence : GNU General Public License version 3.0 (GPLv3) 12 | // 13 | // This program is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published by 15 | // the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This program is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | // 26 | //$LastChangedDate: 2010-08-06 03:05:34 +0200 (Fr, 06 Aug 2010) $ 27 | //$Revision: 58 $ 28 | //$LastChangedBy: schaefer $ 29 | /////////////////////////////////////////////////////////////////////////////// 30 | 31 | 32 | #include "AffineTransformMatrix.h" 33 | 34 | #include 35 | #include 36 | #include // this is a magic incantation which must be done! 37 | WX_DEFINE_OBJARRAY(ArrayOfAffineTransformMatrix) 38 | 39 | AffineTransformMatrix::AffineTransformMatrix() 40 | { 41 | SetIdentity(); 42 | linkScaling = true; 43 | } 44 | 45 | AffineTransformMatrix::~AffineTransformMatrix() 46 | { 47 | } 48 | 49 | /*!\brief Copies a matrix by inserting a given matrix into \a a. 50 | * \param matrix The matrix to copy. 51 | */ 52 | void AffineTransformMatrix::Set(AffineTransformMatrix const& b) 53 | { 54 | if(this == &b) return; 55 | size_t i; 56 | for(i = 0; i < 16; i++) 57 | a[i] = b.a[i]; 58 | TakeMatrixApart(); 59 | } 60 | 61 | AffineTransformMatrix& AffineTransformMatrix::operator=( 62 | const AffineTransformMatrix &b) 63 | { 64 | if(this == &b) return *this; 65 | size_t i; 66 | for(i = 0; i < 16; i++) 67 | this->a[i] = b.a[i]; 68 | //this->TakeMatrixApart(); 69 | return *this; 70 | } 71 | 72 | //! Resets the matrix to the identity matrix. 73 | void AffineTransformMatrix::SetIdentity() 74 | { 75 | rx = ry = rz = 0.0; 76 | tx = ty = tz = 0.0; 77 | sx = sy = sz = 1.0; 78 | unsigned char i; 79 | for(i = 0; i < 16; i++) 80 | a[i] = 0; 81 | a[0] = 1.0; 82 | a[5] = 1.0; 83 | a[10] = 1.0; 84 | a[15] = 1.0; 85 | } 86 | 87 | //! Returns the center point of the matrix. 88 | Vector3 AffineTransformMatrix::GetCenter(void) const 89 | { 90 | Vector3 temp; 91 | temp.x = a[12]; 92 | temp.y = a[13]; 93 | temp.z = a[14]; 94 | return temp; 95 | } 96 | 97 | //! Generate a string containing the matrix. 98 | wxString AffineTransformMatrix::ToString() 99 | { 100 | TakeMatrixApart(); 101 | wxString temp; 102 | temp += wxString::Format(_T("%f#%f#%f#"), tx, ty, tz); 103 | temp += wxString::Format(_T("%f#%f#%f#"), rx, ry, rz); 104 | temp += wxString::Format(_T("%f#%f#%f"), sx, sy, sz); 105 | return temp; 106 | } 107 | 108 | //! Setup the matrix from a string. 109 | void AffineTransformMatrix::FromString(wxString const& string) 110 | { 111 | wxStringTokenizer tkz(string, wxT("#")); 112 | while(tkz.HasMoreTokens()){ 113 | wxString token = tkz.GetNextToken(); 114 | switch(tkz.CountTokens()){ 115 | case 8: 116 | token.ToDouble(&tx); 117 | break; 118 | case 7: 119 | token.ToDouble(&ty); 120 | break; 121 | case 6: 122 | token.ToDouble(&tz); 123 | break; 124 | case 5: 125 | token.ToDouble(&rx); 126 | break; 127 | case 4: 128 | token.ToDouble(&ry); 129 | break; 130 | case 3: 131 | token.ToDouble(&rz); 132 | break; 133 | case 2: 134 | token.ToDouble(&sx); 135 | break; 136 | case 1: 137 | token.ToDouble(&sy); 138 | break; 139 | case 0: 140 | token.ToDouble(&sz); 141 | break; 142 | } 143 | } 144 | PutMatrixTogether(); 145 | } 146 | 147 | //! Calculate rx,ry,rz,tx,ty,tz and sx,sy,sz from the matrix. 148 | void AffineTransformMatrix::TakeMatrixApart(void) 149 | { 150 | double b[16]; 151 | 152 | tx = a[12]; 153 | ty = a[13]; 154 | tz = a[14]; 155 | 156 | sx = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); 157 | sy = sqrt(a[4] * a[4] + a[5] * a[5] + a[6] * a[6]); 158 | sz = sqrt(a[8] * a[8] + a[9] * a[9] + a[10] * a[10]); 159 | 160 | if(sx > 0.0){ 161 | b[0] = a[0] / sx; 162 | b[1] = a[1] / sx; 163 | b[2] = a[2] / sx; 164 | }else{ 165 | b[0] = 0.0; 166 | b[1] = 0.0; 167 | b[2] = 0.0; 168 | } 169 | if(sy > 0.0){ 170 | b[4] = a[4] / sy; 171 | b[5] = a[5] / sy; 172 | b[6] = a[6] / sy; 173 | }else{ 174 | b[4] = 0.0; 175 | b[5] = 0.0; 176 | b[6] = 0.0; 177 | } 178 | if(sz > 0.0){ 179 | b[8] = a[8] / sz; 180 | b[9] = a[9] / sz; 181 | b[10] = a[10] / sz; 182 | }else{ 183 | b[8] = 0.0; 184 | b[9] = 0.0; 185 | b[10] = 0.0; 186 | } 187 | 188 | //FIXME: I think this if(...) is wrong, because b[0] can be 0. 189 | if(b[0] != 0.0 || b[1] != 0.0){ 190 | rz = atan2(b[1], b[0]); 191 | }else{ 192 | rz = 0.0; 193 | } 194 | double coz = cos(rz); 195 | double siz = sin(rz); 196 | 197 | if(b[0] != 0.0 || b[1] != 0.0 || b[2] != 0.0){ 198 | ry = atan2(-b[2], sqrt(b[0] * b[0] + b[1] * b[1])); 199 | }else{ 200 | ry = 0.0; 201 | } 202 | double coy = cos(ry); 203 | double siy = sin(ry); 204 | 205 | b[0] = b[5] * coy * siz - b[6] * siy + b[4] * coy * coz; 206 | b[1] = -b[4] * siz + b[5] * coz; 207 | b[2] = b[5] * siy * siz + b[4] * coz * siy + b[6] * coy; 208 | 209 | if(b[1] != 0.0 || b[2] != 0.0){ 210 | rx = atan2(b[2], b[1]); 211 | }else{ 212 | rx = 0.0; 213 | } 214 | } 215 | 216 | //! Calculate the matrix from rx,ry,rz,tx,ty,tz and sx,sy,sz. 217 | void AffineTransformMatrix::PutMatrixTogether(void) 218 | { 219 | double cox = cos(rx); 220 | double six = sin(rx); 221 | double coy = cos(ry); 222 | double siy = sin(ry); 223 | double coz = cos(rz); 224 | double siz = sin(rz); 225 | 226 | 227 | //Matrix calculated with Axiom: 228 | // Rx := matrix[[1,0,0],[0,cox,-six],[0,six,cox]] 229 | // Ry := matrix[[coy,0,siy],[0,1,0],[-siy,0,coy]] 230 | // Rz := matrix[[coz,-siz,0],[siz,coz,0],[0,0,1]] 231 | // S := matrix[[sx,0,0],[0,sy,0],[0,0,sz]] 232 | // Rz*Ry*Rx*S 233 | 234 | a[0] = coy * coz * sx; 235 | a[1] = coy * siz * sx; 236 | a[2] = -siy * sx; 237 | a[3] = 0.0; 238 | a[4] = (-cox * siz + coz * six * siy) * sy; 239 | a[5] = (six * siy * siz + cox * coz) * sy; 240 | a[6] = coy * six * sy; 241 | a[7] = 0.0; 242 | a[8] = (six * siz + cox * coz * siy) * sz; 243 | a[9] = (cox * siy * siz - coz * six) * sz; 244 | a[10] = cox * coy * sz; 245 | a[11] = 0.0; 246 | a[12] = tx; 247 | a[13] = ty; 248 | a[14] = tz; 249 | a[15] = 1.0; 250 | } 251 | 252 | /*! \brief Inverts the matrix. 253 | * 254 | * The transform used in here is optimized for matrices with 0,0,0,1 in the last row. 255 | * It would not give the correct results for other matrices, 256 | * 257 | * \return Inverted matrix. 258 | */ 259 | const AffineTransformMatrix AffineTransformMatrix::Inverse() const 260 | { 261 | //Axiom code: 262 | // )set fortran optlevel 2 263 | // )set output fortran on 264 | // R:=matrix([[a[0],a[4],a[8],a[12]],[a[1],a[5],a[9],a[13]],[a[2],a[6],a[10],a[14]],[0,0,0,1]]) 265 | // inverse(R) 266 | 267 | double T11 = (a[0] * a[5] + (-a[1] * a[4])) * a[10] + ((-a[0] * a[6]) 268 | + a[2] * a[4]) * a[9] + (a[1] * a[6] + (-a[2] * a[5])) * a[8]; 269 | // T11 is the determinant of the matrix. This can not 270 | // not be zero for a correct transformation matrix. 271 | wxASSERT(T11!=0); 272 | 273 | double T12 = a[4] * a[9]; 274 | double T13 = a[5] * a[8]; 275 | double T14 = a[4] * a[10]; 276 | double T15 = a[6] * a[8]; 277 | double T16 = a[5] * a[10]; 278 | double T17 = a[6] * a[9]; 279 | double T18 = a[0] * a[9]; 280 | double T19 = a[1] * a[8]; 281 | double T21 = a[0] * a[10]; 282 | double T22 = a[2] * a[8]; 283 | double T24 = a[1] * a[10]; 284 | double T25 = a[2] * a[9]; 285 | double T27 = a[1] * a[6] + (-a[2] * a[5]); 286 | double T28 = (-a[0] * a[6]) + a[2] * a[4]; 287 | double T29 = a[0] * a[5] + (-a[1] * a[4]); 288 | double T30 = a[0] * a[5]; 289 | double T31 = a[1] * a[4]; 290 | double T32 = a[0] * a[6]; 291 | double T33 = a[2] * a[4]; 292 | double T34 = a[1] * a[6]; 293 | double T35 = a[2] * a[5]; 294 | 295 | AffineTransformMatrix b; 296 | 297 | b.a[0] = (T16 - T17) / T11; 298 | b.a[4] = (-T14 + T15) / T11; 299 | b.a[8] = (T12 - T13) / T11; 300 | b.a[12] = ((-T12 + T13) * a[14] + (T14 - T15) * a[13] + (-T16 + T17) 301 | * a[12]) / T11; 302 | b.a[1] = (-T24 + T25) / T11; 303 | b.a[5] = (T21 - T22) / T11; 304 | b.a[9] = (-T18 + T19) / T11; 305 | b.a[13] = ((T18 - T19) * a[14] + (-T21 + T22) * a[13] + (-T25 + T24) 306 | * a[12]) / T11; 307 | b.a[2] = T27 / T11; 308 | b.a[6] = T28 / T11; 309 | b.a[10] = T29 / T11; 310 | b.a[14] = ((-T30 + T31) * a[14] + (T32 - T33) * a[13] + (-T34 + T35) 311 | * a[12]) / T11; 312 | b.a[2] = 0; 313 | b.a[6] = 0; 314 | b.a[11] = 0; 315 | b.a[15] = 1; 316 | return b; 317 | } 318 | 319 | //! Overloaded operator to allow correct multiplication of two matrices. 320 | AffineTransformMatrix & AffineTransformMatrix::operator*=( 321 | const AffineTransformMatrix &b) 322 | { 323 | //Generated with this code: 324 | //php -r'for($i=0;$i<4;$i++){for($j=0;$j<4;$j++){printf("this->a[%u]=",$i*4+$j);for($k=0;$k<4;$k++){printf("c[%u]*b.a[%u]%s",$k*4+$j,$i*4+$k,($k==3)?";\r\n":"+");}}}' 325 | 326 | double c[16]; 327 | size_t i; 328 | for(i = 0; i < 16; i++) 329 | c[i] = this->a[i]; 330 | 331 | this->a[0] = c[0] * b.a[0] + c[4] * b.a[1] + c[8] * b.a[2] + c[12] * b.a[3]; 332 | this->a[1] = c[1] * b.a[0] + c[5] * b.a[1] + c[9] * b.a[2] + c[13] * b.a[3]; 333 | this->a[2] = c[2] * b.a[0] + c[6] * b.a[1] + c[10] * b.a[2] + c[14] 334 | * b.a[3]; 335 | this->a[3] = c[3] * b.a[0] + c[7] * b.a[1] + c[11] * b.a[2] + c[15] 336 | * b.a[3]; 337 | this->a[4] = c[0] * b.a[4] + c[4] * b.a[5] + c[8] * b.a[6] + c[12] * b.a[7]; 338 | this->a[5] = c[1] * b.a[4] + c[5] * b.a[5] + c[9] * b.a[6] + c[13] * b.a[7]; 339 | this->a[6] = c[2] * b.a[4] + c[6] * b.a[5] + c[10] * b.a[6] + c[14] 340 | * b.a[7]; 341 | this->a[7] = c[3] * b.a[4] + c[7] * b.a[5] + c[11] * b.a[6] + c[15] 342 | * b.a[7]; 343 | this->a[8] = c[0] * b.a[8] + c[4] * b.a[9] + c[8] * b.a[10] + c[12] 344 | * b.a[11]; 345 | this->a[9] = c[1] * b.a[8] + c[5] * b.a[9] + c[9] * b.a[10] + c[13] 346 | * b.a[11]; 347 | this->a[10] = c[2] * b.a[8] + c[6] * b.a[9] + c[10] * b.a[10] + c[14] 348 | * b.a[11]; 349 | this->a[11] = c[3] * b.a[8] + c[7] * b.a[9] + c[11] * b.a[10] + c[15] 350 | * b.a[11]; 351 | this->a[12] = c[0] * b.a[12] + c[4] * b.a[13] + c[8] * b.a[14] + c[12] 352 | * b.a[15]; 353 | this->a[13] = c[1] * b.a[12] + c[5] * b.a[13] + c[9] * b.a[14] + c[13] 354 | * b.a[15]; 355 | this->a[14] = c[2] * b.a[12] + c[6] * b.a[13] + c[10] * b.a[14] + c[14] 356 | * b.a[15]; 357 | this->a[15] = c[3] * b.a[12] + c[7] * b.a[13] + c[11] * b.a[14] + c[15] 358 | * b.a[15]; 359 | 360 | return *this; 361 | } 362 | 363 | //! Overloaded operator to allow correct multiplication of two matrices. 364 | const AffineTransformMatrix AffineTransformMatrix::operator*( 365 | const AffineTransformMatrix &b) const 366 | { 367 | AffineTransformMatrix c = *this; 368 | c *= b; 369 | return c; 370 | } 371 | 372 | /*!\brief Overloaded operator to allow correct division of two matrices. 373 | * 374 | * The division is done by inverting the second matrix and the multiplying both. 375 | */ 376 | AffineTransformMatrix & AffineTransformMatrix::operator/=( 377 | const AffineTransformMatrix &b) 378 | { 379 | (*this) = (*this) * (b.Inverse()); 380 | return *this; 381 | } 382 | 383 | const AffineTransformMatrix AffineTransformMatrix::operator/( 384 | const AffineTransformMatrix &b) const 385 | { 386 | AffineTransformMatrix c = *this; 387 | c /= b; 388 | return c; 389 | } 390 | 391 | //! Apply the transformation matrix on a given vector. 392 | Vector3 AffineTransformMatrix::Transform(Vector3 const& v) const 393 | { 394 | //Axiom code: 395 | //R:=matrix([[a[0],a[4],a[8],a[12]],[a[1],a[5],a[9],a[13]],[a[2],a[6],a[10],a[14]],[0,0,0,1]]) 396 | //R*matrix([[x],[y],[z],[1]]) 397 | 398 | Vector3 temp; 399 | temp.x = a[0] * v.x + a[4] * v.y + a[8] * v.z + a[12]; 400 | temp.y = a[1] * v.x + a[5] * v.y + a[9] * v.z + a[13]; 401 | temp.z = a[2] * v.x + a[6] * v.y + a[10] * v.z + a[14]; 402 | return temp; 403 | } 404 | 405 | //! Apply the transformation matrix on a given vector without shifting the vector. 406 | Vector3 AffineTransformMatrix::TransformNoShift(Vector3 const& v) const 407 | { 408 | //Axiom code: 409 | //R:=matrix([[a[0],a[4],a[8],0],[a[1],a[5],a[9],0],[a[2],a[6],a[10],0],[0,0,0,1]]) 410 | //R*matrix([[x],[y],[z],[1]]) 411 | 412 | Vector3 temp; 413 | temp.x = a[0] * v.x + a[4] * v.y + a[8] * v.z; 414 | temp.y = a[1] * v.x + a[5] * v.y + a[9] * v.z; 415 | temp.z = a[2] * v.x + a[6] * v.y + a[10] * v.z; 416 | return temp; 417 | } 418 | 419 | //! Function returning an identity matrix. 420 | AffineTransformMatrix AffineTransformMatrix::Identity() 421 | { 422 | AffineTransformMatrix a; 423 | return a; 424 | } 425 | 426 | //! Translate matrix in the global coordinate system. 427 | void AffineTransformMatrix::TranslateGlobal(double const& x, double const& y, 428 | double const& z) 429 | { 430 | a[12] += x; 431 | a[13] += y; 432 | a[14] += z; 433 | } 434 | 435 | //! Translate matrix in the local, rotated coordinate system. 436 | void AffineTransformMatrix::TranslateLocal(double const& x, double const& y, 437 | double const& z) 438 | { 439 | a[12] += x * a[0] + y * a[4] + z * a[8]; 440 | a[13] += x * a[1] + y * a[5] + z * a[9]; 441 | a[14] += x * a[2] + y * a[6] + z * a[10]; 442 | } 443 | 444 | //! Scale matrix in the global coordinate system. 445 | void AffineTransformMatrix::ScaleGlobal(double const& x, double const& y, 446 | double const& z) 447 | { 448 | a[0] *= x; 449 | a[1] *= x; 450 | a[2] *= x; 451 | a[4] *= y; 452 | a[5] *= y; 453 | a[6] *= y; 454 | a[8] *= z; 455 | a[9] *= z; 456 | a[10] *= z; 457 | } 458 | 459 | /*!\brief Rotation around a given vector. 460 | * 461 | * Generates a rotation matrix around a given vector. 462 | * \param vector Axis of rotation. 463 | * \param phi Angle of rotation. 464 | * \return Rotation matrix. 465 | */ 466 | AffineTransformMatrix AffineTransformMatrix::RotateAroundVector( 467 | Vector3 const& vector, double const& phi) 468 | { 469 | double c = cos(phi); 470 | double s = sin(phi); 471 | double t = 1 - c; 472 | 473 | Vector3 v(vector); 474 | v.Normalize(); 475 | 476 | AffineTransformMatrix a; 477 | 478 | a.a[0] = t * v.x * v.x + c; 479 | a.a[1] = t * v.x * v.y + s * v.z; 480 | a.a[2] = t * v.x * v.z - s * v.y; 481 | 482 | a.a[4] = t * v.x * v.y - s * v.z; 483 | a.a[5] = t * v.y * v.y + c; 484 | a.a[6] = t * v.y * v.z + s * v.x; 485 | 486 | a.a[8] = t * v.x * v.z + s * v.y; 487 | a.a[9] = t * v.y * v.z - s * v.x; 488 | a.a[10] = t * v.z * v.z + c; 489 | 490 | return a; 491 | } 492 | 493 | /*! \brief Rotation by mouse. 494 | * 495 | * This function is only a drop in until the RotateByTrackball function works. 496 | * 497 | * \param x Movement of mouse in x direction (=xnew-xold). 498 | * \param y Movement of mouse in y direction (=ynew-yold). 499 | * \param scale Scaling of the movement. 500 | * \return Rotation matrix. 501 | */ 502 | AffineTransformMatrix AffineTransformMatrix::RotateXY(int const& x, 503 | int const& y, double const& scale) 504 | { 505 | 506 | double dx = (double) x / scale; 507 | double dy = (double) y / scale; 508 | 509 | double dist = sqrt(dx * dx + dy * dy); 510 | 511 | AffineTransformMatrix a; 512 | 513 | if(dist > 0.001){ 514 | double ang = -atan2(dy, dx); 515 | 516 | double coy = cos(dist / 100); 517 | double siy = sin(dist / 100); 518 | double coz = cos(ang); 519 | double siz = sin(ang); 520 | 521 | a.a[0] = coz * coz * coy + siz * siz; 522 | a.a[1] = coz * siz * coy - coz * siz; 523 | a.a[2] = -coz * siy; 524 | a.a[4] = siz * coz * coy - coz * siz; 525 | a.a[5] = siz * siz * coy + coz * coz; 526 | a.a[6] = -siz * siy; 527 | a.a[8] = coz * siy; 528 | a.a[9] = siz * siy; 529 | a.a[10] = coy; 530 | } 531 | return a; 532 | } 533 | 534 | //! Rotation by the Z,Y,X rule. 535 | AffineTransformMatrix AffineTransformMatrix::RotateXYZ(double const& x, 536 | double const& y, double const& z) 537 | { 538 | AffineTransformMatrix a; 539 | 540 | 541 | //Axiom code: 542 | // Rx := matrix[[1,0,0,0],[0,cox,-six,0],[0,six,cox,0],[0,0,0,1]] 543 | // Ry := matrix[[coy,0,siy,0],[0,1,0,0],[-siy,0,coy,0],[0,0,0,1]] 544 | // Rz := matrix[[coz,-siz,0,0],[siz,coz,0,0],[0,0,1,0],[0,0,0,1]] 545 | // Rz*Ry*Rx 546 | 547 | double six = sin(x); 548 | double siy = sin(y); 549 | double siz = sin(z); 550 | double cox = cos(x); 551 | double coy = cos(y); 552 | double coz = cos(z); 553 | 554 | a.a[0] = coy * coz; 555 | a.a[1] = coy * siz; 556 | a.a[2] = -siy; 557 | 558 | a.a[4] = -cox * siz + coz * six * siy; 559 | a.a[5] = six * siy * siz + cox * coz; 560 | a.a[6] = coy * six; 561 | 562 | a.a[8] = six * siz + cox * coz * siy; 563 | a.a[9] = cox * siy * siz - coz * six; 564 | a.a[10] = cox * coy; 565 | 566 | return a; 567 | } 568 | 569 | /*!\brief An interwoven rotation. 570 | * 571 | * Generates a rotation matrix around x,y,z. 572 | * In this case the rotations are interwoven: 573 | * 574 | * Every rotation (around x, around y and around z) is done 575 | * in infinitesimal small steps. On step around x, one step around y, ... 576 | * 577 | * This results in a rotation as expected from a 6 DOF controller. 578 | */ 579 | AffineTransformMatrix AffineTransformMatrix::RotateInterwoven(double const& x, 580 | double const& y, double const& z) 581 | { 582 | double alpha = sqrt(x * x + y * y + z * z); 583 | if(alpha == 0) return AffineTransformMatrix::Identity(); 584 | Vector3 R; 585 | R.Set(x / alpha, y / alpha, z / alpha); 586 | return AffineTransformMatrix::RotateAroundVector(R, alpha); 587 | } 588 | 589 | //TODO: Program this: RotateTrackball(x1,y1,x2,y2,r) 590 | // r1= (0,0,r )-(x1,y1,0) 591 | // r2= (0,0,r )-(x2,y2,0) 592 | // P1 = SphereIntersect(r1,C,r); 593 | // P2 = SphereIntersect(r2,C,r); 594 | // V1 = (P1-C) 595 | // V2 = (P2-C) 596 | // V1.Normalize(); 597 | // V2.Normalize(); 598 | // A = V1xV2; 599 | // alpha = arcsin(abs(A)); 600 | // if(V1*V2 <0)alpha+=M_PI/2; 601 | // return RotateAroundVector(A,alpha); 602 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/AffineTransformMatrix.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : AffineTransformMatrix.h 3 | // Purpose : A class to store a 3D affine transform matrix and provide operations upon. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : -lm 7 | // Author : Tobias Schaefer 8 | // Created : 22.07.2009 9 | // Copyright : (C) 2009 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-05-04 01:09:07 +0200 (Di, 04 Mai 2010) $ 26 | //$Revision: 43 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #ifndef AFFINETRANSFORMMATRIX_H_ 31 | #define AFFINETRANSFORMMATRIX_H_ 32 | 33 | /** \class AffineTransformMatrix 34 | * \code #include "AffineTransformMatrix.h"\endcode 35 | * \brief A class to store a 3D affine transform matrix and provide operations upon. 36 | * 37 | * This class stores and manages a 4x4 matrix. This matrix is organized the same way, 38 | * the transformation matrices of OpenGL are: 39 | * 40 | * R11 R12 R13 Tx\n 41 | * R21 R22 R23 Ty\n 42 | * R31 R32 R33 Tz\n 43 | * 0 0 0 1\n 44 | * 45 | * Where R is responsible for rotation and scaling 46 | * and T for translation. 47 | * The vector \c a is organized as follows: 48 | * 49 | * 0 4 8 12\n 50 | * 1 5 9 13\n 51 | * 2 6 10 14\n 52 | * 3 7 11 15\n 53 | * 54 | * Right handed coordinate system:\n 55 | * X to the right of the screen\n 56 | * Y to the top of the screen\n 57 | * Z towards the viewer\n 58 | * 59 | */ 60 | 61 | // http://www.parashift.com/c++-faq-lite/operator-overloading.html 62 | 63 | 64 | #include 65 | #include 66 | #include "Vector3.h" 67 | 68 | class AffineTransformMatrix { 69 | // Constructor / Destructor 70 | public: 71 | AffineTransformMatrix(); 72 | virtual ~AffineTransformMatrix(); 73 | 74 | // Member variables 75 | public: 76 | double a[16]; //!< The transformation matrix. 77 | 78 | double rx, ry, rz; //!< Rotation after taking the matrix apart. 79 | double tx, ty, tz; //!< Translation after taking the matrix apart. 80 | double sx, sy, sz; //!< Scaling after taking the matrix apart. 81 | 82 | bool linkScaling; //!< Force uniform scaling. 83 | 84 | // Methods 85 | public: 86 | 87 | void TakeMatrixApart(void); 88 | void PutMatrixTogether(void); 89 | 90 | wxString ToString(); 91 | void FromString(wxString const& string); 92 | 93 | AffineTransformMatrix& operator=(const AffineTransformMatrix &b); 94 | void Set(AffineTransformMatrix const& b); 95 | 96 | AffineTransformMatrix & operator*=(const AffineTransformMatrix &b); 97 | const AffineTransformMatrix operator*(const AffineTransformMatrix &b) const; 98 | 99 | AffineTransformMatrix & operator/=(const AffineTransformMatrix &b); 100 | const AffineTransformMatrix operator/(const AffineTransformMatrix &b) const; 101 | 102 | Vector3 GetCenter(void) const; 103 | 104 | void SetIdentity(); 105 | static AffineTransformMatrix Identity(); 106 | 107 | const AffineTransformMatrix Inverse() const; 108 | 109 | static AffineTransformMatrix RotateAroundVector(Vector3 const& vector, 110 | double const& phi); 111 | static AffineTransformMatrix RotateInterwoven(double const& x, 112 | double const& y, double const& z); 113 | static AffineTransformMatrix RotateXY(int const& x, int const& y, 114 | double const& scale); 115 | static AffineTransformMatrix RotateXYZ(double const& x, double const& y, 116 | double const& z); 117 | 118 | void TranslateGlobal(double const& x, double const& y, double const& z); 119 | void TranslateLocal(double const& x, double const& y, double const& z); 120 | 121 | void ScaleGlobal(double const& x, double const& y, double const& z); 122 | 123 | Vector3 Transform(Vector3 const& v) const; 124 | Vector3 TransformNoShift(Vector3 const& v) const; 125 | 126 | }; 127 | 128 | WX_DECLARE_OBJARRAY(AffineTransformMatrix, ArrayOfAffineTransformMatrix) 129 | ; 130 | 131 | #endif /* AFFINETRANSFORMMATRIX_H_ */ 132 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | aux_source_directory(. files) 2 | add_library(3D ${files}) 3 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/FileDXF.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : FileDXF.cpp 3 | // Purpose : Reads a DXF File. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 07.08.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | #include "FileDXF.h" 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | 39 | FileDXF::FileDXF() 40 | { 41 | state = idle; 42 | } 43 | 44 | FileDXF::~FileDXF() 45 | { 46 | 47 | } 48 | 49 | void FileDXF::ProcessCode(long codeNr, wxString code) 50 | { 51 | char text[20]; 52 | strcpy(text, code.To8BitData()); 53 | 54 | 55 | // This line converts the english '.' in numbers into the german ','. Argl! 56 | code.Replace(_T("."), _T(",")); 57 | 58 | 59 | // Fill in data 60 | 61 | switch(codeNr){ 62 | case 2: 63 | blockName = code; 64 | break; 65 | case 3: 66 | objectName = code; 67 | break; 68 | case 70: 69 | code.ToLong(&objectFlag); 70 | break; 71 | } 72 | 73 | if(objectType.Cmp(_T("INSERT")) == 0){ 74 | switch(codeNr){ 75 | case 10: 76 | code.ToDouble(&x); 77 | break; 78 | case 20: 79 | code.ToDouble(&y); 80 | break; 81 | case 30: 82 | code.ToDouble(&z); 83 | break; 84 | case 41: 85 | code.ToDouble(&sx); 86 | break; 87 | case 42: 88 | code.ToDouble(&sy); 89 | break; 90 | case 43: 91 | code.ToDouble(&sz); 92 | break; 93 | } 94 | } 95 | 96 | if(objectType.Cmp(_T("VERTEX")) == 0){ 97 | switch(codeNr){ 98 | case 10: 99 | code.ToDouble(&x); 100 | break; 101 | case 20: 102 | code.ToDouble(&y); 103 | break; 104 | case 30: 105 | code.ToDouble(&z); 106 | break; 107 | case 71: 108 | code.ToLong(&v0); 109 | break; 110 | case 72: 111 | code.ToLong(&v1); 112 | break; 113 | case 73: 114 | code.ToLong(&v2); 115 | break; 116 | case 74: 117 | code.ToLong(&v3); 118 | break; 119 | } 120 | } 121 | 122 | if(codeNr == 0){ 123 | // Generate Objects and such 124 | 125 | if(objectType.Cmp(_T("BLOCK")) == 0){ 126 | v.Empty(); 127 | Geometry* g = new Geometry(); 128 | g->matrix.TranslateGlobal(x, y, z); 129 | g->objectName = blockName; 130 | geometry.Add(g); 131 | lastGeometry = geometry.Count() - 1; 132 | } 133 | if(objectType.Cmp(_T("VERTEX")) == 0){ 134 | if(objectFlag == 192){ 135 | Vector3 vector(x, y, z); 136 | v.Add(vector); 137 | } 138 | if(objectFlag == 128){ 139 | if(lastGeometry >= 0){ 140 | if(v0 > 0 && v1 > 0 && v2 > 0 && v3 < 0){ 141 | geometry[lastGeometry].AddTriangle(v[v0 - 1], 142 | v[v1 - 1], v[v2 - 1]); 143 | } 144 | if(v0 > 0 && v1 > 0 && v2 > 0 && v3 > 0) 145 | 146 | { 147 | geometry[lastGeometry].AddQuad(v[v0 - 1], v[v1 - 1], 148 | v[v2 - 1], v[v3 - 1]); 149 | } 150 | } 151 | } 152 | } 153 | 154 | if(objectType.Cmp(_T("INSERT")) == 0){ 155 | size_t i; 156 | for(i = 0; i < geometry.GetCount(); i++){ 157 | if(geometry[i].objectName.Cmp(blockName) == 0){ 158 | geometry[i].matrix.ScaleGlobal(sx, sy, sz); 159 | geometry[i].matrix.TranslateGlobal(x, y, z); 160 | } 161 | } 162 | } 163 | 164 | objectName.Empty(); 165 | x = y = z = 0.0; 166 | sx = sy = sz = 1.0; 167 | v0 = v1 = v2 = v3 = -1; 168 | objectType = code; 169 | 170 | switch(state){ 171 | case idle: 172 | if(code.Cmp(_T("SECTION")) == 0){ 173 | state = inSection; 174 | break; 175 | } 176 | break; 177 | case inSection: 178 | if(code.Cmp(_T("ENDSEC")) == 0){ 179 | state = idle; 180 | break; 181 | } 182 | if(code.Cmp(_T("BLOCK")) == 0){ 183 | state = inBlock; 184 | break; 185 | } 186 | if(code.Cmp(_T("ENTITIES")) == 0){ 187 | state = inEntities; 188 | break; 189 | } 190 | break; 191 | case inBlock: 192 | if(code.Cmp(_T("ENDBLK")) == 0){ 193 | state = idle; 194 | break; 195 | } 196 | // no break here! 197 | case inEntities: 198 | if(code.Cmp(_T("ENDSEC")) == 0){ 199 | state = idle; 200 | break; 201 | } 202 | break; 203 | } 204 | } 205 | } 206 | 207 | bool FileDXF::ReadFile(wxString fileName) 208 | { 209 | wxTextFile file; 210 | 211 | wxLogMessage(wxString::Format(_T("Opening File:") + fileName)); 212 | 213 | if(!file.Open(fileName)){ 214 | wxLogError(_T("STL: Can't open ") + fileName + _T("!")); 215 | return false; 216 | } 217 | 218 | wxString temp; 219 | long codeNumber; 220 | 221 | state = idle; 222 | 223 | temp = file.GetFirstLine(); 224 | do{ 225 | temp.ToLong(&codeNumber); 226 | temp = file.GetNextLine(); 227 | ProcessCode(codeNumber, temp); 228 | temp = file.GetNextLine(); 229 | }while(!file.Eof()); 230 | file.Close(); 231 | 232 | 233 | // Calculate normals to get the lighting right. 234 | size_t i; 235 | for(i = 0; i < geometry.GetCount(); i++){ 236 | 237 | } 238 | return true; 239 | } 240 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/FileDXF.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : FileDXF.h 3 | // Purpose : Reads a DXF File. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 07.08.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #ifndef FILEDXF_H_ 31 | #define FILEDXF_H_ 32 | 33 | /*!\class FileDXF 34 | * \brief Reads a DXF file 35 | * 36 | * ... 37 | */ 38 | 39 | #include "GeometryFileAbstract.h" 40 | #include 41 | 42 | class FileDXF:public GeometryFileAbstract { 43 | // Constructor/ Destructor 44 | public: 45 | FileDXF(); 46 | virtual ~FileDXF(); 47 | 48 | // Member variables 49 | public: 50 | 51 | private: 52 | enum StateType { 53 | idle = 0, inSection, inBlock, inEntities 54 | }; 55 | StateType state; 56 | 57 | wxString blockName; 58 | wxString objectName; 59 | wxString objectType; 60 | long objectFlag; 61 | double x, y, z; 62 | double sx, sy, sz; 63 | long v0, v1, v2, v3; 64 | long lastGeometry; 65 | ArrayOfVector3 v; 66 | 67 | //Methods: 68 | public: 69 | bool ReadFile(wxString fileName); 70 | private: 71 | void ProcessCode(long codeNr, wxString code); 72 | }; 73 | 74 | #endif /* FILEDXF_H_ */ 75 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/Geometry.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : Geometry.cpp 3 | // Purpose : Class for managing 3D geometry data. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer, Samy Kamkar 8 | // Updated : 2020/02/20 9 | // Created : 28.02.2010 10 | // Copyright : (C) 2010 Tobias Schaefer 11 | // Licence : GNU General Public License version 3.0 (GPLv3) 12 | // 13 | // This program is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published by 15 | // the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This program is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | // 26 | //$LastChangedDate: 2010-06-12 17:59:21 +0200 (Sa, 12 Jun 2010) $ 27 | //$Revision: 49 $ 28 | //$LastChangedBy: tobiassch $ 29 | /////////////////////////////////////////////////////////////////////////////// 30 | 31 | 32 | #include "Geometry.h" 33 | 34 | #if defined(__APPLE__) 35 | #include 36 | #else 37 | #include 38 | #endif 39 | 40 | #include 41 | 42 | #include // this is a magic incantation which must be done! 43 | WX_DEFINE_OBJARRAY(ArrayOfGeometry) 44 | 45 | Geometry::Geometry() 46 | { 47 | visible = true; 48 | color.Set(0.8, 0.8, 0.8); 49 | } 50 | Geometry::~Geometry() 51 | { 52 | } 53 | 54 | void Geometry::Clear(void) 55 | { 56 | triangles.Clear(); 57 | } 58 | 59 | void Geometry::CopyFrom(const Geometry &geometry) 60 | { 61 | Clear(); 62 | CopyTrianglesFrom(geometry); 63 | this->matrix = geometry.matrix; 64 | this->objectName = geometry.objectName; 65 | this->visible = geometry.visible; 66 | this->color = geometry.color; 67 | } 68 | 69 | void Geometry::CopyTrianglesFrom(const Geometry &geometry) 70 | { 71 | size_t i; 72 | Triangle temp; 73 | for(i = 0; i < geometry.triangles.GetCount(); i++){ 74 | temp = geometry.triangles[i]; 75 | this->triangles.Add(temp); 76 | } 77 | } 78 | 79 | void Geometry::ApplyTransformation(const AffineTransformMatrix &matrix) 80 | { 81 | size_t i; 82 | for(i = 0; i < triangles.Count(); i++){ 83 | triangles[i].ApplyTransformation(matrix); 84 | // triangles[i].p[0] = matrix.Transform(triangles[i].p[0]); 85 | // triangles[i].p[1] = matrix.Transform(triangles[i].p[1]); 86 | // triangles[i].p[2] = matrix.Transform(triangles[i].p[2]); 87 | // triangles[i].n[0] = matrix.TransformNoShift(triangles[i].n[0]); 88 | // triangles[i].n[1] = matrix.TransformNoShift(triangles[i].n[1]); 89 | // triangles[i].n[2] = matrix.TransformNoShift(triangles[i].n[2]); 90 | } 91 | } 92 | 93 | void Geometry::ApplyTransformation(void) 94 | { 95 | size_t i; 96 | for(i = 0; i < triangles.Count(); i++) 97 | triangles[i].ApplyTransformation(this->matrix); 98 | } 99 | 100 | void Geometry::Paint(void) const 101 | { 102 | if(!visible) return; 103 | size_t i; 104 | 105 | 106 | // GL_RESCALE_NORMAL is faster, but doesn't work on non-uniform scaled models 107 | // GL_NORMALIZE is slower, but works always 108 | // ... and there seems to be a problem under Windows with OpenGL 1.1... 109 | 110 | #if defined __WIN32__ 111 | ::glEnable(GL_NORMALIZE); 112 | #else 113 | ::glEnable(GL_RESCALE_NORMAL); 114 | #endif 115 | 116 | ::glPushMatrix(); 117 | ::glMultMatrixd(matrix.a); 118 | 119 | ::glBegin(GL_TRIANGLES); 120 | ::glColor3f(color.x, color.y, color.z); 121 | for(i = 0; i < triangles.Count(); i++){ 122 | triangles[i].Paint(); 123 | } 124 | ::glEnd(); 125 | ::glPopMatrix(); 126 | #if defined (__WIN32__) 127 | ::glDisable(GL_NORMALIZE); 128 | #else 129 | ::glDisable(GL_RESCALE_NORMAL); 130 | #endif 131 | } 132 | 133 | void Geometry::AddTriangle(const Vector3 &a, const Vector3 &b, const Vector3 &c) 134 | { 135 | Triangle* tri = new Triangle; 136 | tri->p[0] = a; 137 | tri->p[1] = b; 138 | tri->p[2] = c; 139 | tri->CalculateNormal(); 140 | triangles.Add(tri); 141 | } 142 | 143 | void Geometry::AddTriangleWithNormals(const Vector3 &a, const Vector3 &b, 144 | const Vector3 &c, const Vector3 &na, const Vector3 &nb, 145 | const Vector3 &nc) 146 | { 147 | Triangle* tri = new Triangle; 148 | tri->p[0] = a; 149 | tri->p[1] = b; 150 | tri->p[2] = c; 151 | tri->n[0] = na; 152 | tri->n[1] = nb; 153 | tri->n[2] = nc; 154 | triangles.Add(tri); 155 | } 156 | 157 | void Geometry::AddTriangleTransform(const Vector3 &a, const Vector3 &b, 158 | const Vector3 &c, const AffineTransformMatrix &transformMatrix) 159 | { 160 | Triangle* tri = new Triangle; 161 | tri->p[0] = transformMatrix.Transform(a); 162 | tri->p[1] = transformMatrix.Transform(b); 163 | tri->p[2] = transformMatrix.Transform(c); 164 | tri->CalculateNormal(); 165 | triangles.Add(tri); 166 | } 167 | 168 | void Geometry::AddQuad(const Vector3 &a, const Vector3 &b, const Vector3 &c, 169 | const Vector3 &d) 170 | { 171 | Triangle* tri0 = new Triangle; 172 | Triangle* tri1 = new Triangle; 173 | tri0->p[0] = a; 174 | tri0->p[1] = b; 175 | tri0->p[2] = c; 176 | tri1->p[0] = tri0->p[2]; 177 | tri1->p[1] = d; 178 | tri1->p[2] = tri0->p[0]; 179 | tri0->CalculateNormal(); 180 | tri1->n[0] = tri0->n[0]; 181 | tri1->n[1] = tri0->n[1]; 182 | tri1->n[2] = tri0->n[2]; 183 | triangles.Add(tri0); 184 | triangles.Add(tri1); 185 | } 186 | 187 | void Geometry::AddQuadTransform(const Vector3 &a, const Vector3 &b, 188 | const Vector3 &c, const Vector3 &d, 189 | const AffineTransformMatrix &transformMatrix) 190 | { 191 | Triangle* tri0 = new Triangle; 192 | Triangle* tri1 = new Triangle; 193 | tri0->p[0] = transformMatrix.Transform(a); 194 | tri0->p[1] = transformMatrix.Transform(b); 195 | tri0->p[2] = transformMatrix.Transform(c); 196 | tri1->p[0] = tri0->p[2]; 197 | tri1->p[1] = transformMatrix.Transform(d); 198 | tri1->p[2] = tri0->p[0]; 199 | tri0->CalculateNormal(); 200 | tri1->n[0] = tri0->n[0]; 201 | tri1->n[1] = tri0->n[1]; 202 | tri1->n[2] = tri0->n[2]; 203 | triangles.Add(tri0); 204 | triangles.Add(tri1); 205 | } 206 | 207 | void Geometry::CalculateNormals(void) 208 | { 209 | size_t i; 210 | for(i = 0; i < triangles.GetCount(); i++){ 211 | triangles[i].CalculateNormal(); 212 | } 213 | } 214 | 215 | void Geometry::FlipNormals(void) 216 | { 217 | size_t i; 218 | for(i = 0; i < triangles.GetCount(); i++){ 219 | triangles[i].n[0] *= -1; 220 | triangles[i].n[1] *= -1; 221 | triangles[i].n[2] *= -1; 222 | } 223 | } 224 | 225 | void Geometry::ToXml(wxXmlNode* parentNode) 226 | { 227 | wxXmlNode *temp, *temp2; 228 | wxXmlNode *nodeObject = NULL; 229 | 230 | 231 | // Find out, if object already exists in XML tree. 232 | temp = parentNode->GetChildren(); 233 | while(temp != NULL && nodeObject == NULL){ 234 | if(temp->GetName() == _T("geometry") && temp->GetPropVal(_T("name"), 235 | _T("")) == objectName) nodeObject = temp; 236 | temp = temp->GetNext(); 237 | } 238 | if(nodeObject == NULL){ 239 | nodeObject = new wxXmlNode(wxXML_ELEMENT_NODE, _T("geometry")); 240 | nodeObject->AddProperty(_T("name"), objectName); 241 | parentNode->InsertChild(nodeObject, NULL); 242 | } 243 | 244 | // Remove the subelements, that will be updated 245 | temp = nodeObject->GetChildren(); 246 | while(temp != NULL){ 247 | temp2 = NULL; 248 | if(temp->GetName() == _T("matrix")) temp2 = temp; 249 | if(temp->GetName() == _T("tri")) temp2 = temp; 250 | temp = temp->GetNext(); 251 | if(temp2 != NULL){ 252 | nodeObject->RemoveChild(temp2); 253 | delete (temp2); 254 | } 255 | } 256 | 257 | // Insert new matrix 258 | temp = new wxXmlNode(wxXML_ELEMENT_NODE, _T("matrix")); 259 | nodeObject->InsertChild(temp, NULL); 260 | temp2 = new wxXmlNode(wxXML_CDATA_SECTION_NODE, wxEmptyString, 261 | matrix.ToString()); 262 | temp->InsertChild(temp2, NULL); 263 | 264 | 265 | // Insert new triangles 266 | size_t i; 267 | for(i = 0; i < triangles.GetCount(); i++){ 268 | temp = new wxXmlNode(wxXML_ELEMENT_NODE, _T("tri")); 269 | nodeObject->InsertChild(temp, NULL); 270 | temp2 = new wxXmlNode(wxXML_CDATA_SECTION_NODE, wxEmptyString, 271 | triangles[i].ToString()); 272 | temp->InsertChild(temp2, NULL); 273 | } 274 | } 275 | 276 | bool Geometry::FromXml(wxXmlNode* node) 277 | { 278 | if(node->GetName() != _T("geometry")) return false; 279 | objectName = node->GetPropVal(_T("name"), _T("")); 280 | wxXmlNode *temp = node->GetChildren(); 281 | 282 | triangles.Empty(); 283 | Triangle* tri; 284 | 285 | while(temp != NULL){ 286 | if(temp->GetName() == _T("tri")){ 287 | tri = new Triangle(temp->GetNodeContent()); 288 | // if(triangles.GetCount() < 20) wxLogMessage( 289 | // _T("Geometry::FromXml: Tri from >") 290 | // + temp->GetNodeContent() + _T("<.")); 291 | 292 | triangles.Add(tri); 293 | } 294 | if(temp->GetName() == _T("matrix")){ 295 | matrix.FromString(temp->GetNodeContent()); 296 | // wxLogMessage(_T("Geometry::FromXml: Matrix from >") 297 | // + temp->GetNodeContent() + _T("<.")); 298 | } 299 | temp = temp->GetNext(); 300 | } 301 | return true; 302 | } 303 | 304 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/Geometry.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : Geometry.h 3 | // Purpose : Class for managing 3D geometry data. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 28.02.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-06-12 17:59:21 +0200 (Sa, 12 Jun 2010) $ 26 | //$Revision: 49 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | #ifndef GEOMETRY_H_ 32 | #define GEOMETRY_H_ 33 | 34 | #include "Vector3.h" 35 | #include "Triangle.h" 36 | #include "AffineTransformMatrix.h" 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | /*!\class Geometry 43 | * \brief Contains geometric data. 44 | * 45 | * Geometric data is stored in this class. 46 | */ 47 | class Geometry { 48 | // Constructor/ Destructor 49 | public: 50 | Geometry(); 51 | virtual ~Geometry(); 52 | 53 | // Member variables 54 | public: 55 | wxString objectName; 56 | Vector3 color; 57 | bool visible; 58 | 59 | AffineTransformMatrix matrix; //!< Transformation of the data. 60 | ArrayOfTriangle triangles; //!< The storage of the geometric data. 61 | 62 | // Methods 63 | public: 64 | void ToXml(wxXmlNode* parentNode); 65 | bool FromXml(wxXmlNode* node); 66 | 67 | void Paint(void) const; 68 | 69 | void Clear(void); 70 | void CopyFrom(const Geometry &geometry); 71 | void CopyTrianglesFrom(const Geometry &geometry); 72 | 73 | void CalculateNormals(void); 74 | void FlipNormals(void); 75 | 76 | void ApplyTransformation(const AffineTransformMatrix &matrix); 77 | void ApplyTransformation(void); 78 | 79 | 80 | void AddTriangle(const Vector3 &a, const Vector3 &b, const Vector3 &c); 81 | void AddTriangleTransform(const Vector3 &a, const Vector3 &b, 82 | const Vector3 &c, const AffineTransformMatrix &transformMatrix); 83 | void AddTriangleWithNormals(const Vector3 &a, const Vector3 &b, 84 | const Vector3 &c, const Vector3 &na, const Vector3 &nb, 85 | const Vector3 &nc); 86 | 87 | void AddQuad(const Vector3 &a, const Vector3 &b, const Vector3 &c, 88 | const Vector3 &d); 89 | void AddQuadTransform(const Vector3 &a, const Vector3 &b, const Vector3 &c, 90 | const Vector3 &d, const AffineTransformMatrix &transformMatrix); 91 | }; 92 | WX_DECLARE_OBJARRAY(Geometry, ArrayOfGeometry) 93 | ; 94 | 95 | #endif /* GEOMETRY_H_ */ 96 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/GeometryFileAbstract.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : GeometryFileAbstract.cpp 3 | // Purpose : Abstract class for geometry loaded from a file. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Updated : 2020/02/20 9 | // Created : 11.06.2011 10 | // Copyright : (C) 2011 Tobias Schaefer 11 | // Licence : GNU General Public License version 3.0 (GPLv3) 12 | // 13 | // This program is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published by 15 | // the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This program is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | // 26 | //$LastChangedDate: $ 27 | //$Revision: $ 28 | //$LastChangedBy: $ 29 | /////////////////////////////////////////////////////////////////////////////// 30 | 31 | 32 | #include "GeometryFileAbstract.h" 33 | 34 | #if defined(__APPLE__) 35 | #include 36 | #else 37 | #include 38 | #endif 39 | 40 | GeometryFileAbstract::GeometryFileAbstract() 41 | { 42 | } 43 | 44 | GeometryFileAbstract::~GeometryFileAbstract() 45 | { 46 | } 47 | 48 | 49 | void GeometryFileAbstract::Paint(void) const 50 | { 51 | size_t i; 52 | ::glPushMatrix(); 53 | ::glMultMatrixd(matrix.a); 54 | for(i = 0; i < geometry.Count(); i++){ 55 | geometry[i].Paint(); 56 | } 57 | ::glPopMatrix(); 58 | } 59 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/GeometryFileAbstract.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : GeometryFileAbstract.h 3 | // Purpose : Abstract class for geometry loaded from a file. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 11.06.2011 9 | // Copyright : (C) 2011 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | #ifndef GEOMETRYFILEABSTRACT_H_ 32 | #define GEOMETRYFILEABSTRACT_H_ 33 | 34 | #include "Geometry.h" 35 | 36 | #include 37 | 38 | /*!\class GeometryFileAbstract 39 | * \brief Abstract class for geometry loaded from a file. 40 | */ 41 | 42 | class GeometryFileAbstract { 43 | // Constructor/ Destructor 44 | public: 45 | GeometryFileAbstract(); 46 | virtual ~GeometryFileAbstract(); 47 | 48 | // Member variables 49 | public: 50 | AffineTransformMatrix matrix; //!< Transformation of the data. 51 | ArrayOfGeometry geometry; 52 | 53 | //Methods: 54 | public: 55 | void Paint(void) const; 56 | virtual bool ReadFile(wxString fileName) = 0; 57 | }; 58 | 59 | #endif /* GEOMETRYFILEABSTRACT_H_ */ 60 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/Triangle.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : Triangle.cpp 3 | // Purpose : 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer, Samy Kamkar 8 | // Updated : 2020/02/20 9 | // Created : 11.06.2011 10 | // Copyright : (C) 2011 Tobias Schaefer 11 | // Licence : GNU General Public License version 3.0 (GPLv3) 12 | // 13 | // This program is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published by 15 | // the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This program is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | // 26 | //$LastChangedDate: $ 27 | //$Revision: $ 28 | //$LastChangedBy: $ 29 | /////////////////////////////////////////////////////////////////////////////// 30 | 31 | #include "Triangle.h" 32 | 33 | #if defined(__APPLE__) 34 | #include 35 | #else 36 | #include 37 | #endif 38 | 39 | #include 40 | #include // this is a magic incantation which must be done! 41 | WX_DEFINE_OBJARRAY(ArrayOfTriangle) 42 | 43 | Triangle::Triangle() 44 | { 45 | } 46 | Triangle::Triangle(wxString string) 47 | { 48 | this->FromString(string); 49 | } 50 | 51 | Triangle::~Triangle() 52 | { 53 | } 54 | 55 | wxString Triangle::ToString(void) const 56 | { 57 | wxString temp; 58 | temp = p[0].ToString() + _T(";"); 59 | temp += p[1].ToString() + _T(";"); 60 | temp += p[2].ToString() + _T(";"); 61 | temp += n[0].ToString() + _T(";"); 62 | temp += n[1].ToString() + _T(";"); 63 | temp += n[2].ToString() + _T(";"); 64 | temp += c[0].ToString() + _T(";"); 65 | temp += c[1].ToString() + _T(";"); 66 | temp += c[2].ToString(); 67 | return temp; 68 | } 69 | 70 | void Triangle::FromString(wxString const &string) 71 | { 72 | wxStringTokenizer tkz(string, wxT(";")); 73 | while(tkz.HasMoreTokens()){ 74 | wxString token = tkz.GetNextToken(); 75 | switch(tkz.CountTokens()){ 76 | case 8: 77 | p[0].FromString(token); 78 | break; 79 | case 7: 80 | p[1].FromString(token); 81 | break; 82 | case 6: 83 | p[2].FromString(token); 84 | break; 85 | case 5: 86 | n[0].FromString(token); 87 | break; 88 | case 4: 89 | n[1].FromString(token); 90 | break; 91 | case 3: 92 | n[2].FromString(token); 93 | break; 94 | case 2: 95 | c[0].FromString(token); 96 | break; 97 | case 1: 98 | c[1].FromString(token); 99 | break; 100 | case 0: 101 | c[2].FromString(token); 102 | break; 103 | } 104 | } 105 | } 106 | 107 | /*!\brief Puts a triangle in the OpenGL queue. 108 | * 109 | * This function does not call glBegin(GL_TRIANGLES); and 110 | * glEnd();. This has to be done by the calling function. 111 | * (Allows to save on OpenGL calls.) 112 | */ 113 | void Triangle::Paint(bool useNormals, bool useColors) const 114 | { 115 | unsigned char i; 116 | for(i = 0; i < 3; i++){ 117 | if(useNormals) ::glNormal3f(n[i].x, n[i].y, n[i].z); 118 | if(useColors) ::glColor3f(c[i].x, c[i].y, c[i].z); 119 | ::glVertex3f(p[i].x, p[i].y, p[i].z); 120 | } 121 | } 122 | /*!\brief Calculates normals for the corners of a triangle. 123 | * 124 | * If no normals can be provided from elsewhere, this function 125 | * can generate a set. The normal vectors n[0] to n[2] are all 126 | * set normal to the plane of the triangle. Orientation is 127 | * right handed. 128 | */ 129 | void Triangle::CalculateNormal() 130 | { 131 | n[0] = (p[1] - p[0]) * (p[2] - p[1]); 132 | n[0].Normalize(); 133 | n[1] = n[0]; 134 | n[2] = n[0]; 135 | } 136 | 137 | void Triangle::ApplyTransformation(const AffineTransformMatrix &matrix) 138 | { 139 | p[0] = matrix.Transform(p[0]); 140 | p[1] = matrix.Transform(p[1]); 141 | p[2] = matrix.Transform(p[2]); 142 | n[0] = matrix.TransformNoShift(n[0]); 143 | n[1] = matrix.TransformNoShift(n[1]); 144 | n[2] = matrix.TransformNoShift(n[2]); 145 | } 146 | 147 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/Triangle.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : Triangle.h 3 | // Purpose : 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 11.06.2011 9 | // Copyright : (C) 2011 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | #ifndef TRIANGLE_H_ 32 | #define TRIANGLE_H_ 33 | 34 | #include "Vector3.h" 35 | #include "AffineTransformMatrix.h" 36 | #include 37 | #include 38 | /*!\class Triangle 39 | * \brief Defines a simple triangle. 40 | * 41 | * Holds the data for a simple triangle. Three vertices with three normal vectors. 42 | */ 43 | 44 | class Triangle { 45 | // Constructor/Destructor: 46 | public: 47 | Triangle(); 48 | Triangle(wxString string); 49 | virtual ~Triangle(); 50 | //Member variables: 51 | Vector3 p[3]; //!< Position of vertices. 52 | Vector3 n[3]; //!< Normal vectors. 53 | Vector3 c[3]; //!< Color vectors. 54 | 55 | //Methods: 56 | wxString ToString(void) const; 57 | void FromString(wxString const &string); 58 | 59 | void Paint(bool useNormals = true, bool useColors = false) const; 60 | void CalculateNormal(); 61 | void ApplyTransformation(const AffineTransformMatrix &matrix); 62 | 63 | }; 64 | WX_DECLARE_OBJARRAY(Triangle, ArrayOfTriangle) 65 | ; 66 | 67 | #endif /* TRIANGLE_H_ */ 68 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/Vector3.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : Vector3.cpp 3 | // Purpose : A 3D vector class with support functions. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : -lm 7 | // Author : Tobias Schaefer 8 | // Created : 28.01.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-05-22 01:40:18 +0200 (Sa, 22 Mai 2010) $ 26 | //$Revision: 45 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | #include "Vector3.h" 32 | 33 | #include 34 | #include // this is a magic incantation which must be done! 35 | WX_DEFINE_OBJARRAY(ArrayOfVector3) 36 | 37 | wxString Vector3::ToString(void) const 38 | { 39 | return wxString::Format(_T("%f#%f#%f"), x, y, z); 40 | } 41 | 42 | void Vector3::FromString(wxString const& string) 43 | { 44 | wxStringTokenizer tkz(string, wxT("#")); 45 | double temp; 46 | while(tkz.HasMoreTokens()){ 47 | wxString token = tkz.GetNextToken(); 48 | token.ToDouble(&temp); 49 | switch(tkz.CountTokens()){ 50 | case 2: 51 | x = temp; 52 | break; 53 | case 1: 54 | y = temp; 55 | break; 56 | case 0: 57 | z = temp; 58 | break; 59 | } 60 | } 61 | } 62 | 63 | float Vector3::Abs(void) 64 | { 65 | return sqrt(x * x + y * y + z * z); 66 | } 67 | 68 | void Vector3::Zero(void) 69 | { 70 | x = y = z = 0.0; 71 | } 72 | 73 | void Vector3::Swap(Vector3& b) 74 | { 75 | //TODO: Rewrite to simpler version. 76 | float temp; 77 | temp = b.x; 78 | b.x = this->x; 79 | this->x = temp; 80 | 81 | temp = b.y; 82 | b.y = this->y; 83 | this->y = temp; 84 | 85 | temp = b.z; 86 | b.z = this->z; 87 | this->z = temp; 88 | } 89 | 90 | Vector3 Vector3::Normalize(void) 91 | { 92 | float d = Abs(); 93 | if(d > 0){ 94 | x /= d; 95 | y /= d; 96 | z /= d; 97 | } 98 | return Vector3(x, y, z); 99 | } 100 | -------------------------------------------------------------------------------- /ControlSoftware/src/3D/Vector3.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : Vector3.h 3 | // Purpose : A 3D vector class with support functions. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : -lm 7 | // Author : Tobias Schaefer 8 | // Created : 28.01.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-05-29 01:15:52 +0200 (Sa, 29 Mai 2010) $ 26 | //$Revision: 47 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | /*!\class Vector3 31 | * \brief Contains a vector in 3D space 32 | */ 33 | 34 | #ifndef _CVECTOR3_H_ 35 | #define _CVECTOR3_H_ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | class Vector3 { 42 | // Constructor/Destructor: 43 | public: 44 | Vector3(float px = 0.0, float py = 0.0, float pz = 0.0) : 45 | x(px), y(py), z(pz) 46 | { 47 | } 48 | Vector3(wxString string) 49 | { 50 | this->FromString(string); 51 | } 52 | 53 | ~Vector3(void){} 54 | 55 | // Member variables: 56 | public: 57 | float x; 58 | float y; 59 | float z; 60 | 61 | // Methods: 62 | public: 63 | wxString ToString(void) const; 64 | void FromString(wxString const& string); 65 | 66 | //!Calculate the absolut length of a vector. 67 | float Abs(); 68 | 69 | // void operator=(const Vector3& a){x=a.x;y=a.y;z=a.z;}; 70 | 71 | 72 | //! Overloaded operator for vector addition. 73 | Vector3 & operator+=(const Vector3 &a) 74 | { 75 | this->x += a.x; 76 | this->y += a.y; 77 | this->z += a.z; 78 | return *this; 79 | } 80 | 81 | 82 | //! Overloaded operator for vector addition. 83 | const Vector3 operator+(const Vector3& a) const 84 | { 85 | Vector3 temp = *this; 86 | temp += a; 87 | return temp; 88 | } 89 | 90 | 91 | //! Overloaded operator for vector subtraction. 92 | Vector3 & operator-=(const Vector3& a) 93 | { 94 | this->x -= a.x; 95 | this->y -= a.y; 96 | this->z -= a.z; 97 | return *this; 98 | } 99 | 100 | 101 | //! Overloaded operator for vector subtraction. 102 | const Vector3 operator-(const Vector3& a) const 103 | { 104 | Vector3 temp = *this; 105 | temp -= a; 106 | return temp; 107 | } 108 | 109 | 110 | //! Overloaded operator for vector negation. 111 | const Vector3 operator-() const 112 | { 113 | Vector3 temp(-this->x, -this->y, -this->z); 114 | return temp; 115 | } 116 | 117 | 118 | /*!\brief Overloaded operator for vector product. 119 | * 120 | * This function calculates the vector product 121 | * \f[ 122 | * \vec{c}=\left\{ 123 | * \begin{array}{c} 124 | * \vec{a}_y \cdot \vec{b}_z - \vec{a}_z \cdot \vec{b}_y \\ 125 | * \vec{a}_z \cdot \vec{b}_x - \vec{a}_x \cdot \vec{b}_z \\ 126 | * \vec{a}_x \cdot \vec{b}_y - \vec{a}_y \cdot \vec{b}_x 127 | * \end{array} 128 | * \right\} 129 | * \f]. 130 | */ 131 | //!Overloaded operator for vector product. 132 | Vector3 & operator*=(const Vector3& b) 133 | { 134 | Vector3 a = *(this); 135 | this->x = a.y * b.z - a.z * b.y; 136 | this->y = a.z * b.x - a.x * b.z; 137 | this->z = a.x * b.y - a.y * b.x; 138 | return *this; 139 | } 140 | 141 | 142 | //! Overloaded operator for scalar product. 143 | Vector3 & operator*=(const float &b) 144 | { 145 | this->x *= b; 146 | this->y *= b; 147 | this->z *= b; 148 | return *this; 149 | } 150 | 151 | const Vector3 operator*(const Vector3& b) const 152 | { 153 | Vector3 temp = *this; 154 | temp *= b; 155 | return temp; 156 | } 157 | 158 | 159 | //! Overloaded operator for scalar product. 160 | const Vector3 operator*(const float &b) const 161 | { 162 | Vector3 temp = *this; 163 | temp *= b; 164 | return temp; 165 | } 166 | 167 | 168 | //! Calculates the dot product (inner product) of two vectors. 169 | float Dot(const Vector3& b) 170 | { 171 | return (x * b.x + y * b.y + z * b.z); 172 | } 173 | 174 | 175 | //! Overloaded operator for scalar division. 176 | Vector3 & operator/=(const float &b) 177 | { 178 | this->x /= b; 179 | this->y /= b; 180 | this->z /= b; 181 | return *this; 182 | } 183 | 184 | 185 | //! Overloaded operator for scalar division. 186 | const Vector3 operator/(const float &b) const 187 | { 188 | Vector3 temp = *this; 189 | temp /= b; 190 | return temp; 191 | } 192 | 193 | 194 | //! Comparison operator. 195 | bool operator==(const Vector3 &b) const 196 | { 197 | double epsilon = 1e-5; 198 | double epsilon2 = epsilon * epsilon; 199 | return (((this->x - b.x) * (this->x - b.x) + (this->y - b.y) * (this->y 200 | - b.y) + (this->z - b.z) * (this->z - b.z)) <= epsilon2); 201 | } 202 | 203 | 204 | //! Comparison operator. 205 | bool operator!=(const Vector3 &b) const 206 | { 207 | return !(*this == b); 208 | } 209 | 210 | 211 | //! Zeros a vector. 212 | void Zero(void); 213 | 214 | //! Sets the vector to the given coordinates. 215 | void Set(float x, float y, float z) 216 | { 217 | this->x = x; 218 | this->y = y; 219 | this->z = z; 220 | } 221 | 222 | 223 | //! Swap the vector with a given vector. 224 | void Swap(Vector3& b); 225 | 226 | //! Normalizes the length of a vector. 227 | Vector3 Normalize(void); 228 | }; 229 | WX_DECLARE_OBJARRAY(Vector3, ArrayOfVector3) 230 | ; 231 | 232 | #endif // _CVECTOR3_H_ 233 | -------------------------------------------------------------------------------- /ControlSoftware/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(3D) 2 | add_subdirectory(gui) 3 | add_subdirectory(hardware) 4 | -------------------------------------------------------------------------------- /ControlSoftware/src/Config.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : Config.h 3 | // Purpose : Global configuration. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 21.02.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-05-22 01:40:18 +0200 (Sa, 22 Mai 2010) $ 26 | //$Revision: 45 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | /* Configuration file. Major switches that change the code 31 | * and the structure can be found here (_DEBUG_ for example). 32 | */ 33 | 34 | #ifndef CONFIG_H_ 35 | #define CONFIG_H_ 36 | 37 | #define _OPENRTMS_VERSION "0.2" 38 | #define _OPENRTMS_AUTHORS "Tobias Schaefer" 39 | #define _OPENRTMS_NAMEOFCONFIG "Open-rTMS" 40 | #define _OPENRTMS_FIRMWARE "firmware/firmware_openrtms_h09_20130202.binary" 41 | #define _DEBUGMODE true 42 | 43 | #endif /* CONFIG_H_ */ 44 | -------------------------------------------------------------------------------- /ControlSoftware/src/Open-rTMS.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : Open-rTMS.cpp 3 | // Purpose : Main entry point. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 21.02.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #include "Open-rTMS.h" 31 | #include "languages.h" 32 | #include "Config.h" 33 | 34 | #include 35 | 36 | #ifndef __WIN32__ 37 | #include "icon/logo.xpm" 38 | #endif 39 | 40 | // The line that starts it all. 41 | IMPLEMENT_APP(OpenrTMSApp) 42 | 43 | OpenrTMSApp::OpenrTMSApp() 44 | { 45 | 46 | // Setup the language and the i18n translations: 47 | 48 | unsigned int selectedLanguage = wxLocale::GetSystemLanguage(); 49 | if(selectedLanguage == wxLANGUAGE_UNKNOWN) selectedLanguage = 50 | wxLANGUAGE_DEFAULT; 51 | 52 | // Read language from config: 53 | wxConfig *config = new wxConfig(_T(_OPENRTMS_NAMEOFCONFIG)); 54 | wxString str; 55 | if(config->Read(_T("Language"), &str)){ 56 | unsigned int i; 57 | for(i = 0; i < WXSIZEOF(langNames); i++) 58 | if(str.CmpNoCase(langNames[i]) == 0){ 59 | selectedLanguage = langIds[i]; 60 | } 61 | } 62 | // The config is closed / deleted immediately, because the MainFrame 63 | // opens the config as well. It is not needed in the App class anymore. 64 | delete config; 65 | 66 | // Set the language: 67 | //TODO: Why does wxLOCALE_CONV_ENCODING not work? 68 | if(!locale.Init(selectedLanguage, wxLOCALE_LOAD_DEFAULT)){ 69 | wxLogError(_T("This language is not supported by the system!")); 70 | return; 71 | } 72 | 73 | locale.AddCatalogLookupPathPrefix(_T("i18n")); 74 | bool catalogLoaded = locale.AddCatalog(_T("Open-rTMS")); 75 | if(!catalogLoaded){ 76 | wxLogError( 77 | _T("The translation catalog for ") 78 | + locale.GetCanonicalName() + _T(" was not loaded!")); 79 | } 80 | } 81 | 82 | bool OpenrTMSApp::OnInit() 83 | { 84 | frame = new MainFrame(NULL); 85 | 86 | //TODO: Check, why the icon is not working with Windows / Code::Blocks. 87 | #ifndef __WIN32__ 88 | wxIcon iconLogo(logo_xpm); 89 | frame->SetIcon(iconLogo); 90 | #endif 91 | 92 | frame->Show(true); 93 | SetTopWindow(frame); 94 | 95 | return true; 96 | } 97 | 98 | /*! \mainpage Open-rTMS - Developers Documentation 99 | * 100 | * \image html pictures/start.png 101 | * 102 | */ 103 | 104 | -------------------------------------------------------------------------------- /ControlSoftware/src/Open-rTMS.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : Open-rTMS.h 3 | // Purpose : Main entry point. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 21.02.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #ifndef OPENRTMS_H_ 31 | #define OPENRTMS_H_ 32 | 33 | #include "StdInclude.h" 34 | #include "Config.h" 35 | #include "gui/MainFrame.h" 36 | #include 37 | 38 | /*!\class OpenrTMSApp 39 | * \brief Main application class for the project 40 | * 41 | * the purpose of this class is only to provide a vehicle upon which the rest of the 42 | * program runs. 43 | * 44 | * This classes tasks are: 45 | * 46 | * - Setup the language (in the Constructor). 47 | * - Open the main window (in OnInit). 48 | * 49 | * Everything else is done in the MainFrame. 50 | * 51 | */ 52 | 53 | class OpenrTMSApp:public wxApp { 54 | // Constructor 55 | public: 56 | OpenrTMSApp(void); 57 | 58 | // Member variables 59 | public: 60 | MainFrame* frame; 61 | 62 | protected: 63 | wxLocale locale; 64 | 65 | // Methods 66 | public: 67 | bool OnInit(); 68 | 69 | }; 70 | 71 | DECLARE_APP(OpenrTMSApp) 72 | #endif /* OPENRTMS_H_ */ 73 | -------------------------------------------------------------------------------- /ControlSoftware/src/StdInclude.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : StdInclude.h 3 | // Purpose : Takes care of precompiled header issues 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 21.05.2009 9 | // Copyright : (C) 2009 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #ifndef STDINC_H_ 31 | #define STDINC_H_ 32 | 33 | // For compilers that support precompilation, includes "wx/wx.h". 34 | 35 | #include 36 | 37 | #ifdef __BORLANDC__ 38 | #pragma hdrstop 39 | #endif 40 | 41 | #ifndef WX_PRECOMP 42 | #include 43 | #endif 44 | 45 | 46 | #endif /* STDINC_H_ */ 47 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/AboutDialog.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : AboutDialog.cpp 3 | // Purpose : The about dialog. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 21.02.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-05-22 01:40:18 +0200 (Sa, 22 Mai 2010) $ 26 | //$Revision: 45 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #include "AboutDialog.h" 31 | 32 | AboutDialog::AboutDialog(wxWindow* parent) : 33 | GUIAboutDialog(parent) 34 | { 35 | } 36 | 37 | AboutDialog::~AboutDialog() 38 | { 39 | 40 | } 41 | 42 | void AboutDialog::OnClose(wxCommandEvent& event) 43 | { 44 | Close(); 45 | } 46 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/AboutDialog.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : AboutDialog.h 3 | // Purpose : The about dialog. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 21.02.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | 32 | #ifndef ABOUTDIALOG_H_ 33 | #define ABOUTDIALOG_H_ 34 | 35 | #include "../StdInclude.h" 36 | #include "gui.h" 37 | 38 | class AboutDialog:public GUIAboutDialog { 39 | // Constructor/ Destructor 40 | public: 41 | AboutDialog(wxWindow* parent); 42 | virtual ~AboutDialog(); 43 | 44 | // Member variables 45 | private: 46 | 47 | 48 | // Methods 49 | private: 50 | 51 | void OnClose(wxCommandEvent& event); 52 | }; 53 | 54 | #endif /* ABOUTDIALOG_H_ */ 55 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | aux_source_directory(. files) 2 | add_library(gui ${files}) 3 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/DialogCurrentControl.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : DialogCurrentControl.cpp 3 | // Purpose : 4 | // Thread Safe : No 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 19.11.2013 9 | // Copyright : (C) 2013 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | /////////////////////////////////////////////////////////////////////////////// 26 | 27 | #include "DialogCurrentControl.h" 28 | 29 | DialogCurrentControl::DialogCurrentControl(wxWindow* parent, 30 | SerialPort * serial) : 31 | GUIControlCurrentsDialog(parent) 32 | { 33 | wxASSERT(serial!=NULL); 34 | this->serial = serial; 35 | } 36 | 37 | DialogCurrentControl::~DialogCurrentControl() 38 | { 39 | 40 | } 41 | 42 | void DialogCurrentControl::OnButtonClose(wxCommandEvent& event) 43 | { 44 | this->Close(); 45 | } 46 | 47 | bool DialogCurrentControl::TransferDataToWindow(void) 48 | { 49 | return true; 50 | } 51 | bool DialogCurrentControl::TransferDataFromWindow(void) 52 | { 53 | return true; 54 | } 55 | 56 | void DialogCurrentControl::SetCurrent(unsigned char channel, int current_mA) 57 | { 58 | int i = ((current_mA + 250) * 4095) / 501; 59 | 60 | if(i < 0 || i > 9999) return; 61 | if(channel < 0 || channel > 7) return; 62 | 63 | char command[16]; 64 | sprintf(command, "C %u %4u\n", channel, i); 65 | serial->SendData(command, strlen(command)); 66 | } 67 | 68 | // There must be a better way of doing this. 69 | // event.GetId() did not return the ID_CHANNELx of the slider... 70 | 71 | void DialogCurrentControl::OnScroll0(wxScrollEvent& event) 72 | { 73 | int current = event.GetPosition(); 74 | SetCurrent(0, current); 75 | } 76 | void DialogCurrentControl::OnScroll1(wxScrollEvent& event) 77 | { 78 | int current = event.GetPosition(); 79 | SetCurrent(1, current); 80 | } 81 | void DialogCurrentControl::OnScroll2(wxScrollEvent& event) 82 | { 83 | int current = event.GetPosition(); 84 | SetCurrent(2, current); 85 | } 86 | void DialogCurrentControl::OnScroll3(wxScrollEvent& event) 87 | { 88 | int current = event.GetPosition(); 89 | SetCurrent(3, current); 90 | } 91 | void DialogCurrentControl::OnScroll4(wxScrollEvent& event) 92 | { 93 | int current = event.GetPosition(); 94 | SetCurrent(4, current); 95 | } 96 | void DialogCurrentControl::OnScroll5(wxScrollEvent& event) 97 | { 98 | int current = event.GetPosition(); 99 | SetCurrent(5, current); 100 | } 101 | void DialogCurrentControl::OnScroll6(wxScrollEvent& event) 102 | { 103 | int current = event.GetPosition(); 104 | SetCurrent(6, current); 105 | } 106 | void DialogCurrentControl::OnScroll7(wxScrollEvent& event) 107 | { 108 | int current = event.GetPosition(); 109 | SetCurrent(7, current); 110 | } 111 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/DialogCurrentControl.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : DialogCurrentControl.h 3 | // Purpose : 4 | // Thread Safe : No 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 19.11.2013 9 | // Copyright : (C) 2013 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | /////////////////////////////////////////////////////////////////////////////// 26 | 27 | #ifndef DIALOGCURRENTCONTROL_H_ 28 | #define DIALOGCURRENTCONTROL_H_ 29 | 30 | /*!\class DialogCurrentControl 31 | * \brief Dialog that allows the direct control of the currents in the coils. 32 | */ 33 | 34 | #include "../StdInclude.h" 35 | #include "../hardware/SerialPort.h" 36 | 37 | #include "gui.h" 38 | 39 | class DialogCurrentControl:public GUIControlCurrentsDialog { 40 | // Constructor / Destructor 41 | public: 42 | DialogCurrentControl(wxWindow* parent, SerialPort * serial); 43 | virtual ~DialogCurrentControl(); 44 | 45 | // Member variables 46 | private: 47 | SerialPort * serial; 48 | // Methods 49 | 50 | public: 51 | bool TransferDataToWindow(void); 52 | bool TransferDataFromWindow(void); 53 | 54 | private: 55 | void SetCurrent(unsigned char channel, int current_mA); 56 | 57 | virtual void OnButtonClose(wxCommandEvent& event); 58 | virtual void OnScroll0(wxScrollEvent& event); 59 | virtual void OnScroll1(wxScrollEvent& event); 60 | virtual void OnScroll2(wxScrollEvent& event); 61 | virtual void OnScroll3(wxScrollEvent& event); 62 | virtual void OnScroll4(wxScrollEvent& event); 63 | virtual void OnScroll5(wxScrollEvent& event); 64 | virtual void OnScroll6(wxScrollEvent& event); 65 | virtual void OnScroll7(wxScrollEvent& event); 66 | 67 | }; 68 | 69 | #endif /* DIALOGCURRENTCONTROL_H_ */ 70 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/MainCanvas.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : MainCanvas.cpp 3 | // Purpose : 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 07.08.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #include "MainCanvas.h" 31 | 32 | #include 33 | 34 | #ifdef __WXMAC__ 35 | #include "OpenGL/glu.h" 36 | #else 37 | #include 38 | #endif 39 | 40 | static int wx_gl_attribs[] = 41 | {WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 24, 0}; 42 | 43 | MainCanvas::MainCanvas(wxWindow *parent, wxWindowID id, const wxPoint& pos, 44 | const wxSize& size, long style, const wxString& name) : 45 | wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size, 46 | style | wxFULL_REPAINT_ON_RESIZE, name, wx_gl_attribs) 47 | { 48 | Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(MainCanvas::OnEnterWindow), 49 | NULL, this); 50 | Connect(wxEVT_ERASE_BACKGROUND, 51 | wxEraseEventHandler(MainCanvas::OnEraseBackground), NULL, this); 52 | Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(MainCanvas::OnMouseEvent), 53 | NULL, this); 54 | Connect(wxEVT_LEFT_UP, wxMouseEventHandler(MainCanvas::OnMouseEvent), NULL, 55 | this); 56 | Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(MainCanvas::OnMouseEvent), 57 | NULL, this); 58 | Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(MainCanvas::OnMouseEvent), 59 | NULL, this); 60 | Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainCanvas::OnMouseEvent), 61 | NULL, this); 62 | Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(MainCanvas::OnMouseEvent), NULL, 63 | this); 64 | Connect(wxEVT_MOTION, wxMouseEventHandler(MainCanvas::OnMouseEvent), NULL, 65 | this); 66 | Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(MainCanvas::OnMouseEvent), 67 | NULL, this); 68 | Connect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(MainCanvas::OnMouseEvent), 69 | NULL, this); 70 | Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(MainCanvas::OnMouseEvent), 71 | NULL, this); 72 | Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(MainCanvas::OnMouseEvent), 73 | NULL, this); 74 | Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(MainCanvas::OnMouseEvent), 75 | NULL, this); 76 | Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(MainCanvas::OnMouseEvent), 77 | NULL, this); 78 | Connect(wxEVT_PAINT, wxPaintEventHandler(MainCanvas::OnPaint), NULL, this); 79 | 80 | //TODO: MAXIMIZE does not throw a EVT_SIZE. Workaround would be a timer to do a regular repaint. 81 | Connect(wxEVT_SIZE, wxSizeEventHandler(MainCanvas::OnSize), NULL, this); 82 | 83 | mouse_x = mouse_y = 0; 84 | rotx = rotz = 0.0; 85 | transx = transy = transz = 0.0; 86 | } 87 | 88 | MainCanvas::~MainCanvas() 89 | { 90 | // Disconnect Events 91 | Disconnect(wxEVT_ENTER_WINDOW, 92 | wxMouseEventHandler(MainCanvas::OnEnterWindow), NULL, this); 93 | Disconnect(wxEVT_ERASE_BACKGROUND, 94 | wxEraseEventHandler(MainCanvas::OnEraseBackground), NULL, this); 95 | Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(MainCanvas::OnMouseEvent), 96 | NULL, this); 97 | Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(MainCanvas::OnMouseEvent), 98 | NULL, this); 99 | Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(MainCanvas::OnMouseEvent), 100 | NULL, this); 101 | Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(MainCanvas::OnMouseEvent), 102 | NULL, this); 103 | Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainCanvas::OnMouseEvent), 104 | NULL, this); 105 | Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(MainCanvas::OnMouseEvent), 106 | NULL, this); 107 | Disconnect(wxEVT_MOTION, wxMouseEventHandler(MainCanvas::OnMouseEvent), 108 | NULL, this); 109 | Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(MainCanvas::OnMouseEvent), 110 | NULL, this); 111 | Disconnect(wxEVT_MIDDLE_DCLICK, 112 | wxMouseEventHandler(MainCanvas::OnMouseEvent), NULL, this); 113 | Disconnect(wxEVT_RIGHT_DCLICK, 114 | wxMouseEventHandler(MainCanvas::OnMouseEvent), NULL, this); 115 | Disconnect(wxEVT_LEAVE_WINDOW, 116 | wxMouseEventHandler(MainCanvas::OnMouseEvent), NULL, this); 117 | Disconnect(wxEVT_ENTER_WINDOW, 118 | wxMouseEventHandler(MainCanvas::OnMouseEvent), NULL, this); 119 | Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(MainCanvas::OnMouseEvent), 120 | NULL, this); 121 | Disconnect(wxEVT_PAINT, wxPaintEventHandler(MainCanvas::OnPaint), NULL, 122 | this); 123 | Disconnect(wxEVT_SIZE, wxSizeEventHandler(MainCanvas::OnSize), NULL, this); 124 | 125 | } 126 | 127 | void MainCanvas::OnEnterWindow(wxMouseEvent& WXUNUSED(event)) 128 | { 129 | SetFocus(); 130 | } 131 | 132 | void MainCanvas::OnSize(wxSizeEvent& event) 133 | { 134 | // this is also necessary to update the context on some platforms 135 | wxGLCanvas::OnSize(event); 136 | this->Refresh(); 137 | } 138 | 139 | void MainCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event)) 140 | { 141 | // Do nothing, to avoid flashing. 142 | } 143 | 144 | void MainCanvas::OnMouseEvent(wxMouseEvent& event) 145 | { 146 | 147 | if(event.ButtonDown(wxMOUSE_BTN_ANY)){ 148 | mouse_x = event.m_x; 149 | mouse_y = event.m_y; 150 | } 151 | 152 | if(event.Dragging() && event.ButtonIsDown(wxMOUSE_BTN_LEFT)){ 153 | transx += (float) (event.m_x - mouse_x) / 1000; 154 | transz -= (float) (event.m_y - mouse_y) / 1000; 155 | } 156 | if(event.GetWheelRotation() != 0){ 157 | transy += (float) event.GetWheelRotation() / 1000; 158 | } 159 | 160 | if(event.Dragging() && event.ButtonIsDown(wxMOUSE_BTN_RIGHT)){ 161 | rotz -= (float) (event.m_x - mouse_x) / 5; 162 | rotx -= (float) (event.m_y - mouse_y) / 5; 163 | } 164 | 165 | if(event.Dragging() || event.GetWheelRotation() != 0){ 166 | mouse_x = event.m_x; 167 | mouse_y = event.m_y; 168 | this->Refresh(); 169 | } 170 | 171 | } 172 | 173 | void MainCanvas::InitGL() 174 | { 175 | SetCurrent(); 176 | 177 | /* set viewing projection */ 178 | // glMatrixMode(GL_PROJECTION); 179 | // glFrustum( -0.5f, 0.5f, -0.5f, 0.5f, 1.0f, 3.0f); 180 | // Is done in OnSize(...) 181 | // GLfloat attenuation[] = 182 | // {1.0f, -0.01f, -.000001f}; 183 | //::glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, attenuation, 0); 184 | ::glEnable(GL_COLOR_MATERIAL); 185 | ::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); 186 | ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 187 | //::glBlendFunc(GL_ONE, GL_ONE); // for Stereo Mode 188 | 189 | ::glEnable(GL_BLEND); 190 | ::glEnable(GL_POINT_SMOOTH); 191 | ::glEnable(GL_DEPTH_TEST); 192 | SetupLighting(); 193 | this->Refresh(); 194 | 195 | } 196 | 197 | void MainCanvas::SetupLighting() 198 | { 199 | GLfloat ambient0[] = 200 | {0.2f, 0.2f, 0.2f}; 201 | GLfloat diffuse0[] = 202 | {0.5f, 0.5f, 0.5f}; 203 | GLfloat specular0[] = 204 | {0.9f, 0.9f, 0.9f}; 205 | GLfloat position0[] = 206 | {-100, 200, 500, 0}; 207 | glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0); 208 | glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0); 209 | glLightfv(GL_LIGHT0, GL_SPECULAR, specular0); 210 | glLightfv(GL_LIGHT0, GL_POSITION, position0); 211 | glEnable(GL_LIGHT0); // ... and activate 212 | 213 | ::glEnable(GL_LIGHTING); 214 | } 215 | 216 | void MainCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) 217 | { 218 | if(!IsShown()) return; 219 | 220 | #ifndef __WXMOTIF__ 221 | if(!GetContext()) return; 222 | #endif 223 | 224 | wxGLCanvas::SetCurrent(); 225 | wxPaintDC(this); 226 | 227 | // Init OpenGL once, but after SetCurrent 228 | if(!isInitialized){ 229 | InitGL(); 230 | isInitialized = true; 231 | } 232 | 233 | ::glMatrixMode(GL_MODELVIEW); 234 | ::glLoadIdentity(); 235 | 236 | // Switch to a coronal coordinate system (i.e. You look the patient directly into the face) 237 | // Z is upwards, X is to the right, and Y is toward the viewer 238 | ::glScalef(1.0, 1.0, -1.0); // Change right hande to left handed by inverting Z 239 | ::glRotatef(-90, 1.0, 0.0, 0.0); // Rotate Z upwards 240 | 241 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 242 | glDrawBuffer(GL_BACK); 243 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 244 | 245 | // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...) 246 | int w, h; 247 | GetClientSize(&w, &h); 248 | #ifndef __WXMOTIF__ 249 | if(GetContext()) 250 | #endif 251 | { 252 | SetCurrent(); 253 | ::glViewport(0, 0, (GLint) w, (GLint) h); 254 | GLdouble ar = (GLdouble) w / (GLdouble) h; // setup perspective 255 | ::glMatrixMode(GL_PROJECTION); 256 | ::glLoadIdentity(); 257 | ::gluPerspective(45, ar, 0.01, 10); 258 | ::glMatrixMode(GL_MODELVIEW); 259 | } 260 | 261 | ::glTranslatef(0, -1.0, 0.0); // Move the origin back by 1 meter. 262 | ::glTranslatef(transx, transy, transz); // Move the origin 263 | ::glRotatef(rotx, 1, 0, 0); // Rotate around X, ... 264 | ::glRotatef(rotz, 0, 0, 1); // ... then rotate around Z (turntable style) 265 | 266 | // ::glMultMatrixd(transmat.a); 267 | // ::glMultMatrixd(rotmat.a); 268 | 269 | Render(); 270 | 271 | glFlush(); 272 | SwapBuffers(); 273 | } 274 | 275 | void MainCanvas::RenderCoordinateSystem(void) 276 | { 277 | glBegin(GL_LINES); 278 | 279 | glColor3b(32, 32, 32); 280 | glNormal3f(-1, 0, 0); 281 | glVertex3f(-1, 0, 0); 282 | glColor3b(127, 0, 0); 283 | glNormal3f(1, 0, 0); 284 | glVertex3f(1, 0, 0); 285 | 286 | glColor3b(32, 32, 32); 287 | glNormal3f(0, -1, 0); 288 | glVertex3f(0, -1, 0); 289 | glColor3b(0, 127, 0); 290 | glNormal3f(0, 1, 0); 291 | glVertex3f(0, 1, 0); 292 | 293 | glColor3b(32, 32, 32); 294 | glNormal3f(0, 0, -1); 295 | glVertex3f(0, 0, -1); 296 | glColor3b(0, 0, 127); 297 | glNormal3f(0, 0, 1); 298 | glVertex3f(0, 0, 1); 299 | 300 | glEnd(); 301 | } 302 | 303 | void MainCanvas::Render() 304 | { 305 | ::glEnable(GL_RESCALE_NORMAL); 306 | RenderCoordinateSystem(); 307 | 308 | ::glDisable(GL_RESCALE_NORMAL); 309 | 310 | //Headform: 311 | //plot(-(u+1)*(1-t).^3+u*(1-t).^2+1,-(u+1)*t.^3+u*t.^2+1,'-x') 312 | 313 | } 314 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/MainCanvas.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : MainCanvas.h 3 | // Purpose : 4 | // Thread Safe : Yes 5 | // Platform dependent : Yes 6 | // Compiler Options : -lopengl32 -lglu 7 | // Author : Tobias Schaefer 8 | // Created : 07.08.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #ifndef MAINCANVAS_H_ 31 | #define MAINCANVAS_H_ 32 | 33 | #include "../StdInclude.h" 34 | #include "../Config.h" 35 | #include 36 | 37 | /*!\class MainCanvas 38 | * \brief Canvas for the Main Window 39 | * 40 | * It is basically a 2D display rendered in 3D. 41 | * (For the coolness factor, speed and everything.) 42 | */ 43 | 44 | class MainCanvas:public wxGLCanvas { 45 | // Constructor / Destructor 46 | public: 47 | MainCanvas(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = 48 | wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 49 | 0, const wxString& name = _T("OpenGLCanvas")); 50 | virtual ~MainCanvas(); 51 | // Member Variables 52 | private: 53 | bool isInitialized; //! The OpenGL system is inititalized on the first paint event. It is flagged here! 54 | 55 | public: 56 | ::GLfloat rotx, rotz, transx, transy, transz; 57 | int mouse_x, mouse_y; 58 | 59 | // Methods 60 | public: 61 | void InitGL(); 62 | void SetupLighting(); 63 | 64 | void RenderCoordinateSystem(void); 65 | void Render(); 66 | 67 | protected: 68 | void OnPaint(wxPaintEvent& WXUNUSED(event)); 69 | void OnSize(wxSizeEvent& event); 70 | void OnEraseBackground(wxEraseEvent& WXUNUSED(event)); 71 | void OnEnterWindow(wxMouseEvent& WXUNUSED(event)); 72 | void OnMouseEvent(wxMouseEvent& event); 73 | void OnTimer(wxTimerEvent& event); 74 | }; 75 | 76 | #endif /* MAINCANVAS_H_ */ 77 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/MainFrame.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : MainFrame.cpp 3 | // Purpose : The main window. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 21.02.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-05-22 01:40:18 +0200 (Sa, 22 Mai 2010) $ 26 | //$Revision: 45 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #include "MainFrame.h" 31 | #include "SerialSetupDialog.h" 32 | #include "AboutDialog.h" 33 | #include "../languages.h" 34 | 35 | #include 36 | #include 37 | #include 38 | #include "DialogCurrentControl.h" 39 | 40 | MainFrame::MainFrame(wxWindow* parent) : 41 | GUIMainFrame(parent) 42 | { 43 | // logWindow = new wxLogWindow(this, _("Open-rTMS - log window"), false, true); 44 | // logWindow->Show(); 45 | 46 | // wxLogMessage(_T("Control Software started!")); 47 | 48 | // Read configuration: 49 | config = new wxConfig(_T(_OPENRTMS_NAMEOFCONFIG)); 50 | 51 | wxString temp; 52 | config->Read(_T("Port"), &temp, _T("/dev/ttyUSB0")); 53 | config->Read(_T("OpenOnStartup"), &openOnStartup, false); 54 | 55 | if(openOnStartup){ 56 | serial.Open(temp.ToAscii(), 115200); 57 | if(serial.IsOpen()) serial.SetDTR(true); 58 | } 59 | TransferDataToWindow(); 60 | } 61 | 62 | MainFrame::~MainFrame() 63 | { 64 | delete config; // config is written back to file (automagically) 65 | } 66 | 67 | bool MainFrame::TransferDataToWindow(void) 68 | { 69 | if(serial.IsOpen()){ 70 | m_buttonConnect->Enable(false); 71 | m_buttonCurrents->Enable(true); 72 | m_buttonDisconnect->Enable(true); 73 | 74 | m_menubar->Enable(ID_CONNECT, false); 75 | m_menubar->Enable(ID_CONTROLCURRENTS, true); 76 | m_menubar->Enable(ID_DISCONNECT, true); 77 | 78 | m_statusBar->SetStatusText(_("Hardware: Connected"), 1); 79 | }else{ 80 | m_buttonConnect->Enable(true); 81 | m_buttonCurrents->Enable(false); 82 | m_buttonDisconnect->Enable(false); 83 | 84 | m_menubar->Enable(ID_CONNECT, true); 85 | m_menubar->Enable(ID_CONTROLCURRENTS, false); 86 | m_menubar->Enable(ID_DISCONNECT, false); 87 | 88 | m_statusBar->SetStatusText(_("Hardware: Disconnected"), 1); 89 | } 90 | return true; 91 | } 92 | 93 | bool MainFrame::TransferDataFromWindow(void) 94 | { 95 | return true; 96 | } 97 | 98 | void MainFrame::OnQuit(wxCommandEvent& event) 99 | { 100 | this->Close(); 101 | } 102 | 103 | void MainFrame::OnChangeLanguage(wxCommandEvent& event) 104 | { 105 | long lng = wxGetSingleChoiceIndex(_T( 106 | "Please choose language:\nChanges will take place after restart!"), 107 | _T("Language"), WXSIZEOF(langNames), langNames); 108 | if(lng < 0) return; 109 | config->Write(_T("Language"), langNames[lng]); 110 | } 111 | 112 | void MainFrame::OnAbout(wxCommandEvent& event) 113 | { 114 | AboutDialog* dialog = new AboutDialog(this); 115 | dialog->Show(); 116 | } 117 | 118 | void MainFrame::OnConnect(wxCommandEvent& event) 119 | { 120 | if(serial.IsOpen()) return; 121 | 122 | wxString temp; 123 | config->Read(_T("Port"), &temp, _T("/dev/ttyUSB0")); 124 | 125 | serial.Open(temp.ToAscii(), 115200); 126 | if(serial.IsOpen()){ 127 | serial.SetDTR(true); 128 | }else{ 129 | wxMessageDialog dialog(this, 130 | _T("Serial port (") + temp + _T(") is not found!"), 131 | _("Connection to hardware"), 132 | wxOK | wxICON_ERROR | wxSTAY_ON_TOP); 133 | dialog.ShowModal(); 134 | } 135 | TransferDataToWindow(); 136 | } 137 | void MainFrame::OnControlCurrents(wxCommandEvent& event) 138 | { 139 | if(!serial.IsOpen()) return; 140 | DialogCurrentControl dialog(this, &serial); 141 | dialog.ShowModal(); 142 | } 143 | void MainFrame::OnDisconnect(wxCommandEvent& event) 144 | { 145 | serial.Close(); 146 | TransferDataToWindow(); 147 | } 148 | 149 | void MainFrame::OnSetupHardware(wxCommandEvent& event) 150 | { 151 | wxString temp; 152 | config->Read(_T("Port"), &temp, _T("/dev/ttyUSB0")); 153 | 154 | SerialSetupDialog dialog(this, &serial, temp, openOnStartup); 155 | if(dialog.ShowModal() == wxID_OK){ 156 | config->Write(_T("Port"), dialog.portName); 157 | config->Write(_T("OpenOnStartup"), dialog.openOnStartup); 158 | config->Flush(); 159 | } 160 | TransferDataToWindow(); 161 | } 162 | 163 | //void MainFrame::OnTimer(wxTimerEvent& event) 164 | //{ 165 | // 166 | //} 167 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/MainFrame.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : MainFrame.h 3 | // Purpose : The main window. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 21.02.2010 9 | // Copyright : (C) 2010 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #ifndef MAINFRAME_H_ 31 | #define MAINFRAME_H_ 32 | 33 | #include "../Config.h" 34 | #include "../StdInclude.h" 35 | #include "../hardware/SerialPort.h" 36 | #include "gui.h" 37 | #include 38 | #include 39 | #include 40 | 41 | class MainFrame:public GUIMainFrame { 42 | // Constructor/ Destructor 43 | public: 44 | MainFrame(wxWindow* parent); 45 | virtual ~MainFrame(); 46 | 47 | // Member variables 48 | 49 | public: 50 | 51 | private: 52 | wxConfig * config; 53 | SerialPort serial; 54 | 55 | wxLogWindow * logWindow; 56 | // wxTimer timer; 57 | 58 | bool openOnStartup; 59 | 60 | // Methods 61 | private: 62 | 63 | void OnConnect(wxCommandEvent& event); 64 | void OnControlCurrents(wxCommandEvent& event); 65 | void OnDisconnect(wxCommandEvent& event); 66 | void OnQuit(wxCommandEvent& event); 67 | void OnSetupHardware(wxCommandEvent& event); 68 | void OnAbout(wxCommandEvent& event); 69 | void OnChangeLanguage(wxCommandEvent& event); 70 | 71 | bool TransferDataToWindow(void); 72 | bool TransferDataFromWindow(void); 73 | 74 | // void OnTimer(wxTimerEvent& event); 75 | 76 | }; 77 | 78 | #endif /* MAINFRAME_H_ */ 79 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/SerialSetupDialog.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : SerialSetupDialog.cpp 3 | // Purpose : Setup dialog for serial port. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 25.07.2009 9 | // Copyright : (C) 2009 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-05-22 01:40:18 +0200 (Sa, 22 Mai 2010) $ 26 | //$Revision: 45 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #include "SerialSetupDialog.h" 31 | #include "../hardware/ParallaxPropeller.h" 32 | #include 33 | 34 | SerialSetupDialog::SerialSetupDialog(wxWindow* parent, SerialPort* serial, 35 | wxString portName, bool openOnStartup) : 36 | GUISerialSetupDialog(parent) 37 | { 38 | wxASSERT(serial != NULL); 39 | 40 | this->serial = serial; 41 | this->portName = portName; 42 | this->openOnStartup = openOnStartup; 43 | 44 | if(serial->IsOpen()) m_textCtrlLog->SetValue(_("Connected!\n")); 45 | 46 | m_textCtrlPort->SetValue(portName); 47 | TransferDataToWindow(); 48 | } 49 | 50 | SerialSetupDialog::~SerialSetupDialog() 51 | { 52 | } 53 | 54 | void SerialSetupDialog::OnConnect(wxCommandEvent& event) 55 | { 56 | TransferDataFromWindow(); 57 | 58 | if(!serial->Open(portName.ToAscii(), 115200)){ 59 | m_textCtrlLog->SetValue(_("Port could not be opened!\n")); 60 | return; 61 | } 62 | serial->SetDTR(true); 63 | m_textCtrlLog->SetValue( 64 | _("Connected...\nSearching for Parallax Propeller...\n")); 65 | TransferDataToWindow(); 66 | Refresh(); 67 | 68 | ParallaxPropeller propeller(serial); 69 | 70 | int v = propeller.GetVersion(); 71 | m_textCtrlLog->AppendText(propeller.log); 72 | if(v == -1){ 73 | m_textCtrlLog->AppendText( 74 | _("No Parallax Propeller found on this port!\n")); 75 | }else{ 76 | m_textCtrlLog->AppendText( 77 | wxString::Format(_("Parallax Propeller (Version %d) found!\n"), 78 | v)); 79 | } 80 | m_textCtrlLog->AppendText(_("Finished searching!")); 81 | } 82 | 83 | void SerialSetupDialog::OnDisconnect(wxCommandEvent& event) 84 | { 85 | TransferDataFromWindow(); 86 | if(!serial->Close()) return; 87 | TransferDataToWindow(); 88 | } 89 | 90 | void SerialSetupDialog::OnClose(wxCommandEvent& event) 91 | { 92 | TransferDataFromWindow(); 93 | this->Close(); 94 | } 95 | 96 | void SerialSetupDialog::OnProgramGenerator(wxCommandEvent& event) 97 | { 98 | m_textCtrlLog->SetValue(_("Programming...\n")); 99 | 100 | ParallaxPropeller propeller(serial); 101 | 102 | bool worked = propeller.UploadAndStart(wxFileName(_T(_OPENRTMS_FIRMWARE)), 103 | m_checkBoxWriteEEprom->GetValue()); 104 | 105 | m_textCtrlLog->AppendText(propeller.log); 106 | 107 | if(worked){ 108 | m_textCtrlLog->AppendText(_("Scope loaded and started!\n")); 109 | }else{ 110 | m_textCtrlLog->AppendText(_T("Programming failed!\n")); 111 | } 112 | } 113 | 114 | bool SerialSetupDialog::TransferDataToWindow(void) 115 | { 116 | m_checkBoxOpenOnStartup->SetValue(openOnStartup); 117 | m_textCtrlPort->SetValue(portName); 118 | 119 | if(serial->IsOpen()){ 120 | m_buttonConnect->Enable(false); 121 | m_buttonDisconnect->Enable(true); 122 | m_textCtrlPort->Enable(false); 123 | 124 | m_buttonProgramGenerator->Enable(true); 125 | m_checkBoxWriteEEprom->Enable(true); 126 | }else{ 127 | m_buttonConnect->Enable(true); 128 | m_buttonDisconnect->Enable(false); 129 | m_textCtrlPort->Enable(true); 130 | m_textCtrlLog->SetValue(_("Disconnected!")); 131 | 132 | m_buttonProgramGenerator->Enable(false); 133 | m_checkBoxWriteEEprom->Enable(false); 134 | } 135 | 136 | return true; 137 | } 138 | 139 | bool SerialSetupDialog::TransferDataFromWindow(void) 140 | { 141 | openOnStartup = m_checkBoxOpenOnStartup->GetValue(); 142 | portName = m_textCtrlPort->GetValue(); 143 | return true; 144 | } 145 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/SerialSetupDialog.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : SerialSetupDialog.h 3 | // Purpose : Setup dialog for serial port. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 25.07.2009 9 | // Copyright : (C) 2009 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-05-22 01:40:18 +0200 (Sa, 22 Mai 2010) $ 26 | //$Revision: 45 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #ifndef SERIALSETUPDIALOG_H_ 31 | #define SERIALSETUPDIALOG_H_ 32 | 33 | #include "../StdInclude.h" 34 | #include "../Config.h" 35 | #include "../hardware/SerialPort.h" 36 | #include "gui.h" 37 | 38 | class SerialSetupDialog:public GUISerialSetupDialog { 39 | // Constructor / Destructor 40 | public: 41 | SerialSetupDialog(wxWindow* parent, SerialPort* serial, wxString portName, 42 | bool openOnStartup); 43 | virtual ~SerialSetupDialog(); 44 | 45 | // Member Variables 46 | public: 47 | wxString portName; 48 | bool openOnStartup; 49 | 50 | private: 51 | SerialPort* serial; 52 | 53 | // Member Functions 54 | public: 55 | 56 | private: 57 | void OnConnect(wxCommandEvent& event); 58 | void OnDisconnect(wxCommandEvent& event); 59 | void OnClose(wxCommandEvent& event); 60 | void OnProgramGenerator(wxCommandEvent& event); 61 | 62 | bool TransferDataToWindow(void); 63 | bool TransferDataFromWindow(void); 64 | }; 65 | 66 | #endif /* SERIALSETUPDIALOG_H_ */ 67 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/gui.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////// 2 | // C++ code generated with wxFormBuilder (version Dec 21 2009) 3 | // http://www.wxformbuilder.org/ 4 | // 5 | // PLEASE DO "NOT" EDIT THIS FILE! 6 | /////////////////////////////////////////////////////////////////////////// 7 | 8 | #include "gui.h" 9 | 10 | /////////////////////////////////////////////////////////////////////////// 11 | 12 | GUIMainFrame::GUIMainFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) 13 | { 14 | this->SetSizeHints( wxDefaultSize, wxDefaultSize ); 15 | 16 | m_statusBar = this->CreateStatusBar( 2, wxST_SIZEGRIP, wxID_ANY ); 17 | m_menubar = new wxMenuBar( 0 ); 18 | menuProject = new wxMenu(); 19 | wxMenuItem* m_menuItemConnect; 20 | m_menuItemConnect = new wxMenuItem( menuProject, ID_CONNECT, wxString( _("&Connect") ) , wxEmptyString, wxITEM_NORMAL ); 21 | menuProject->Append( m_menuItemConnect ); 22 | 23 | wxMenuItem* m_menuItemControlCurrents; 24 | m_menuItemControlCurrents = new wxMenuItem( menuProject, ID_CONTROLCURRENTS, wxString( _("&Control currents") ) , wxEmptyString, wxITEM_NORMAL ); 25 | menuProject->Append( m_menuItemControlCurrents ); 26 | m_menuItemControlCurrents->Enable( false ); 27 | 28 | wxMenuItem* m_menuItemDisconnect; 29 | m_menuItemDisconnect = new wxMenuItem( menuProject, ID_DISCONNECT, wxString( _("&Disconnect") ) , _("Disconnect from hardware"), wxITEM_NORMAL ); 30 | menuProject->Append( m_menuItemDisconnect ); 31 | m_menuItemDisconnect->Enable( false ); 32 | 33 | wxMenuItem* m_separator1; 34 | m_separator1 = menuProject->AppendSeparator(); 35 | 36 | wxMenuItem* m_menuItemQuit; 37 | m_menuItemQuit = new wxMenuItem( menuProject, wxID_QUIT, wxString( _("&Quit") ) + wxT('\t') + wxT("Ctrl+Q"), _("Quit the program."), wxITEM_NORMAL ); 38 | menuProject->Append( m_menuItemQuit ); 39 | 40 | m_menubar->Append( menuProject, _("&Project") ); 41 | 42 | menuSettings = new wxMenu(); 43 | wxMenuItem* m_menuItemSetupPort; 44 | m_menuItemSetupPort = new wxMenuItem( menuSettings, wxID_SETUPSERIALPORT, wxString( _("&Setup and program hardware") ) , _("Setup the serial port and program the hardware."), wxITEM_NORMAL ); 45 | menuSettings->Append( m_menuItemSetupPort ); 46 | 47 | wxMenuItem* m_menuItemLanguage; 48 | m_menuItemLanguage = new wxMenuItem( menuSettings, wxID_ANY, wxString( _("&Change language") ) , wxEmptyString, wxITEM_NORMAL ); 49 | menuSettings->Append( m_menuItemLanguage ); 50 | 51 | m_menubar->Append( menuSettings, _("&Settings") ); 52 | 53 | menuHelp = new wxMenu(); 54 | wxMenuItem* m_menuItem9; 55 | m_menuItem9 = new wxMenuItem( menuHelp, wxID_ABOUT, wxString( _("&About") ) , wxEmptyString, wxITEM_NORMAL ); 56 | menuHelp->Append( m_menuItem9 ); 57 | 58 | m_menubar->Append( menuHelp, _("&Help") ); 59 | 60 | this->SetMenuBar( m_menubar ); 61 | 62 | wxBoxSizer* bSizer1; 63 | bSizer1 = new wxBoxSizer( wxVERTICAL ); 64 | 65 | m_canvas = new MainCanvas(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); 66 | bSizer1->Add( m_canvas, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); 67 | 68 | wxBoxSizer* bSizer13; 69 | bSizer13 = new wxBoxSizer( wxHORIZONTAL ); 70 | 71 | 72 | bSizer13->Add( 0, 0, 1, wxEXPAND, 5 ); 73 | 74 | m_buttonConnect = new wxButton( this, wxID_ANY, _("Connect"), wxDefaultPosition, wxDefaultSize, 0 ); 75 | bSizer13->Add( m_buttonConnect, 0, wxALL, 5 ); 76 | 77 | 78 | bSizer13->Add( 0, 0, 1, wxEXPAND, 5 ); 79 | 80 | m_buttonCurrents = new wxButton( this, wxID_ANY, _("Control currents"), wxDefaultPosition, wxDefaultSize, 0 ); 81 | m_buttonCurrents->Enable( false ); 82 | 83 | bSizer13->Add( m_buttonCurrents, 0, wxALL, 5 ); 84 | 85 | 86 | bSizer13->Add( 0, 0, 1, wxEXPAND, 5 ); 87 | 88 | m_buttonDisconnect = new wxButton( this, wxID_ANY, _("Disconnect"), wxDefaultPosition, wxDefaultSize, 0 ); 89 | m_buttonDisconnect->Enable( false ); 90 | 91 | bSizer13->Add( m_buttonDisconnect, 0, wxALL, 5 ); 92 | 93 | 94 | bSizer13->Add( 0, 0, 1, wxEXPAND, 5 ); 95 | 96 | bSizer1->Add( bSizer13, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); 97 | 98 | this->SetSizer( bSizer1 ); 99 | this->Layout(); 100 | 101 | // Connect Events 102 | this->Connect( m_menuItemConnect->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnConnect ) ); 103 | this->Connect( m_menuItemControlCurrents->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnControlCurrents ) ); 104 | this->Connect( m_menuItemDisconnect->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnDisconnect ) ); 105 | this->Connect( m_menuItemQuit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnQuit ) ); 106 | this->Connect( m_menuItemSetupPort->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnSetupHardware ) ); 107 | this->Connect( m_menuItemLanguage->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnChangeLanguage ) ); 108 | this->Connect( m_menuItem9->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnAbout ) ); 109 | m_buttonConnect->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIMainFrame::OnConnect ), NULL, this ); 110 | m_buttonCurrents->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIMainFrame::OnControlCurrents ), NULL, this ); 111 | m_buttonDisconnect->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIMainFrame::OnDisconnect ), NULL, this ); 112 | } 113 | 114 | GUIMainFrame::~GUIMainFrame() 115 | { 116 | // Disconnect Events 117 | this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnConnect ) ); 118 | this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnControlCurrents ) ); 119 | this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnDisconnect ) ); 120 | this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnQuit ) ); 121 | this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnSetupHardware ) ); 122 | this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnChangeLanguage ) ); 123 | this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GUIMainFrame::OnAbout ) ); 124 | m_buttonConnect->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIMainFrame::OnConnect ), NULL, this ); 125 | m_buttonCurrents->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIMainFrame::OnControlCurrents ), NULL, this ); 126 | m_buttonDisconnect->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIMainFrame::OnDisconnect ), NULL, this ); 127 | } 128 | 129 | GUIAboutDialog::GUIAboutDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) 130 | { 131 | this->SetSizeHints( wxDefaultSize, wxDefaultSize ); 132 | 133 | wxBoxSizer* bSizer4; 134 | bSizer4 = new wxBoxSizer( wxVERTICAL ); 135 | 136 | m_textCtrl2 = new wxTextCtrl( this, wxID_ANY, _("Open rTMS Control Center\n\n(C) Tobias Schäfer 2011\n\nGNU General Public License version 3.0 (GPLv3)\n\nThis program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with this program. If not, see ."), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY ); 137 | bSizer4->Add( m_textCtrl2, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); 138 | 139 | m_button = new wxButton( this, wxID_CANCEL, _("Ok"), wxDefaultPosition, wxDefaultSize, 0 ); 140 | bSizer4->Add( m_button, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 141 | 142 | this->SetSizer( bSizer4 ); 143 | this->Layout(); 144 | } 145 | 146 | GUIAboutDialog::~GUIAboutDialog() 147 | { 148 | } 149 | 150 | GUISerialSetupDialog::GUISerialSetupDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) 151 | { 152 | this->SetSizeHints( wxDefaultSize, wxDefaultSize ); 153 | 154 | wxBoxSizer* bSizer2; 155 | bSizer2 = new wxBoxSizer( wxVERTICAL ); 156 | 157 | wxBoxSizer* bSizer14; 158 | bSizer14 = new wxBoxSizer( wxHORIZONTAL ); 159 | 160 | m_staticText1 = new wxStaticText( this, wxID_ANY, _("Serial Port:"), wxDefaultPosition, wxDefaultSize, 0 ); 161 | m_staticText1->Wrap( -1 ); 162 | bSizer14->Add( m_staticText1, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxALIGN_BOTTOM, 5 ); 163 | 164 | 165 | bSizer14->Add( 0, 0, 1, wxEXPAND, 5 ); 166 | 167 | m_checkBoxOpenOnStartup = new wxCheckBox( this, wxID_ANY, _("Open port on Startup"), wxDefaultPosition, wxDefaultSize, 0 ); 168 | bSizer14->Add( m_checkBoxOpenOnStartup, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); 169 | 170 | bSizer2->Add( bSizer14, 0, wxEXPAND, 5 ); 171 | 172 | m_textCtrlPort = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); 173 | bSizer2->Add( m_textCtrlPort, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); 174 | 175 | wxBoxSizer* bSizer3; 176 | bSizer3 = new wxBoxSizer( wxHORIZONTAL ); 177 | 178 | m_buttonConnect = new wxButton( this, wxID_OK, _("Connect"), wxDefaultPosition, wxDefaultSize, 0 ); 179 | bSizer3->Add( m_buttonConnect, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); 180 | 181 | m_buttonDisconnect = new wxButton( this, wxID_ANY, _("Disconnect"), wxDefaultPosition, wxDefaultSize, 0 ); 182 | m_buttonDisconnect->Enable( false ); 183 | 184 | bSizer3->Add( m_buttonDisconnect, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); 185 | 186 | bSizer2->Add( bSizer3, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); 187 | 188 | wxStaticBoxSizer* sbSizer1; 189 | sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Programm hardware with...") ), wxVERTICAL ); 190 | 191 | m_buttonProgramGenerator = new wxButton( this, wxID_ANY, _("rTMS - signal generator"), wxDefaultPosition, wxDefaultSize, 0 ); 192 | m_buttonProgramGenerator->Enable( false ); 193 | 194 | sbSizer1->Add( m_buttonProgramGenerator, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 195 | 196 | m_checkBoxWriteEEprom = new wxCheckBox( this, wxID_ANY, _("write the program to the EEPROM as well"), wxDefaultPosition, wxDefaultSize, 0 ); 197 | m_checkBoxWriteEEprom->SetValue(true); 198 | m_checkBoxWriteEEprom->Enable( false ); 199 | 200 | sbSizer1->Add( m_checkBoxWriteEEprom, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 201 | 202 | bSizer2->Add( sbSizer1, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); 203 | 204 | m_textCtrlLog = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY ); 205 | bSizer2->Add( m_textCtrlLog, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); 206 | 207 | wxBoxSizer* bSizer8; 208 | bSizer8 = new wxBoxSizer( wxHORIZONTAL ); 209 | 210 | m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); 211 | bSizer8->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); 212 | 213 | m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); 214 | bSizer8->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); 215 | 216 | bSizer2->Add( bSizer8, 0, wxALIGN_RIGHT, 5 ); 217 | 218 | this->SetSizer( bSizer2 ); 219 | this->Layout(); 220 | 221 | // Connect Events 222 | this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( GUISerialSetupDialog::OnClose ) ); 223 | m_buttonConnect->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUISerialSetupDialog::OnConnect ), NULL, this ); 224 | m_buttonDisconnect->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUISerialSetupDialog::OnDisconnect ), NULL, this ); 225 | m_buttonProgramGenerator->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUISerialSetupDialog::OnProgramGenerator ), NULL, this ); 226 | } 227 | 228 | GUISerialSetupDialog::~GUISerialSetupDialog() 229 | { 230 | // Disconnect Events 231 | this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( GUISerialSetupDialog::OnClose ) ); 232 | m_buttonConnect->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUISerialSetupDialog::OnConnect ), NULL, this ); 233 | m_buttonDisconnect->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUISerialSetupDialog::OnDisconnect ), NULL, this ); 234 | m_buttonProgramGenerator->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUISerialSetupDialog::OnProgramGenerator ), NULL, this ); 235 | } 236 | 237 | GUIControlCurrentsDialog::GUIControlCurrentsDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) 238 | { 239 | this->SetSizeHints( wxDefaultSize, wxDefaultSize ); 240 | 241 | wxBoxSizer* bSizer12; 242 | bSizer12 = new wxBoxSizer( wxVERTICAL ); 243 | 244 | wxFlexGridSizer* fgSizer1; 245 | fgSizer1 = new wxFlexGridSizer( 2, 8, 0, 0 ); 246 | fgSizer1->AddGrowableCol( 0 ); 247 | fgSizer1->AddGrowableCol( 1 ); 248 | fgSizer1->AddGrowableCol( 2 ); 249 | fgSizer1->AddGrowableCol( 3 ); 250 | fgSizer1->AddGrowableCol( 4 ); 251 | fgSizer1->AddGrowableCol( 5 ); 252 | fgSizer1->AddGrowableCol( 6 ); 253 | fgSizer1->AddGrowableCol( 7 ); 254 | fgSizer1->AddGrowableRow( 1 ); 255 | fgSizer1->SetFlexibleDirection( wxBOTH ); 256 | fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); 257 | 258 | m_staticText5 = new wxStaticText( this, wxID_ANY, _("Channel 0"), wxDefaultPosition, wxDefaultSize, 0 ); 259 | m_staticText5->Wrap( -1 ); 260 | fgSizer1->Add( m_staticText5, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 261 | 262 | m_staticText6 = new wxStaticText( this, wxID_ANY, _("Channel 1"), wxDefaultPosition, wxDefaultSize, 0 ); 263 | m_staticText6->Wrap( -1 ); 264 | fgSizer1->Add( m_staticText6, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 265 | 266 | m_staticText7 = new wxStaticText( this, wxID_ANY, _("Channel 2"), wxDefaultPosition, wxDefaultSize, 0 ); 267 | m_staticText7->Wrap( -1 ); 268 | fgSizer1->Add( m_staticText7, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 269 | 270 | m_staticText8 = new wxStaticText( this, wxID_ANY, _("Channel 3"), wxDefaultPosition, wxDefaultSize, 0 ); 271 | m_staticText8->Wrap( -1 ); 272 | fgSizer1->Add( m_staticText8, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 273 | 274 | m_staticText9 = new wxStaticText( this, wxID_ANY, _("Channel 4"), wxDefaultPosition, wxDefaultSize, 0 ); 275 | m_staticText9->Wrap( -1 ); 276 | fgSizer1->Add( m_staticText9, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 277 | 278 | m_staticText10 = new wxStaticText( this, wxID_ANY, _("Channel 5"), wxDefaultPosition, wxDefaultSize, 0 ); 279 | m_staticText10->Wrap( -1 ); 280 | fgSizer1->Add( m_staticText10, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 281 | 282 | m_staticText11 = new wxStaticText( this, wxID_ANY, _("Channel 6"), wxDefaultPosition, wxDefaultSize, 0 ); 283 | m_staticText11->Wrap( -1 ); 284 | fgSizer1->Add( m_staticText11, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 285 | 286 | m_staticText4 = new wxStaticText( this, wxID_ANY, _("Channel 7"), wxDefaultPosition, wxDefaultSize, 0 ); 287 | m_staticText4->Wrap( -1 ); 288 | fgSizer1->Add( m_staticText4, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); 289 | 290 | m_slider0 = new wxSlider( this, ID_CHANNEL0, 0, -250, 250, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_LABELS|wxSL_VERTICAL ); 291 | fgSizer1->Add( m_slider0, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); 292 | 293 | m_slider1 = new wxSlider( this, ID_CHANNEL1, 0, -250, 250, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_LABELS|wxSL_VERTICAL ); 294 | fgSizer1->Add( m_slider1, 1, wxALL|wxEXPAND, 5 ); 295 | 296 | m_slider2 = new wxSlider( this, ID_CHANNEL2, 0, -250, 250, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_LABELS|wxSL_VERTICAL ); 297 | fgSizer1->Add( m_slider2, 1, wxALL|wxEXPAND, 5 ); 298 | 299 | m_slider3 = new wxSlider( this, ID_CHANNEL3, 0, -250, 250, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_LABELS|wxSL_VERTICAL ); 300 | fgSizer1->Add( m_slider3, 1, wxALL|wxEXPAND, 5 ); 301 | 302 | m_slider4 = new wxSlider( this, ID_CHANNEL4, 0, -250, 250, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_LABELS|wxSL_VERTICAL ); 303 | fgSizer1->Add( m_slider4, 1, wxALL|wxEXPAND, 5 ); 304 | 305 | m_slider5 = new wxSlider( this, ID_CHANNEL5, 0, -250, 250, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_LABELS|wxSL_VERTICAL ); 306 | fgSizer1->Add( m_slider5, 1, wxALL|wxEXPAND, 5 ); 307 | 308 | m_slider6 = new wxSlider( this, ID_CHANNEL6, 0, -250, 250, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_LABELS|wxSL_VERTICAL ); 309 | fgSizer1->Add( m_slider6, 1, wxALL|wxEXPAND, 5 ); 310 | 311 | m_slider7 = new wxSlider( this, ID_CHANNEL7, 0, -250, 250, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_LABELS|wxSL_VERTICAL ); 312 | fgSizer1->Add( m_slider7, 1, wxALL|wxEXPAND, 5 ); 313 | 314 | bSizer12->Add( fgSizer1, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); 315 | 316 | m_buttonCancel = new wxButton( this, wxID_ANY, _("Close Dialog"), wxDefaultPosition, wxDefaultSize, 0 ); 317 | bSizer12->Add( m_buttonCancel, 0, wxALL|wxEXPAND, 5 ); 318 | 319 | this->SetSizer( bSizer12 ); 320 | this->Layout(); 321 | 322 | this->Centre( wxBOTH ); 323 | 324 | // Connect Events 325 | m_slider0->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll0 ), NULL, this ); 326 | m_slider1->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll1 ), NULL, this ); 327 | m_slider2->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll2 ), NULL, this ); 328 | m_slider3->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll3 ), NULL, this ); 329 | m_slider4->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll4 ), NULL, this ); 330 | m_slider5->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll5 ), NULL, this ); 331 | m_slider6->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll6 ), NULL, this ); 332 | m_slider7->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll7 ), NULL, this ); 333 | m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIControlCurrentsDialog::OnButtonClose ), NULL, this ); 334 | } 335 | 336 | GUIControlCurrentsDialog::~GUIControlCurrentsDialog() 337 | { 338 | // Disconnect Events 339 | m_slider0->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll0 ), NULL, this ); 340 | m_slider1->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll1 ), NULL, this ); 341 | m_slider2->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll2 ), NULL, this ); 342 | m_slider3->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll3 ), NULL, this ); 343 | m_slider4->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll4 ), NULL, this ); 344 | m_slider5->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll5 ), NULL, this ); 345 | m_slider6->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll6 ), NULL, this ); 346 | m_slider7->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( GUIControlCurrentsDialog::OnScroll7 ), NULL, this ); 347 | m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIControlCurrentsDialog::OnButtonClose ), NULL, this ); 348 | } 349 | -------------------------------------------------------------------------------- /ControlSoftware/src/gui/gui.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////// 2 | // C++ code generated with wxFormBuilder (version Dec 21 2009) 3 | // http://www.wxformbuilder.org/ 4 | // 5 | // PLEASE DO "NOT" EDIT THIS FILE! 6 | /////////////////////////////////////////////////////////////////////////// 7 | 8 | #ifndef __gui__ 9 | #define __gui__ 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "MainCanvas.h" 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | /////////////////////////////////////////////////////////////////////////// 35 | 36 | /////////////////////////////////////////////////////////////////////////////// 37 | /// Class GUIMainFrame 38 | /////////////////////////////////////////////////////////////////////////////// 39 | class GUIMainFrame : public wxFrame 40 | { 41 | private: 42 | 43 | protected: 44 | enum 45 | { 46 | ID_CONNECT = 1000, 47 | ID_CONTROLCURRENTS, 48 | ID_DISCONNECT, 49 | wxID_QUIT, 50 | wxID_SETUPSERIALPORT, 51 | }; 52 | 53 | wxStatusBar* m_statusBar; 54 | wxMenuBar* m_menubar; 55 | wxMenu* menuProject; 56 | wxMenu* menuSettings; 57 | wxMenu* menuHelp; 58 | MainCanvas* m_canvas; 59 | 60 | wxButton* m_buttonConnect; 61 | 62 | wxButton* m_buttonCurrents; 63 | 64 | wxButton* m_buttonDisconnect; 65 | 66 | 67 | // Virtual event handlers, overide them in your derived class 68 | virtual void OnConnect( wxCommandEvent& event ) { event.Skip(); } 69 | virtual void OnControlCurrents( wxCommandEvent& event ) { event.Skip(); } 70 | virtual void OnDisconnect( wxCommandEvent& event ) { event.Skip(); } 71 | virtual void OnQuit( wxCommandEvent& event ) { event.Skip(); } 72 | virtual void OnSetupHardware( wxCommandEvent& event ) { event.Skip(); } 73 | virtual void OnChangeLanguage( wxCommandEvent& event ) { event.Skip(); } 74 | virtual void OnAbout( wxCommandEvent& event ) { event.Skip(); } 75 | 76 | 77 | public: 78 | 79 | GUIMainFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Open-rTMS Control Center V0.2"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 518,350 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); 80 | ~GUIMainFrame(); 81 | 82 | }; 83 | 84 | /////////////////////////////////////////////////////////////////////////////// 85 | /// Class GUIAboutDialog 86 | /////////////////////////////////////////////////////////////////////////////// 87 | class GUIAboutDialog : public wxDialog 88 | { 89 | private: 90 | 91 | protected: 92 | wxTextCtrl* m_textCtrl2; 93 | wxButton* m_button; 94 | 95 | public: 96 | 97 | GUIAboutDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Open-rTMS About"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,400 ), long style = wxDEFAULT_DIALOG_STYLE ); 98 | ~GUIAboutDialog(); 99 | 100 | }; 101 | 102 | /////////////////////////////////////////////////////////////////////////////// 103 | /// Class GUISerialSetupDialog 104 | /////////////////////////////////////////////////////////////////////////////// 105 | class GUISerialSetupDialog : public wxDialog 106 | { 107 | private: 108 | 109 | protected: 110 | wxStaticText* m_staticText1; 111 | 112 | wxCheckBox* m_checkBoxOpenOnStartup; 113 | wxTextCtrl* m_textCtrlPort; 114 | wxButton* m_buttonConnect; 115 | wxButton* m_buttonDisconnect; 116 | wxButton* m_buttonProgramGenerator; 117 | wxCheckBox* m_checkBoxWriteEEprom; 118 | wxTextCtrl* m_textCtrlLog; 119 | wxButton* m_buttonOK; 120 | wxButton* m_buttonCancel; 121 | 122 | // Virtual event handlers, overide them in your derived class 123 | virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } 124 | virtual void OnConnect( wxCommandEvent& event ) { event.Skip(); } 125 | virtual void OnDisconnect( wxCommandEvent& event ) { event.Skip(); } 126 | virtual void OnProgramGenerator( wxCommandEvent& event ) { event.Skip(); } 127 | 128 | 129 | public: 130 | 131 | GUISerialSetupDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Open-rTMS Setup Serial Connection"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 454,454 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSTAY_ON_TOP ); 132 | ~GUISerialSetupDialog(); 133 | 134 | }; 135 | 136 | /////////////////////////////////////////////////////////////////////////////// 137 | /// Class GUIControlCurrentsDialog 138 | /////////////////////////////////////////////////////////////////////////////// 139 | class GUIControlCurrentsDialog : public wxDialog 140 | { 141 | private: 142 | 143 | protected: 144 | enum 145 | { 146 | ID_CHANNEL0 = 1000, 147 | ID_CHANNEL1, 148 | ID_CHANNEL2, 149 | ID_CHANNEL3, 150 | ID_CHANNEL4, 151 | ID_CHANNEL5, 152 | ID_CHANNEL6, 153 | ID_CHANNEL7, 154 | }; 155 | 156 | wxStaticText* m_staticText5; 157 | wxStaticText* m_staticText6; 158 | wxStaticText* m_staticText7; 159 | wxStaticText* m_staticText8; 160 | wxStaticText* m_staticText9; 161 | wxStaticText* m_staticText10; 162 | wxStaticText* m_staticText11; 163 | wxStaticText* m_staticText4; 164 | wxSlider* m_slider0; 165 | wxSlider* m_slider1; 166 | wxSlider* m_slider2; 167 | wxSlider* m_slider3; 168 | wxSlider* m_slider4; 169 | wxSlider* m_slider5; 170 | wxSlider* m_slider6; 171 | wxSlider* m_slider7; 172 | wxButton* m_buttonCancel; 173 | 174 | // Virtual event handlers, overide them in your derived class 175 | virtual void OnScroll0( wxScrollEvent& event ) { event.Skip(); } 176 | virtual void OnScroll1( wxScrollEvent& event ) { event.Skip(); } 177 | virtual void OnScroll2( wxScrollEvent& event ) { event.Skip(); } 178 | virtual void OnScroll3( wxScrollEvent& event ) { event.Skip(); } 179 | virtual void OnScroll4( wxScrollEvent& event ) { event.Skip(); } 180 | virtual void OnScroll5( wxScrollEvent& event ) { event.Skip(); } 181 | virtual void OnScroll6( wxScrollEvent& event ) { event.Skip(); } 182 | virtual void OnScroll7( wxScrollEvent& event ) { event.Skip(); } 183 | virtual void OnButtonClose( wxCommandEvent& event ) { event.Skip(); } 184 | 185 | 186 | public: 187 | 188 | GUIControlCurrentsDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Current Control"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 716,455 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); 189 | ~GUIControlCurrentsDialog(); 190 | 191 | }; 192 | 193 | #endif //__gui__ 194 | -------------------------------------------------------------------------------- /ControlSoftware/src/hardware/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | aux_source_directory(. files) 2 | add_library(hardware ${files}) 3 | -------------------------------------------------------------------------------- /ControlSoftware/src/hardware/ParallaxPropeller.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : ParallaxPropeller.cpp 3 | // Purpose : 4 | // Thread Safe : No 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 20.02.2012 9 | // Copyright : (C) 2012 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | #include "ParallaxPropeller.h" 32 | 33 | #include 34 | #include 35 | 36 | ParallaxPropeller::ParallaxPropeller(SerialPort* serial) 37 | { 38 | this->serial = serial; 39 | version = 0; 40 | log.Empty(); 41 | } 42 | 43 | ParallaxPropeller::~ParallaxPropeller() 44 | { 45 | 46 | } 47 | 48 | bool ParallaxPropeller::HandShake(void) 49 | { 50 | if(!serial->IsOpen()) return false; 51 | 52 | serial->SetDTR(true); 53 | ::wxMilliSleep(10); 54 | serial->SetDTR(false); 55 | ::wxMilliSleep(10); 56 | serial->SetDTR(true); 57 | ::wxMilliSleep(90); 58 | 59 | char temp[250]; 60 | 61 | 62 | // Flush old data on serial port. 63 | serial->FlushData(); 64 | 65 | temp[0] = 0xF9; 66 | serial->SendData(temp, 1); 67 | 68 | unsigned char LFSR = 0x50; 69 | unsigned int i; 70 | for(i = 0; i < 250; i++){ 71 | if(LFSR & 1){ 72 | temp[i] = 0xff; 73 | }else{ 74 | temp[i] = 0xfe; 75 | } 76 | LFSR = (LFSR << 1) | (((LFSR >> 7) ^ (LFSR >> 5) ^ (LFSR >> 4) ^ (LFSR 77 | >> 1)) & 1); 78 | } 79 | serial->SendData(temp, 250); 80 | serial->WaitTXFinish(); 81 | for(i = 0; i < 250; i++) 82 | temp[i] = 0xf9; 83 | serial->SendData(temp, 250); 84 | serial->WaitTXFinish(); 85 | ::wxMilliSleep(25); 86 | i = serial->ReadData(temp, 250); 87 | 88 | if(i == 0){ 89 | log += _T("No data received on this port!\n"); 90 | return false; 91 | } 92 | 93 | if(i != 250){ 94 | log 95 | += wxString::Format( 96 | _T("Identification sequence: Only %d of 250 bit received!\n"), 97 | i); 98 | return false; 99 | } 100 | for(i = 0; i < 250; i++){ 101 | if((unsigned char) temp[i] != (0xfe | (LFSR & 1))){ 102 | log 103 | += wxString::Format( 104 | _T("Bit %u in identification sequence is false!\n(received byte is 0x%02X instead of 0x%02X)\n"), 105 | i, temp[i], (0xfe | (LFSR & 1))); 106 | return false; 107 | } 108 | LFSR = (LFSR << 1) | (((LFSR >> 7) ^ (LFSR >> 5) ^ (LFSR >> 4) ^ (LFSR 109 | >> 1)) & 1); 110 | } 111 | // serial->WaitTXFinish(); 112 | // ::wxMilliSleep(10); 113 | // i = serial->ReadDataWaiting(); 114 | // log += wxString::Format(_T("%d RX bytes on port.\n"), i); 115 | 116 | temp[0] = 0xf9; 117 | for(i = 0; i < 8; i++){ 118 | serial->SendData(temp, 1); 119 | } 120 | serial->WaitTXFinish(); 121 | ::wxMilliSleep(1); 122 | i = serial->ReadData(temp, 250); 123 | 124 | if(i != 8){ 125 | log += wxString::Format( 126 | _T("Chip version: Only %d of 8 bit received!\n"), i); 127 | return false; 128 | } 129 | 130 | version = 0; 131 | for(i = 0; i < 8; i++){ 132 | version >>= 1; 133 | version |= ((temp[i] & 1) << 7); 134 | } 135 | return true; 136 | } 137 | 138 | void ParallaxPropeller::Transmit8(uint8_t val) 139 | { 140 | if(!serial->IsOpen()) return; 141 | unsigned char i; 142 | unsigned char temp[3]; 143 | temp[0] = 0x92; // = 0b10010010 = Bit 2 1 0 144 | temp[1] = 0x92; // = 0b10010010 = Bit 5 4 3 145 | temp[2] = 0xf2; // = 0b11110010 = Bit 7 6 146 | unsigned char p = 0; 147 | for(i = 0; i < 8; i++){ 148 | if((i % 3) == 0) temp[p] |= ((val & 1) << 0); 149 | if((i % 3) == 1) temp[p] |= ((val & 1) << 3); 150 | if((i % 3) == 2) temp[p++] |= ((val & 1) << 6); 151 | val >>= 1; 152 | } 153 | serial->SendData((char*) temp, 3); 154 | } 155 | void ParallaxPropeller::Transmit32(uint32_t val) 156 | { 157 | if(!serial->IsOpen()) return; 158 | unsigned char i; 159 | unsigned char temp[11]; 160 | for(i = 0; i < 10; i++) 161 | temp[i] = 0x92; 162 | temp[10] = 0xf2; 163 | unsigned char p = 0; 164 | for(i = 0; i < 32; i++){ 165 | if((i % 3) == 0) temp[p] |= ((val & 1) << 0); 166 | if((i % 3) == 1) temp[p] |= ((val & 1) << 3); 167 | if((i % 3) == 2) temp[p++] |= ((val & 1) << 6); 168 | val >>= 1; 169 | } 170 | serial->SendData((char*) temp, 11); 171 | } 172 | 173 | int ParallaxPropeller::GetVersion(void) 174 | { 175 | if(!HandShake()) return -1; 176 | serial->SetDTR(false); 177 | ::wxMilliSleep(10); 178 | serial->SetDTR(true); 179 | return version; 180 | } 181 | 182 | bool ParallaxPropeller::UploadAndStart(wxFileName filename, bool burnToEEPROM) 183 | { 184 | wxFile file; 185 | if(!file.Open(filename.GetFullPath(), wxFile::read)){ 186 | log += wxString::Format(_T("File could not be read!\n")); 187 | return false; 188 | } 189 | unsigned char buffer[32768]; 190 | size_t n = file.Read(buffer, 32768); 191 | if(n == 0){ 192 | log += wxString::Format(_T("File is empty!\n")); 193 | return false; 194 | } 195 | if(n < 16){ 196 | log += wxString::Format(_T("File has no header!\n")); 197 | return false; 198 | } 199 | if((n % 4) != 0){ 200 | log += wxString::Format(_T("Filelength is not a multitude of 4!\n")); 201 | return false; 202 | } 203 | 204 | log += wxString::Format(_T("%d bytes read from file.\n"), n); 205 | 206 | if(!HandShake()) return false; 207 | 208 | size_t i; 209 | // i = serial->ReadDataWaiting(); 210 | // log += wxString::Format(_T("%d RX bytes on port.\n"), i); 211 | 212 | 213 | if(burnToEEPROM){ 214 | Transmit32(3); // = Load RAM, write RAM to EEPROM, launch program. 215 | }else{ 216 | Transmit32(1); // = Load RAM, launch program. 217 | } 218 | 219 | // log += wxString::Format(_T("Prozess return.\n")); 220 | // return true; 221 | 222 | 223 | //n = 1300; 224 | 225 | Transmit32(n >> 2); // Number of longs in file 226 | serial->WaitTXFinish(); 227 | 228 | 229 | // size_t i; 230 | uint32_t val; 231 | for(i = 0; i < n; i += 4){ 232 | val = (buffer[i + 3] << 24) | (buffer[i + 2] << 16) | (buffer[i + 1] 233 | << 8) | (buffer[i + 0] << 0); 234 | // val = (buffer[i + 0] << 24) | (buffer[i + 1] << 16) | (buffer[i + 2] 235 | // << 8) | (buffer[i + 3] << 0); 236 | Transmit32(val); 237 | serial->WaitTXFinish(); 238 | } 239 | 240 | // Read back checksum result 241 | n = 0; 242 | char temp[10]; 243 | do{ 244 | temp[0] = 0xf9; 245 | serial->SendData(temp, 1); 246 | serial->WaitTXFinish(); 247 | ::wxMilliSleep(10); 248 | i = serial->ReadDataWaiting(); 249 | n++; 250 | }while(i == 0 && n < 100); 251 | 252 | if(i > 0){ 253 | i = serial->ReadData(temp, 10); 254 | } 255 | 256 | // log += wxString::Format(_T("Start nach %d Impulsen! (%.3f Sekunden)\n"), n, 257 | // (float) n * 9e-3); 258 | 259 | if(i != 1){ 260 | log += wxString::Format( 261 | _T("Wrong number of bytes received (Bytecount = %d)!\n"), 262 | i); 263 | 264 | if(i > 10) i = 10; 265 | for(n = 0; n < i; n++){ 266 | log += wxString::Format(_T("Byte %d = 0x%02X\n"), n, 267 | (unsigned char) temp[n]); 268 | } 269 | return false; 270 | } 271 | if((unsigned char) temp[0] != 0xFE){ 272 | log += wxString::Format( 273 | _T("Program verification failed!\n(Result = 0x%02X)\n"), 274 | (unsigned char) temp[0]); 275 | return false; 276 | } 277 | 278 | if(!burnToEEPROM) return true; 279 | 280 | // Burn data to EEPROM 281 | 282 | log += wxString::Format(_T("Programming EEPROM...\n")); 283 | temp[0] = 0xf9; 284 | n = 0; 285 | do{ 286 | serial->SendData(temp, 1); 287 | serial->WaitTXFinish(); 288 | ::wxMilliSleep(10); 289 | i = serial->ReadDataWaiting(); 290 | n++; 291 | }while(i == 0 && n < 300); 292 | 293 | if(i > 0) i = serial->ReadData(temp, 10); 294 | log += wxString::Format(_T("Programming took %.3f seconds.\n"), (float) n 295 | * 0.01); 296 | 297 | if(i != 1){ 298 | log += wxString::Format( 299 | _T("Wrong number of bytes received (Bytecount = %d)!\n"), 300 | i); 301 | 302 | if(i > 10) i = 10; 303 | for(n = 0; n < i; n++){ 304 | log += wxString::Format(_T("Byte %d = 0x%02X\n"), n, 305 | (unsigned char) temp[n]); 306 | } 307 | return false; 308 | } 309 | if((unsigned char) temp[0] != 0xFE){ 310 | log += wxString::Format( 311 | _T("Programming EEPROM failed!\n(Result = 0x%02X)\n"), 312 | (unsigned char) temp[0]); 313 | return false; 314 | } 315 | log += wxString::Format(_T("OK!\n")); 316 | 317 | 318 | // Verify EEPROM 319 | 320 | log += wxString::Format(_T("Verifying EEPROM...\n")); 321 | temp[0] = 0xf9; 322 | n = 0; 323 | do{ 324 | serial->SendData(temp, 1); 325 | serial->WaitTXFinish(); 326 | ::wxMilliSleep(10); 327 | i = serial->ReadDataWaiting(); 328 | n++; 329 | }while(i == 0 && n < 300); 330 | if(i > 0) i = serial->ReadData(temp, 10); 331 | 332 | log += wxString::Format(_T("Verification took %.3f seconds.\n"), (float) n 333 | * 0.01); 334 | 335 | if(i != 1){ 336 | log += wxString::Format( 337 | _T("Wrong number of bytes received (Bytecount = %d)!\n"), 338 | i); 339 | 340 | if(i > 10) i = 10; 341 | for(n = 0; n < i; n++){ 342 | log += wxString::Format(_T("Byte %d = 0x%02X\n"), n, 343 | (unsigned char) temp[n]); 344 | } 345 | return false; 346 | } 347 | if((unsigned char) temp[0] != 0xFE){ 348 | log += wxString::Format( 349 | _T("Verification of EEPROM failed!\n(Result = 0x%02X)\n"), 350 | (unsigned char) temp[0]); 351 | return false; 352 | } 353 | log += wxString::Format(_T("OK!\n")); 354 | 355 | return true; 356 | } 357 | 358 | -------------------------------------------------------------------------------- /ControlSoftware/src/hardware/ParallaxPropeller.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : ParallaxPropeller.h 3 | // Purpose : 4 | // Thread Safe : No 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 20.02.2012 9 | // Copyright : (C) 2012 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | #ifndef PARALLAXPROPELLER_H_ 32 | #define PARALLAXPROPELLER_H_ 33 | 34 | /*!\class ParallaxPropeller 35 | * \brief Programmer for a Parallax Propeller 36 | * 37 | * This class contains functions for Programming the RAM and also the I2C-EEPROM connected 38 | * to a Parallax Propeller CPU. 39 | * 40 | * http://propeller.wikispaces.com/Download+Protocol 41 | */ 42 | 43 | #include "SerialPort.h" 44 | 45 | #include 46 | #include 47 | #include 48 | 49 | class ParallaxPropeller { 50 | public: 51 | ParallaxPropeller(SerialPort* serial); 52 | virtual ~ParallaxPropeller(); 53 | 54 | // Member variables 55 | public: 56 | 57 | wxString log; 58 | 59 | private: 60 | SerialPort* serial; 61 | 62 | unsigned char version; 63 | 64 | // Member functions 65 | public: 66 | int GetVersion(void); 67 | bool UploadAndStart(wxFileName filename, bool burnToEEPROM = false); 68 | 69 | private: 70 | bool HandShake(void); 71 | void Transmit8(uint8_t val); 72 | void Transmit32(uint32_t val); 73 | 74 | }; 75 | 76 | #endif /* PARALLAXPROPELLER_H_ */ 77 | -------------------------------------------------------------------------------- /ControlSoftware/src/hardware/SerialPort.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : SerialPort.cpp 3 | // Purpose : A serial port class for Linux, Windows, and macOS. 4 | // Thread Safe : No 5 | // Platform dependent : Yes 6 | // Compiler Options : 7 | // Author : Tobias Schaefer, Samy Kamkar 8 | // Updated : 2020/02/20 9 | // Created : 08.09.2002 10 | // Copyright : (C) 2002 Tobias Schaefer 11 | // Licence : GNU General Public License version 3.0 (GPLv3) 12 | // 13 | // This program is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published by 15 | // the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This program is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | // 26 | //$LastChangedDate: 2010-05-04 01:09:07 +0200 (Di, 04 Mai 2010) $ 27 | //$Revision: 43 $ 28 | //$LastChangedBy: tobiassch $ 29 | /////////////////////////////////////////////////////////////////////////////// 30 | 31 | 32 | #include "SerialPort.h" 33 | 34 | //#include 35 | 36 | SerialPort::SerialPort() 37 | { 38 | #ifdef __WIN 39 | memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED)); 40 | memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED)); 41 | m_hIDComDev = NULL; 42 | #endif 43 | 44 | 45 | #if defined(__LINUX) || defined(__APPLE) 46 | buffer_RD = 0; 47 | buffer_WR = 0; 48 | #endif 49 | Error[0] = 0; 50 | Opened = false; 51 | szPort[0] = 0; 52 | } 53 | 54 | SerialPort::~SerialPort() 55 | { 56 | Close(); 57 | } 58 | 59 | bool SerialPort::Open(int nPort, int nBaud) 60 | { 61 | if(Opened) return (true); 62 | 63 | #ifdef __WIN 64 | wsprintf(szPort, "COM%d", nPort); 65 | #endif 66 | 67 | 68 | #if defined(__LINUX) || defined(__APPLE) 69 | if(nPort < 1) return false; 70 | sprintf(szPort, "/dev/ttyS%1i", nPort - 1); 71 | // sprintf (szPort, "/dev/ttyUSB0"); 72 | #endif 73 | //wxLogMessage(_T("sizeof(szPort)=%u"), sizeof(szPort)); 74 | return Open(szPort, nBaud); 75 | } 76 | 77 | bool SerialPort::Open(const char *Port, int nBaud) 78 | { 79 | if(Port == NULL) return false; 80 | if(Opened) return true; 81 | 82 | #ifdef __WIN 83 | 84 | char szComParams[50]; 85 | DCB dcb; 86 | 87 | wsprintf(szPort, "%s", Port); 88 | m_hIDComDev = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, 89 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); 90 | if(m_hIDComDev == NULL) return (FALSE); 91 | 92 | memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED)); 93 | memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED)); 94 | 95 | COMMTIMEOUTS CommTimeOuts; 96 | CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; 97 | CommTimeOuts.ReadTotalTimeoutMultiplier = 0; 98 | CommTimeOuts.ReadTotalTimeoutConstant = 0; 99 | CommTimeOuts.WriteTotalTimeoutMultiplier = 0; 100 | CommTimeOuts.WriteTotalTimeoutConstant = 5000; 101 | SetCommTimeouts(m_hIDComDev, &CommTimeOuts); 102 | 103 | wsprintf(szComParams, "%s:%d,n,8,1", Port, nBaud); 104 | 105 | m_OverlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 106 | m_OverlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 107 | 108 | dcb.DCBlength = sizeof(DCB); 109 | GetCommState(m_hIDComDev, &dcb); 110 | dcb.BaudRate = nBaud; 111 | dcb.ByteSize = 8; 112 | unsigned char ucSet; 113 | ucSet = (unsigned char) ((FC_RTSCTS & FC_DTRDSR) != 0); 114 | ucSet = (unsigned char) ((FC_RTSCTS & FC_RTSCTS) != 0); 115 | ucSet = (unsigned char) ((FC_RTSCTS & FC_XONXOFF) != 0); 116 | if(!SetCommState(m_hIDComDev, &dcb) 117 | || !SetupComm(m_hIDComDev, 10000, 10000) || m_OverlappedRead.hEvent 118 | == NULL || m_OverlappedWrite.hEvent == NULL){ 119 | //DWORD dwError = GetLastError(); 120 | if(m_OverlappedRead.hEvent != NULL) CloseHandle(m_OverlappedRead.hEvent); 121 | if(m_OverlappedWrite.hEvent != NULL) CloseHandle( 122 | m_OverlappedWrite.hEvent); 123 | CloseHandle(m_hIDComDev); 124 | return (FALSE); 125 | } 126 | 127 | #endif 128 | 129 | 130 | #if defined(__LINUX) || defined(__APPLE) 131 | 132 | 133 | // if (nPort < 1) return false; 134 | //if(!spezial) 135 | sprintf(szPort, "%s", Port); 136 | //else 137 | // sprintf (szPort, "/dev/ttyUSB0"); 138 | 139 | fd = open(szPort, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY); 140 | if(fd < 0) return false; 141 | 142 | fcntl(fd, F_SETFL, FNDELAY); // Disables delay on read = read does not block, when called and no data is available. 143 | 144 | tcgetattr(fd, &oldtio); 145 | bzero(&newtio, sizeof(newtio)); 146 | 147 | newtio.c_cflag = CLOCAL | CREAD; 148 | newtio.c_cflag |= CS8 | HUPCL; 149 | //newtio.c_cflag |= CRTSCTS; // Hardware flow control 150 | newtio.c_iflag = IGNPAR; 151 | 152 | 153 | // newtio.c_oflag &= ~OPOST; 154 | 155 | // Baudrate setzen 156 | 157 | bool flag = false; 158 | if(nBaud == 50){ 159 | cfsetispeed(&newtio, B50); 160 | cfsetospeed(&newtio, B50); 161 | flag = true; 162 | } 163 | if(nBaud == 75){ 164 | cfsetispeed(&newtio, B75); 165 | cfsetospeed(&newtio, B75); 166 | flag = true; 167 | } 168 | if(nBaud == 110){ 169 | cfsetispeed(&newtio, B110); 170 | cfsetospeed(&newtio, B110); 171 | flag = true; 172 | } 173 | if(nBaud == 134){ 174 | cfsetispeed(&newtio, B134); 175 | cfsetospeed(&newtio, B134); 176 | flag = true; 177 | } 178 | if(nBaud == 150){ 179 | cfsetispeed(&newtio, B150); 180 | cfsetospeed(&newtio, B150); 181 | flag = true; 182 | } 183 | if(nBaud == 200){ 184 | cfsetispeed(&newtio, B200); 185 | cfsetospeed(&newtio, B200); 186 | flag = true; 187 | } 188 | if(nBaud == 300){ 189 | cfsetispeed(&newtio, B300); 190 | cfsetospeed(&newtio, B300); 191 | flag = true; 192 | } 193 | if(nBaud == 600){ 194 | cfsetispeed(&newtio, B600); 195 | cfsetospeed(&newtio, B600); 196 | flag = true; 197 | } 198 | if(nBaud == 1200){ 199 | cfsetispeed(&newtio, B1200); 200 | cfsetospeed(&newtio, B1200); 201 | flag = true; 202 | } 203 | if(nBaud == 1800){ 204 | cfsetispeed(&newtio, B1800); 205 | cfsetospeed(&newtio, B1800); 206 | flag = true; 207 | } 208 | if(nBaud == 2400){ 209 | cfsetispeed(&newtio, B2400); 210 | cfsetospeed(&newtio, B2400); 211 | flag = true; 212 | } 213 | if(nBaud == 4800){ 214 | cfsetispeed(&newtio, B4800); 215 | cfsetospeed(&newtio, B4800); 216 | flag = true; 217 | } 218 | if(nBaud == 9600){ 219 | cfsetispeed(&newtio, B9600); 220 | cfsetospeed(&newtio, B9600); 221 | flag = true; 222 | } 223 | if(nBaud == 19200){ 224 | cfsetispeed(&newtio, B19200); 225 | cfsetospeed(&newtio, B19200); 226 | flag = true; 227 | } 228 | if(nBaud == 38400){ 229 | cfsetispeed(&newtio, B38400); 230 | cfsetospeed(&newtio, B38400); 231 | flag = true; 232 | } 233 | if(nBaud == 57600){ 234 | cfsetispeed(&newtio, B57600); 235 | cfsetospeed(&newtio, B57600); 236 | flag = true; 237 | } 238 | if(nBaud == 115200){ 239 | cfsetispeed(&newtio, B115200); 240 | cfsetospeed(&newtio, B115200); 241 | flag = true; 242 | } 243 | if(nBaud == 230400){ 244 | cfsetispeed(&newtio, B230400); 245 | cfsetospeed(&newtio, B230400); 246 | flag = true; 247 | } 248 | if(!flag) return false; 249 | 250 | tcsetattr(fd, TCSADRAIN, &newtio); // TCSADRAIN = Wait for pending transmissions to finish and change afterwards. 251 | 252 | #endif 253 | 254 | Opened = true; 255 | return (Opened); 256 | } 257 | 258 | bool SerialPort::Close(void) 259 | { 260 | if(!Opened) return true; 261 | 262 | #ifdef __WIN 263 | if(m_hIDComDev == NULL) return (TRUE); 264 | 265 | if(m_OverlappedRead.hEvent != NULL) CloseHandle(m_OverlappedRead.hEvent); 266 | if(m_OverlappedWrite.hEvent != NULL) CloseHandle(m_OverlappedWrite.hEvent); 267 | CloseHandle(m_hIDComDev); 268 | m_hIDComDev = NULL; 269 | #endif 270 | 271 | 272 | #if defined(__LINUX) || defined(__APPLE) 273 | 274 | oldtio.c_cflag = CLOCAL | CREAD; 275 | oldtio.c_cflag |= B0; // sideeffect: DTR turned off 276 | 277 | tcsetattr(fd, TCSANOW, &oldtio); 278 | close(fd); 279 | #endif 280 | 281 | Opened = false; 282 | // printf("Port wurde geschlossen!\n"); 283 | return (true); 284 | } 285 | 286 | #ifdef __WIN 287 | bool SerialPort::WriteCommByte(unsigned char ucByte) 288 | { 289 | 290 | BOOL bWriteStat; 291 | DWORD dwBytesWritten; 292 | 293 | bWriteStat = WriteFile(m_hIDComDev, (LPSTR) & ucByte, 1, &dwBytesWritten, 294 | &m_OverlappedWrite); 295 | if(!bWriteStat && (GetLastError() == ERROR_IO_PENDING)){ 296 | if(WaitForSingleObject(m_OverlappedWrite.hEvent, 1000)) 297 | dwBytesWritten = 0; 298 | else{ 299 | GetOverlappedResult(m_hIDComDev, &m_OverlappedWrite, 300 | &dwBytesWritten, FALSE); 301 | m_OverlappedWrite.Offset += dwBytesWritten; 302 | } 303 | } 304 | return (true); 305 | } 306 | #endif 307 | 308 | int SerialPort::SendData(char *buffer, unsigned int size) 309 | { 310 | #ifdef __WIN 311 | if(m_hIDComDev == NULL) return (0); 312 | 313 | DWORD dwBytesWritten = 0; 314 | unsigned int i; 315 | for(i = 0; i < size; i++){ 316 | WriteCommByte(buffer[i]); 317 | dwBytesWritten++; 318 | } 319 | 320 | return ((int) dwBytesWritten); 321 | #endif 322 | #if defined(__LINUX) || defined(__APPLE) 323 | if(!Opened) return 0; 324 | int dwBytesWritten = 0; 325 | 326 | dwBytesWritten = write(fd, buffer, size); 327 | return ((int) dwBytesWritten); 328 | #endif 329 | } 330 | 331 | int SerialPort::ReadDataWaiting(void) 332 | { 333 | #ifdef __WIN 334 | if(m_hIDComDev == NULL) return (0); 335 | 336 | DWORD dwErrorFlags; 337 | COMSTAT ComStat; 338 | 339 | ClearCommError(m_hIDComDev, &dwErrorFlags, &ComStat); 340 | 341 | return ((int) ComStat.cbInQue); 342 | #endif 343 | #if defined(__LINUX) || defined(__APPLE) 344 | if(!Opened) return 0; 345 | // tcflush(fd,TCIOFLUSH); 346 | while((buffer_WR + 1) % BUFFER_LEN != buffer_RD){ 347 | if(1 != read(fd, m_buffer + buffer_WR, 1)) break; 348 | buffer_WR++; 349 | buffer_WR %= BUFFER_LEN; 350 | } 351 | // sprintf(Error,"%d %d",buffer_WR,buffer_RD); 352 | return (buffer_WR - buffer_RD + BUFFER_LEN) % BUFFER_LEN; 353 | #endif 354 | } 355 | 356 | int SerialPort::ReadData(char *buffer, unsigned int limit) 357 | { 358 | #ifdef __WIN 359 | 360 | if(m_hIDComDev == NULL) return (0); 361 | 362 | BOOL bReadStatus; 363 | DWORD dwBytesRead, dwErrorFlags; 364 | COMSTAT ComStat; 365 | 366 | ClearCommError(m_hIDComDev, &dwErrorFlags, &ComStat); 367 | if(!ComStat.cbInQue) return (0); 368 | 369 | dwBytesRead = (DWORD) ComStat.cbInQue; 370 | if(limit < (int) dwBytesRead) dwBytesRead = (DWORD) limit; 371 | 372 | bReadStatus = ReadFile(m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, 373 | &m_OverlappedRead); 374 | if(!bReadStatus){ 375 | if(GetLastError() == ERROR_IO_PENDING){ 376 | WaitForSingleObject(m_OverlappedRead.hEvent, 2000); 377 | return ((int) dwBytesRead); 378 | } 379 | return (0); 380 | } 381 | 382 | return ((int) dwBytesRead); 383 | #endif 384 | #if defined(__LINUX) || defined(__APPLE) 385 | 386 | if(!Opened) return 0; 387 | 388 | unsigned int i = ReadDataWaiting(); 389 | unsigned int j; 390 | if(i > limit) i = limit; 391 | for(j = 0; j < i; j++) 392 | buffer[j] = m_buffer[(buffer_RD + j) % BUFFER_LEN]; 393 | buffer_RD += i; 394 | buffer_RD %= BUFFER_LEN; 395 | return i; 396 | #endif 397 | } 398 | 399 | void SerialPort::FlushData() 400 | { 401 | char Dummy[128]; 402 | unsigned int i = ReadDataWaiting(); 403 | unsigned int j, k; 404 | while(i != 0){ 405 | j = i; 406 | if(j > 128) j = 128; 407 | k = ReadData(Dummy, j); 408 | i -= k; 409 | } 410 | } 411 | 412 | void SerialPort::SetDTR(bool activate) 413 | { 414 | if(!Opened) return; 415 | 416 | #ifdef __WIN 417 | //TODO: Implement DTR on/off for windows! 418 | #error Not implemented! 419 | #endif 420 | 421 | 422 | #if defined(__LINUX) || defined(__APPLE) 423 | int dtr_bits = TIOCM_DTR; 424 | if(activate){ 425 | ioctl(fd, TIOCMBIS, &dtr_bits); 426 | }else{ 427 | ioctl(fd, TIOCMBIC, &dtr_bits); 428 | } 429 | #endif 430 | } 431 | 432 | void SerialPort::WaitTXFinish(void) 433 | { 434 | if(!Opened) return; 435 | tcdrain(fd); 436 | } 437 | 438 | -------------------------------------------------------------------------------- /ControlSoftware/src/hardware/SerialPort.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : SerialPort.h 3 | // Purpose : A serial port class for Linux, Windows, and macOS. 4 | // Thread Safe : No 5 | // Platform dependent : Yes 6 | // Compiler Options : 7 | // Authors : Tobias Schaefer, Samy Kamkar 8 | // Created : 08.09.2002 9 | // Copyright : (C) 2002 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: 2010-05-04 01:09:07 +0200 (Di, 04. Mai 2010) $ 26 | //$Revision: 43 $ 27 | //$LastChangedBy: tobiassch $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | #ifndef __SERIALPORT_H__ 31 | #define __SERIALPORT_H__ 32 | 33 | /*!\class SerialPort 34 | * \brief Serial port class for Linux, Windows, and macOS 35 | * 36 | * 37 | */ 38 | 39 | #define FC_DTRDSR 0x01 40 | #define FC_RTSCTS 0x02 41 | #define FC_XONXOFF 0x04 42 | #define ASCII_BEL 0x07 43 | #define ASCII_BS 0x08 44 | #define ASCII_LF 0x0A 45 | #define ASCII_CR 0x0D 46 | #define ASCII_XON 0x11 47 | #define ASCII_XOFF 0x13 48 | 49 | #define BUFFER_LEN 2100 50 | 51 | #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) 52 | #define __WIN 53 | #elif defined(linux) || defined(__linux) 54 | #define __LINUX 55 | #define __UNIX 56 | #elif defined(__APPLE__) 57 | #define __APPLE 58 | #define __UNIX 59 | #else 60 | #error "Requires Linux, Windows, or macOS (Weder Linux noch Windows gefunden)!" 61 | #endif 62 | 63 | #ifdef __WIN 64 | #include 65 | #endif 66 | 67 | #ifdef __LINUX 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | #define _POSIX_SOURCE 1 75 | #endif 76 | 77 | #ifdef __APPLE 78 | #include 79 | #include 80 | #include 81 | #include 82 | #include 83 | #include 84 | #include 85 | #include 86 | #define _POSIX_SOURCE 1 87 | #endif 88 | 89 | class SerialPort { 90 | 91 | public: 92 | SerialPort(); 93 | virtual ~SerialPort(); 94 | 95 | bool Open(int nPort = 2, int nBaud = 19200); 96 | bool Open(const char *Port = NULL, int nBaud = 19200); 97 | bool Close(void); 98 | 99 | int ReadData(char *, unsigned int); 100 | int SendData(char *, unsigned int); 101 | int ReadDataWaiting(void); 102 | void FlushData(void); 103 | bool IsOpen(void) 104 | { 105 | return (Opened); 106 | } 107 | char* GetName() 108 | { 109 | return (szPort); 110 | } 111 | void SetDTR(bool activate); 112 | void WaitTXFinish(void); 113 | 114 | protected: 115 | bool Opened; 116 | 117 | char szPort[15]; ///> Name of the open port. 118 | 119 | #ifdef __WIN 120 | bool WriteCommByte( unsigned char ); 121 | HANDLE m_hIDComDev; 122 | OVERLAPPED m_OverlappedRead, m_OverlappedWrite; 123 | #endif 124 | 125 | 126 | #if defined(__LINUX) || defined(__APPLE) 127 | int fd, c, res; 128 | unsigned int buffer_RD, buffer_WR; 129 | char m_buffer[BUFFER_LEN]; 130 | struct termios oldtio, newtio; 131 | 132 | #endif 133 | 134 | public: 135 | char Error[200]; 136 | 137 | }; 138 | 139 | #endif // __SERIALPORT_H__ 140 | -------------------------------------------------------------------------------- /ControlSoftware/src/icon/logo.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * logo_xpm[] = { 3 | "32 32 118 2", 4 | " c None", 5 | ". c #FFFFFF", 6 | "+ c #FDF5F0", 7 | "@ c #FBE2D3", 8 | "# c #F7C3A4", 9 | "$ c #F4A87A", 10 | "% c #F29D69", 11 | "& c #F1955C", 12 | "* c #F39F6D", 13 | "= c #F3A677", 14 | "- c #F7C5A7", 15 | "; c #F9D4BE", 16 | "> c #FDF0E8", 17 | ", c #FEF7F4", 18 | "' c #FDEFE7", 19 | ") c #F8CAAF", 20 | "! c #F08D51", 21 | "~ c #ED7126", 22 | "{ c #EC6A1C", 23 | "] c #EC6818", 24 | "^ c #3B1A06", 25 | "/ c #EF8341", 26 | "( c #F1955D", 27 | "_ c #F9D3BC", 28 | ": c #FCECE2", 29 | "< c #F6BC99", 30 | "[ c #EE7831", 31 | "} c #000000", 32 | "| c #583520", 33 | "1 c #CB9C7F", 34 | "2 c #FCE7DB", 35 | "3 c #FDF6F2", 36 | "4 c #FEFEFE", 37 | "5 c #F29A65", 38 | "6 c #C35613", 39 | "7 c #562608", 40 | "8 c #76340C", 41 | "9 c #622B09", 42 | "0 c #E66517", 43 | "a c #EF8443", 44 | "b c #F6B893", 45 | "c c #FCEEE5", 46 | "d c #F3A06E", 47 | "e c #75330B", 48 | "f c #BD5313", 49 | "g c #2E1404", 50 | "h c #F0894B", 51 | "i c #F8CCB2", 52 | "j c #FAD9C5", 53 | "k c #5F2A09", 54 | "l c #D45D15", 55 | "m c #F8CDB2", 56 | "n c #F5B38B", 57 | "o c #251003", 58 | "p c #461E07", 59 | "q c #170A02", 60 | "r c #F08B4E", 61 | "s c #EE7A34", 62 | "t c #2F1404", 63 | "u c #FADBC8", 64 | "v c #ED762D", 65 | "w c #301504", 66 | "x c #1D0D03", 67 | "y c #F9D5BF", 68 | "z c #F29964", 69 | "A c #F9D6C1", 70 | "B c #F7C6A8", 71 | "C c #F08C50", 72 | "D c #EE7C37", 73 | "E c #FADCC9", 74 | "F c #EE7F41", 75 | "G c #EC5B18", 76 | "H c #EC5118", 77 | "I c #EC6418", 78 | "J c #F7B9A7", 79 | "K c #ED512E", 80 | "L c #EC3718", 81 | "M c #EC3518", 82 | "N c #EC3918", 83 | "O c #EC4B18", 84 | "P c #EC6218", 85 | "Q c #2B1304", 86 | "R c #F6A599", 87 | "S c #EC3C20", 88 | "T c #EC3618", 89 | "U c #EC4A18", 90 | "V c #EC6118", 91 | "W c #C35513", 92 | "X c #8C3D0E", 93 | "Y c #F3A16F", 94 | "Z c #F6A79A", 95 | "` c #EC3B1F", 96 | " . c #EC4018", 97 | ".. c #EC5818", 98 | "+. c #F9D1BA", 99 | "@. c #FACCC5", 100 | "#. c #EF5A43", 101 | "$. c #EC4218", 102 | "%. c #F6BF9D", 103 | "&. c #FDF2F0", 104 | "*. c #F7B2A7", 105 | "=. c #EC3D21", 106 | "-. c #FEFAF9", 107 | ";. c #EC3B20", 108 | ">. c #F2886C", 109 | ",. c #F8C9AD", 110 | "'. c #FCE9DD", 111 | "). c #FEF7F3", 112 | "!. c #EC3619", 113 | "~. c #EC391D", 114 | "{. c #F1715D", 115 | "]. c #FEF5F4", 116 | "^. c #F2816F", 117 | "/. c #FCE1DD", 118 | "(. c #F8BAB0", 119 | "_. c #FBD7D1", 120 | ":. c #F8BEB5", 121 | "<. c #EC371A", 122 | ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", 123 | ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", 124 | ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", 125 | ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", 126 | ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", 127 | ". . . . . . . . + @ # $ % & * = - ; > , . . . . . . . . . . . . ", 128 | ". . . . . . ' ) ! ~ { ] ] ] ^ ] ] ] / ( _ : . . . . . . . . . . ", 129 | ". . . . : < [ ] ] ] ] ] ] ] ^ } ] ] ] ] ] ] | 1 2 3 4 . . . . . ", 130 | ". . . : 5 6 7 8 8 8 ] ] ] ^ 8 ] ] ] ] ] ] 8 9 0 a b c 4 . . . . ", 131 | ". . : d ] 0 6 e } e ] f g e ] ] ] ] ] ] ] ] } ] ] ] h i 4 . . . ", 132 | ". . j ! ] ] ] g k f ] g } } ] ] ] ] ] ] ] 8 } l ] ] ] ] m 4 . . ", 133 | ". . n ] ] ] ] f ^ g ] f o 8 8 ] 8 8 ] ] ] ^ p l ] ] ] ] ] i 4 . ", 134 | ". . n ] ] ] 8 q e ] ] ] ] q e f } 8 } 8 8 8 8 8 ] ] 8 ] ] r c 4 ", 135 | ". . n ] ] ] 8 8 ] ] ] ] 8 o f o g ] ] k g ] f g ] 8 ^ ] ] ] < 3 ", 136 | ". . j s ] ] ] 8 } ] ] ] e ] ] ] f ] ] ] ] ] ] g f 8 8 ] ] ] & c ", 137 | ". . : a ] ] 8 t f f ] ] ] ] ] ] o q g ] ] ] ] 8 8 } ] ] ] ] ] u ", 138 | ". . . ) v ] ] g g g ] ] f ] ] ] q w f ] ] ] ] x x 8 ] ] ] ] ] y ", 139 | ". . . : z ] ] ] ] } 8 8 g ] ] ] q k ] ] ] ] g k ] ] ] ] ] ] ] ) ", 140 | ". . . . : d ] ] ] ] e e ] ] ] ] f q f ] ] f g ] ] ] ] ^ } g ] A ", 141 | ". . . . . : B C ] ] [ r / D ] ] ] 8 g ] ] ] ] ] ] ] ^ ^ o o ] E ", 142 | ". . . . . . . . . . . . . 4 i F G H H G I ] ] ] ] } ^ ] ] ] ] > ", 143 | ". . . . . . . . . . . . . . 4 J K L M N O P ] Q 9 ] l l ] ] ] , ", 144 | ". . . . . . . . . . . . . . . R S M M M T U V W 0 ] X X ] ] Y . ", 145 | ". . . . . . . . . . . . . . . Z ` M M M M M ...I ] ] 8 8 ] +.. ", 146 | ". . . . . . . . . . . . . . . @.#.M M M M M M $.G ] ] ] ] %., . ", 147 | ". . . . . . . . . . . . . . . &.*.=.M M M M M L H ] ] C %., . . ", 148 | ". . . . . . . . . . . . . . . . -.;.M M M M M =.>.,.y '.).. . . ", 149 | ". . . . . . . . . . . . . . . . . !.M M M M ~.{.@.. . . . . . . ", 150 | ". . . . . . . . . . . . . . . . ].M M M M M ^.@.&.. . . . . . . ", 151 | ". . . . . . . . . . . . . . . . /.M M M M M (.. . . . . . . . . ", 152 | ". . . . . . . . . . . . . . . . _.M M M M M :.. . . . . . . . . ", 153 | ". . . . . . . . . . . . . . . . /.<.M M M !._.. . . . . . . . . "}; 154 | -------------------------------------------------------------------------------- /ControlSoftware/src/languages.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Name : languages.h 3 | // Purpose : Definition of the supported languages. 4 | // Thread Safe : Yes 5 | // Platform dependent : No 6 | // Compiler Options : 7 | // Author : Tobias Schaefer 8 | // Created : 11.12.2011 9 | // Copyright : (C) 2011 Tobias Schaefer 10 | // Licence : GNU General Public License version 3.0 (GPLv3) 11 | // 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // 17 | // This program is distributed in the hope that it will be useful, 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | // GNU General Public License for more details. 21 | // 22 | // You should have received a copy of the GNU General Public License 23 | // along with this program. If not, see . 24 | // 25 | //$LastChangedDate: $ 26 | //$Revision: $ 27 | //$LastChangedBy: $ 28 | /////////////////////////////////////////////////////////////////////////////// 29 | 30 | 31 | #ifndef LANGUAGES_H_ 32 | #define LANGUAGES_H_ 33 | 34 | /*!\class languages 35 | * \brief Definition of the languages provided in the i18n directory. 36 | */ 37 | 38 | #include 39 | #include 40 | 41 | // language data 42 | static const wxLanguage langIds[] = 43 | {wxLANGUAGE_DEFAULT, wxLANGUAGE_ENGLISH, wxLANGUAGE_GERMAN}; 44 | 45 | const wxString langNames[] = 46 | {_T("System default"), _T("English"), _T("German")}; 47 | 48 | // the arrays must be in sync 49 | wxCOMPILE_TIME_ASSERT( WXSIZEOF(langNames) == WXSIZEOF(langIds), 50 | LangArraysMismatch ); 51 | 52 | #endif /* LANGUAGES_H_ */ 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openrTMS 2 | 3 | Open rTMS (Transcranial Magnetic Stimulation) 4 | 5 | This is a fork based off of the [Open rTMS (v_0_2)](https://sourceforge.net/p/open-rtms/) project last updated in 2014. 6 | 7 | ### New Features (2021) 8 | 9 | - macOS support (including OpenGL + wxWidgets) 10 | 11 | ### Hardware 12 | 13 | - [Eagle design files](SignalGenerator/eagle/) 14 | 15 | ### Firmware 16 | 17 | - [Firmware](SignalGenerator/spin/) 18 | 19 | ### Software 20 | 21 | - [Windows/Linux/macOS software](ControlSoftware/) 22 | -------------------------------------------------------------------------------- /SignalGenerator/eagle/Generator_V0.9.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/SignalGenerator/eagle/Generator_V0.9.brd -------------------------------------------------------------------------------- /SignalGenerator/eagle/Generator_V0.9.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/SignalGenerator/eagle/Generator_V0.9.sch -------------------------------------------------------------------------------- /SignalGenerator/spin/EightChannelDAC.spin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/SignalGenerator/spin/EightChannelDAC.spin -------------------------------------------------------------------------------- /SignalGenerator/spin/Testbench_VGAOverlay.spin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/SignalGenerator/spin/Testbench_VGAOverlay.spin -------------------------------------------------------------------------------- /SignalGenerator/spin/TextDriver16x16.spin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/SignalGenerator/spin/TextDriver16x16.spin -------------------------------------------------------------------------------- /SignalGenerator/spin/TextDriver16x32.spin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/SignalGenerator/spin/TextDriver16x32.spin -------------------------------------------------------------------------------- /SignalGenerator/spin/firmware_openrtms_h09_20130202.binary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/SignalGenerator/spin/firmware_openrtms_h09_20130202.binary -------------------------------------------------------------------------------- /SignalGenerator/spin/firmware_openrtms_h09_20130202.spin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/openrTMS/75d19ac1585918a31ec3278edfc86e2764106f3a/SignalGenerator/spin/firmware_openrtms_h09_20130202.spin --------------------------------------------------------------------------------