├── .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 |
27 |
28 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
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 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
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
--------------------------------------------------------------------------------