├── LICENSE
├── README.md
├── background.jpg
├── background.png
├── background2.jpg
├── background2.png
├── background3-2.png
├── background3.png
├── content.cpp
├── content.h
├── demo6.pro
├── highway.cpp
├── highway.h
├── key.cpp
├── key.h
├── main.cpp
├── navdata.cpp
├── navdata.h
├── plotter.cpp
├── plotter.h
├── posix_qextserialport.cpp
├── posix_qextserialport.h
├── qextserialbase.cpp
├── qextserialbase.h
├── sea.jpg
├── src.qrc
├── stable.h
├── steering.cpp
├── steering.h
├── style.qss
├── um220.cpp
└── um220.h
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 | {one line to give the program's name and a brief idea of what it does.}
635 | Copyright (C) {year} {name of author}
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | {project} Copyright (C) {year} {fullname}
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ##handheld-navigator手持导航仪
2 |
3 | 本项目为一个基于qt4和嵌入式linux系统的简易北斗导航仪,功能界面模仿自Furuno GP30船载导航仪。为学习QtE和C++时做的demo。
4 |
5 | ----------
6 |
7 | ###线程
8 | 本项目定义为在海船上使用的导航仪,故最重要的功能是卫星数据的接收与显示,且使用按键操作。由于基于嵌入式Linux设备,故使用一个独立的线程定时进行串口读取,并同时用这个定时器完成界面的刷新;又编写自定义驱动,通过阻塞方式获取按键数据,再通过信号与槽方式实现功能。
9 |
10 | ###按键
11 | 本项目使用了六个按键,分别是四个方向键和一个确认键,一个界面切换键。
12 |
13 | ###数据抽象
14 |
15 | - 卫星、按键数据的实现作为全局变量在main.cpp中被创建,在各个子界面中作为外部变量被使用。
16 | - 储存途径点坐标的链表的实现作为全局变量在plotter.cpp中被创建,在各个子界面中作为外部变量被使用。
17 |
18 | ###子界面
19 | 为显示四个功能界面,主框架为一QStackedWidget,各子界面继承自QWidget。通过按键可循环切换四个页面。
20 |
21 | 1. navdata:显示时间、经纬度、速度、航向角
22 | 2. plotter:显示经纬度、速度、航向角,以及一图形化的途径点设置界面(QGraphicsView实现)
23 | 3. highway:显示航向角、方向角、速度、到途径点距离,以及一图形化仿3D导航界面(QPainter实现)
24 | 4. sterring:显示航向角、方向角、速度、到途径时间,以及一图形化仿罗盘导航界面(QPainter实现)
25 |
26 | ###美化
27 | 为了实现自适应分辨率,各个界面在获取设备分辨率后按比例绘制。并使用qss加上贴图和立体效果。
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azure42/handheld-navigator/2617750d3ff74949b30552ff1d5ae7fdf3922920/background.jpg
--------------------------------------------------------------------------------
/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azure42/handheld-navigator/2617750d3ff74949b30552ff1d5ae7fdf3922920/background.png
--------------------------------------------------------------------------------
/background2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azure42/handheld-navigator/2617750d3ff74949b30552ff1d5ae7fdf3922920/background2.jpg
--------------------------------------------------------------------------------
/background2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azure42/handheld-navigator/2617750d3ff74949b30552ff1d5ae7fdf3922920/background2.png
--------------------------------------------------------------------------------
/background3-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azure42/handheld-navigator/2617750d3ff74949b30552ff1d5ae7fdf3922920/background3-2.png
--------------------------------------------------------------------------------
/background3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azure42/handheld-navigator/2617750d3ff74949b30552ff1d5ae7fdf3922920/background3.png
--------------------------------------------------------------------------------
/content.cpp:
--------------------------------------------------------------------------------
1 | #include "content.h"
2 | Content::Content(QWidget *parent):
3 | QFrame(parent)
4 | {
5 | stack =new QStackedWidget();
6 | // stack->setFrameStyle(QFrame::Panel|QFrame::Raised);//视觉风格
7 | stack->setFrameStyle(QFrame::Box|QFrame::Plain);
8 | navdata =new NavData();
9 | plotter =new Plotter();//栈内的三个页面
10 | highway =new Highway();
11 | steering = new Steering();
12 | // readKeyThread = new readKey;
13 | stack->addWidget(navdata);//添加三个页面对象到栈
14 | stack->addWidget(plotter);
15 | stack->addWidget(highway);
16 | stack->addWidget(steering);
17 |
18 | QVBoxLayout *RightLayout =new QVBoxLayout(this);//右侧布局为一个整体,由页面和按钮构成,为竖直布局
19 | RightLayout->addWidget(stack);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/content.h:
--------------------------------------------------------------------------------
1 | #ifndef _CONTENT_H_
2 | #define _CONTENT_H_
3 | //添加的头文件
4 | //#include "stable.h"
5 | #include "navdata.h"
6 | #include "plotter.h"
7 | #include "highway.h"
8 | #include "steering.h"
9 | #include "key.h"
10 |
11 | class Content : public QFrame
12 | {
13 | Q_OBJECT
14 | public:
15 | Content(QWidget *parent=0);
16 | QStackedWidget *stack;
17 |
18 | NavData *navdata;
19 | Plotter *plotter;
20 | Highway *highway;
21 | Steering *steering;
22 | // readKey *readKeyThread;
23 | };
24 | #endif
25 |
--------------------------------------------------------------------------------
/demo6.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2016-03-10T21:32:02
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += core gui
8 |
9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
10 |
11 | TARGET = demo6
12 | TEMPLATE = app
13 |
14 | PRECOMPILED_HEADER = stable.h
15 | precompile_header:!isEmpty(PRECOMPILED_HEADER) {
16 |
17 | DEFINES += USING_DEBUG
18 |
19 | }
20 |
21 | SOURCES += \
22 | plotter.cpp \
23 | navdata.cpp \
24 | highway.cpp \
25 | main.cpp \
26 | key.cpp \
27 | content.cpp \
28 | steering.cpp \
29 | um220.cpp \
30 | qextserialbase.cpp \
31 | posix_qextserialport.cpp
32 |
33 | HEADERS += \
34 | navdata.h \
35 | plotter.h \
36 | steering.h \
37 | um220.h \
38 | highway.h \
39 | key.h \
40 | content.h \
41 | stable.h \
42 | qextserialbase.h \
43 | posix_qextserialport.h
44 |
45 | FORMS +=
46 |
47 | RESOURCES += \
48 | src.qrc
49 |
50 | OTHER_FILES +=
51 |
--------------------------------------------------------------------------------
/highway.cpp:
--------------------------------------------------------------------------------
1 | #include "highway.h"
2 | #include"QFont"
3 | #include"math.h"
4 | #include"key.h"
5 | extern class um220 *beidouData;
6 | extern QLinkedList pointList;
7 | int i=1;
8 | Highway::Highway(QWidget *parent) :
9 | QWidget(parent)
10 | {
11 | QCursor cursor ;
12 | cursor = QCursor(Qt::BlankCursor);
13 | setCursor(cursor);
14 |
15 | timer = new QTimer();
16 | QObject::connect(timer,SIGNAL(timeout()),this,SLOT(showTime()));
17 | timer->start(200);
18 |
19 | QFont font;
20 | font.setPointSize(30);
21 |
22 | brgLabel =new QLabel(tr("BRG"));
23 | brgLabel->setFont(font);
24 | cseLabel =new QLabel(tr("CSE"));
25 | cseLabel->setFont(font);
26 | rngLabel =new QLabel(tr("RNG"));
27 | rngLabel->setFont(font);
28 | spdLabel =new QLabel(tr("SPD"));
29 | spdLabel->setFont(font);
30 | hwPainting = new hwPaintingWidget;
31 | hwPainting->show();
32 |
33 |
34 | mainLayout = new QGridLayout(this);
35 | mainLayout->addWidget(brgLabel,0,0);
36 | mainLayout->addWidget(cseLabel,1,0);
37 | mainLayout->addWidget(spdLabel,2,0);
38 | mainLayout->addWidget(rngLabel,3,0);
39 | mainLayout->addWidget(hwPainting,0,1,4,4);
40 |
41 | //mainLayout->setSizeConstraint(QLayout::SetFixedSize);
42 | }
43 |
44 |
45 |
46 | void hwPaintingWidget::paintEvent(QPaintEvent *event)
47 | {
48 |
49 | pWidth=(QApplication::desktop()->width()-5*10)*4/5;
50 | pHeight=QApplication::desktop()->height()-4*10;
51 | //手动计算paintingWidget的尺寸
52 |
53 | static const QPoint arrow[3] =
54 | {
55 | QPoint(pWidth/40, pHeight/5),
56 | QPoint(-pWidth/40, pHeight/5),
57 | QPoint(0, -pHeight/5)
58 | };
59 | static const QPoint arrow2[3] =
60 | {
61 | QPoint(pWidth/20, 0),
62 | QPoint(-pWidth/20, 0),
63 | QPoint(0, -pHeight/10)
64 | };
65 |
66 | setAutoFillBackground(true);
67 | QPalette palette;
68 | // palette.setColor(QPalette::Background, Qt::white);
69 | setPalette(palette);
70 |
71 | QPainter painter(this);
72 | painter.setRenderHint(QPainter::Antialiasing);
73 |
74 | //绘制边界线
75 | painter.drawLine(0,pHeight*7/8,pWidth,pHeight*7/8);//下
76 | painter.drawLine(pWidth*2/9,0,0,pHeight*7/8);//左
77 | painter.drawLine(pWidth*7/9,0,pWidth,pHeight*7/8);//右
78 | painter.drawLine(pWidth/2,0,pWidth/2,pHeight*7/8);//中
79 |
80 | //绘制标尺
81 | for(int i=1;i<8;i++)
82 | {
83 | painter.drawLine(pWidth/8*i,pHeight*7/8,pWidth/8*i,pHeight*7/8-pHeight/20);
84 | }
85 |
86 | double brg;
87 | if(pointList.isEmpty() == false)
88 | {//若存在途径点,则显示下一目标编号
89 | QFont font;
90 | font.setPixelSize(35);
91 | painter.setFont(font);
92 | painter.drawText(QPoint(10,10),QString::number(i));
93 | brg = beidouData->brgGet(pointList.first()) ;
94 | }
95 | else
96 | {//否则显示演示角度
97 | brg = -45;
98 | // painter.drawText(QPoint(pWidth / 3,pHeight /8),QString("NO Point selected(-45°for example)"));
99 | }
100 | // painter.drawLine(QPoint(pWidth / 2,pHeight /8),QPoint(pWidth,pHeight));
101 |
102 | //绘制航向标(蓝色)
103 | painter.translate(pWidth / 2, pHeight / 2);
104 | painter.save();
105 | painter.translate(0, pHeight / 4);
106 | painter.setPen(Qt::NoPen);
107 | painter.setBrush(Qt::darkCyan);
108 | painter.rotate(brg);
109 | painter.drawConvexPolygon(arrow, 3);
110 |
111 | //绘制船位指示标(红色)
112 | painter.restore();//以画布中央为初始位置
113 | painter.translate(-1*brg/180*pWidth , //横向移动
114 | pHeight / 2); //纵向移动
115 | painter.setBrush(Qt::darkRed);
116 | painter.drawConvexPolygon(arrow2, 3);
117 | }
118 |
119 |
120 | void Highway::showTime()
121 | {
122 | if(pointList.isEmpty() == false
123 | &&pointList.first().x()-beidouData->Lon.toDouble()<1.0
124 | &&pointList.first().x()-beidouData->Lon.toDouble()<1.0)
125 | //船在目标点方圆一海里以内,视为到达
126 | {
127 | pointList.removeFirst();
128 | i++;
129 | }
130 | cseString = "CSE:";
131 | cseString.append(beidouData->cog);
132 | cseString.append("°");
133 | cseLabel->setText(cseString);
134 |
135 | brgString = "BRG:";
136 | brgString.append(beidouData->cog);
137 | brgString.append("°");
138 | brgLabel->setText(brgString);
139 |
140 | rngString = "RNG:";
141 | if (pointList.isEmpty()==false)
142 | rngString.append(QString::number(beidouData->rngGet(pointList.first())));
143 | rngString.append(" NM");
144 | rngLabel->setText(rngString);
145 |
146 | spdString = "SPD:";
147 | spdString.append(beidouData->spd);
148 | spdString.append("knot");
149 | spdLabel->setText(spdString);
150 |
151 | update();
152 | hwPainting->update();
153 | }
154 |
155 |
--------------------------------------------------------------------------------
/highway.h:
--------------------------------------------------------------------------------
1 | #ifndef _HIGHWAY_H_
2 | #define _HIGHWAY_H_
3 |
4 | #include "stable.h"
5 | #include "um220.h"
6 |
7 | class hwPaintingWidget : public QWidget
8 | {
9 | Q_OBJECT
10 | public:
11 | double angelCalc(QPointF);
12 | protected:
13 |
14 | void paintEvent(QPaintEvent *event);
15 | int pWidth,pHeight;
16 | private:
17 |
18 | //private slots:
19 | // void showTime();
20 |
21 | };
22 |
23 | class Highway : public QWidget
24 | {
25 | Q_OBJECT
26 | public:
27 | Highway(QWidget *parent=0);
28 |
29 | private:
30 | QTimer *timer;
31 | QLabel *brgLabel;
32 | QLabel *rngLabel;
33 | QLabel *spdLabel;
34 | QLabel *cseLabel;
35 |
36 | QString cseString;
37 | QString brgString;
38 | QString rngString;
39 | QString spdString;
40 |
41 | QGridLayout *mainLayout;
42 | protected:
43 | // void paintEvent(QPaintEvent *event);
44 | hwPaintingWidget *hwPainting;
45 |
46 | private slots:
47 | void showTime();
48 | };
49 |
50 |
51 |
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/key.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | //#include
7 |
8 | #define KEYCOUNTS 6
9 |
10 | readKey::readKey(QObject *parent) :
11 | QThread(parent)
12 | {
13 | initFlag = false;
14 | indexNum = 1;
15 | }
16 |
17 | //void readKey::keyPressEvent(QKeyEvent *event)
18 | //{
19 | // switch(event->key())
20 | // {
21 | // case Qt::Key_Enter:
22 | // {
23 | // qDebug()<<"!!";
24 | // }break;
25 |
26 | // }
27 | //}
28 |
29 |
30 | void readKey::run()
31 | {
32 | int keyValue[KEYCOUNTS];
33 | int i;
34 | while(1)
35 | {
36 | if( !initFlag )
37 | {
38 | fd = open("/dev/key",0);
39 | initFlag = ~initFlag;
40 | }
41 |
42 | read(fd,keyValue, sizeof(keyValue));
43 |
44 | for(i=0; i
6 |
7 | class readKey : public QThread
8 | {
9 | Q_OBJECT
10 | public:
11 | explicit readKey(QObject *parent = 0);
12 | // void keyInit();
13 | volatile int indexNum;
14 | protected:
15 | void keyPressEvent(QKeyEvent *event);
16 | private:
17 | volatile bool initFlag;
18 | volatile int fd;
19 |
20 | void run();
21 | signals:
22 | void disSwitch(int);
23 | void dirKey(int);
24 | public slots:
25 |
26 | };
27 |
28 | #endif // KEY_H
29 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include "content.h"
2 | #include "um220.h"
3 | #include "key.h"
4 |
5 | um220 *beidouData = new um220;
6 | readKey *readKeyThread = new readKey;
7 |
8 | int main(int argc, char *argv[])
9 | {
10 | QApplication a(argc, argv);
11 | //设置字符编码为UTF-8,解决特殊符号乱码的问题
12 | QTextCodec *codec = QTextCodec::codecForName("UTF-8");
13 | QTextCodec::setCodecForTr(codec);
14 | QTextCodec::setCodecForLocale(codec);
15 | QTextCodec::setCodecForCStrings(codec);
16 | //主框架
17 | QSplitter *splitterMain =new QSplitter(Qt::Horizontal,0);
18 | splitterMain->setOpaqueResize(true);
19 | //添加左侧列表
20 | QListWidget *list =new QListWidget(splitterMain);
21 | list->insertItem(0,QObject::tr("Nav Data Display"));
22 | list->insertItem(1,QObject::tr("Plotter Display"));
23 | list->insertItem(2,QObject::tr("Highway Display"));
24 | list->insertItem(3,QObject::tr("Steering Display"));
25 | Content *content =new Content(splitterMain);
26 | //页面切换功能
27 | readKeyThread->start();
28 | QObject::connect(readKeyThread,SIGNAL(disSwitch(int)),
29 | content->stack, SLOT(setCurrentIndex(int)));
30 | content->stack->setCurrentIndex(3);//0~3:NPHS
31 | list->hide();//隐藏左侧列表
32 |
33 | beidouData->um220init();//北斗模块初始化
34 | //从资源文件中载入style sheet
35 | QFile file(":/style.qss");
36 | file.open(QFile::ReadOnly);
37 | QString styleSheet = QLatin1String(file.readAll());
38 | qApp->setStyleSheet(styleSheet);
39 | //展示窗口
40 | splitterMain->showFullScreen();
41 | return a.exec();
42 | }
43 |
--------------------------------------------------------------------------------
/navdata.cpp:
--------------------------------------------------------------------------------
1 | #include "navdata.h"
2 | #include "um220.h"
3 | //test
4 | extern class um220 *beidouData;
5 |
6 | NavData::NavData(QWidget *parent) :
7 | QWidget(parent)
8 | {
9 | QCursor cursor ;
10 | cursor = QCursor(Qt::BlankCursor);
11 | setCursor(cursor);
12 |
13 | QObject::connect(beidouData,SIGNAL(dataUpdate()),this,SLOT(showTime()));
14 | //线程触发界面的刷新
15 | // QDateTime timeTemp = QDateTime::currentDateTime();
16 | // QString timeStr = timeTemp.toString("yyyy-MM-dd hh:mm:ss");
17 | //通过系统时钟获取当前时间
18 | QFont font;
19 | font.setPointSize(35);
20 |
21 | timeLabel =new QLabel();
22 |
23 | QFont timeFont;
24 | timeFont.setPointSize(35);
25 | timeLabel->setLineWidth(3);
26 | timeLabel->setMidLineWidth(3);
27 | timeLabel->setFont(timeFont);
28 |
29 | coordinateLabel =new QLabel;
30 | coordinateLabel->setFont(font);
31 | coordinateLabel->setText("GPS unconnected!");
32 | SPDLabel =new QLabel;
33 | SPDLabel->setFont(font);
34 | CSELabel =new QLabel;
35 | CSELabel->setFont(font);
36 |
37 | QGridLayout *mainLayout = new QGridLayout(this);//主布局为网格
38 | mainLayout->setMargin(5);
39 | mainLayout->setSpacing(5);
40 | mainLayout->addWidget(timeLabel,0,0,1,2);
41 | mainLayout->addWidget(coordinateLabel,1,0,1,2);
42 | mainLayout->addWidget(SPDLabel,2,0);
43 | mainLayout->addWidget(CSELabel,2,1);
44 | mainLayout->setRowStretch(0,1);//各行高度比1:4:2
45 | mainLayout->setRowStretch(1,4);
46 | mainLayout->setRowStretch(2,2);
47 |
48 | }
49 |
50 | void NavData::showTime()
51 | {
52 | timeLabel->setText(beidouData->time);
53 |
54 | CSEString = "CSE:";
55 | CSEString.append(beidouData->cog);
56 | CSEString.append("°");
57 | CSELabel->setText(CSEString);
58 |
59 | SPDString = "SPD:";
60 | SPDString.append(beidouData->spd);
61 | SPDString.append("knot");
62 | SPDLabel->setText(SPDString);
63 |
64 | coordinateString = "Longitude:";
65 | coordinateString.append(beidouData->Lon);
66 | if(beidouData->E.toInt())//东南西北判别
67 | coordinateString.append(QString("E\nLatitude:"));
68 | else
69 | coordinateString.append(QString("W\nLatitude:"));
70 | coordinateString.append(beidouData->Lat);
71 | if(beidouData->N.toInt())
72 | coordinateString.append(QString("N"));
73 | else
74 | coordinateString.append(QString("S"));
75 | coordinateLabel->setText(coordinateString);
76 | }
77 |
--------------------------------------------------------------------------------
/navdata.h:
--------------------------------------------------------------------------------
1 | #ifndef _NAVDATA_H_
2 | #define _NAVDATA_H_
3 |
4 | #include "stable.h"
5 |
6 |
7 | class NavData : public QWidget
8 | {
9 | Q_OBJECT
10 | public:
11 | NavData(QWidget *parent=0);
12 | // class um220 beidouData;
13 | private:
14 | QLabel *timeLabel;
15 | QLabel *coordinateLabel;
16 | QLabel *SPDLabel;
17 | QLabel *CSELabel;
18 | QTimer *timer;
19 | QString coordinateString;
20 | QString SPDString;
21 | QString CSEString;
22 | // um220 *beidouData;
23 | private slots:
24 | void showTime();
25 | };
26 | #endif
27 |
--------------------------------------------------------------------------------
/plotter.cpp:
--------------------------------------------------------------------------------
1 | #include "plotter.h"
2 | #include "um220.h"
3 | #include "key.h"
4 | #define BEISHU 0.1//一像素代表多少海里
5 | extern class um220 *beidouData;
6 | QLinkedList pointList;
7 | extern readKey *readKeyThread;
8 |
9 | /*****************
10 | *
11 | * 页面布局和文字刷新
12 | * 以及画布scene初始化
13 | *
14 | *****************/
15 | Plotter::Plotter(QWidget *parent) :
16 | QWidget(parent)
17 | {
18 |
19 | QObject::connect(beidouData,SIGNAL(dataUpdate()),this,SLOT(showTime()));
20 |
21 | plView =new PlView;
22 | QObject::connect(readKeyThread,SIGNAL(dirKey(int)),
23 | plView, SLOT(dirGet(int)));//切换界面
24 |
25 | scene = new QGraphicsScene;
26 | scene->setSceneRect(0, 0, plView->viewWidth, plView->viewHeight);
27 |
28 | plView->setScene(scene);
29 | plView->setRenderHint(QPainter::Antialiasing);//抗锯齿
30 | plView->centerOn(QPoint(0,0));
31 | plView->setAlignment(Qt::AlignLeft | Qt::AlignTop);
32 | //默认视野在中间,强制调至左上角,否则无法实现鼠标全局坐标和view相对坐标的对应
33 | plView->setBackgroundBrush(QImage(":/sea.jpg"));
34 | plView->setCacheMode(QGraphicsView::CacheBackground);
35 | //窗口静态布局初始化
36 | {
37 | QFont font;
38 | // font.setPointSize(45);
39 | font.setPointSize(35);
40 |
41 | settingLabel =new QLabel(tr("MOD\n3D"));
42 | settingLabel->setFont(font);
43 |
44 | CSELabel =new QLabel(tr("CSE"));
45 | CSELabel->setFont(font);
46 | SPDLabel =new QLabel(tr("SPD"));
47 | SPDLabel->setFont(font);
48 | coordinateLabel =new QLabel(tr("LON\t\t\t\t\t\tLAT"));
49 | coordinateLabel->setFont(font);
50 | mainLayout = new QGridLayout(this);
51 | mainLayout->addWidget(settingLabel,0,0);
52 | mainLayout->addWidget(CSELabel,1,0);
53 | mainLayout->addWidget(SPDLabel,2,0);
54 | mainLayout->addWidget(plView,0,1,3,1);
55 | mainLayout->addWidget(coordinateLabel,3,0,1,2);
56 | mainLayout->setRowStretch(0,2);
57 | mainLayout->setRowStretch(1,2);
58 | mainLayout->setRowStretch(2,2);
59 | mainLayout->setRowStretch(3,1);
60 | mainLayout->setColumnStretch(0,1);
61 | mainLayout->setColumnStretch(1,5);
62 | }
63 |
64 | //创建一个直径8像素的圆形item代表当前位置
65 | QGraphicsItem *zero = new QGraphicsEllipseItem(
66 | QRectF(plView->viewWidth/2.0,plView->viewHeight/2.0,8,8));
67 | plView->cursor.setPos(plView->viewWidth/2+10*3+plView->viewWidth/5+1,plView->viewHeight/2+10*2+4);
68 | scene->addItem(zero);
69 |
70 | }
71 |
72 | void Plotter::showTime()
73 | {
74 | //文字刷新
75 | CSEString = "CSE:";
76 | CSEString.append(beidouData->cog);
77 | CSEString.append("°");
78 | CSELabel->setText(CSEString);
79 |
80 | SPDString = "SPD:";
81 | SPDString.append(beidouData->spd);
82 | SPDString.append("knot");
83 | SPDLabel->setText(SPDString);
84 |
85 |
86 |
87 | QPointF nowCoor =plView->coorCalc(cursor().pos(),plView->viewWidth,plView->viewHeight);
88 |
89 | coordinatextring = "Longitude:";
90 | coordinatextring.append(QString::number(nowCoor.x()));
91 | if(beidouData->E.toInt())//东南西北后缀判别
92 | coordinatextring.append(QString("E\t\t\t\tlongitude:"));
93 | else
94 | coordinatextring.append(QString("W\t\t\t\tLatitude:"));
95 | coordinatextring.append(QString::number(nowCoor.y()));
96 | if(beidouData->N.toInt())
97 | coordinatextring.append(QString("N"));
98 | else
99 | coordinatextring.append(QString("S"));
100 | coordinateLabel->setText(coordinatextring);
101 | }
102 |
103 | /*****************
104 | * coorCalc
105 | * 输入:光标位置的||全局坐标||
106 | * 输出:经纬度
107 | *
108 | *****************/
109 | QPointF PlView::coorCalc(QPointF nowPos,int viewWidth,int viewHeight)
110 | {
111 | QPoint temp= mapFromGlobal(nowPos.toPoint());
112 | return QPointF(beidouData->Lon.toInt()+(temp.x()-viewWidth/2.0)*BEISHU,
113 | beidouData->Lat.toInt()+(temp.y()-viewHeight/2.0)*BEISHU
114 | );
115 | }
116 |
117 |
118 | /*****************
119 | *
120 | * 自定义item,代表途径点
121 | * 的小叉
122 | *
123 | *****************/
124 | /*
125 | XItem::XItem()
126 | {
127 | setFlag(QGraphicsItem::ItemIsFocusable);
128 | setFlag(QGraphicsItem::ItemIsMovable);
129 | setAcceptHoverEvents(true);
130 | }
131 |
132 | QRectF XItem::boundingRect() const
133 | {
134 | qreal adjust = 0;
135 | return QRectF(-10 - adjust, -10 - adjust,
136 | 20 + adjust, 20 + adjust);
137 | }
138 |
139 | void XItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
140 | {
141 | painter->setBrush(Qt::black);
142 | painter->drawLine(-10,-10,10,10);
143 | painter->drawLine(-10,10,10,-10);
144 |
145 | }
146 | */
147 |
148 |
149 | /*****************
150 | *
151 | * View:整体嵌入布局
152 | * 并负责管理光标操作
153 | *
154 | *****************/
155 | PlView::PlView(QWidget *parent) :
156 | QGraphicsView(parent)
157 | {
158 | QCursor cursor ;
159 | cursor = QCursor(Qt::CrossCursor);
160 | setCursor(cursor);
161 | viewWidth=(QApplication::desktop()->width()-5*10)*5/6.0;
162 | viewHeight=(QApplication::desktop()->height()-7*10)*6/7.0;
163 |
164 | // cursor.setPos(QPoint(500,400));
165 | }
166 |
167 | /*****************
168 | *
169 | * key.c中接收自定义按键数据,
170 | * 发送keyEvent,在本函数中处理
171 | * 不用自定义事件是为了便于调试
172 | * 和增强可移植性
173 | *
174 | *****************/
175 |
176 | void PlView::keyPressEvent(QKeyEvent *event)
177 | {
178 | switch (event->key())
179 | {
180 |
181 | case Qt::Key_Equal ://缩放视野,坐标体系不变
182 | scale(1.2, 1.2);//按键不够用,考虑用激活右键惨淡实现
183 | break;
184 | case Qt::Key_Minus :
185 | scale(1 / 1.2, 1 / 1.2);
186 | break;
187 |
188 | case Qt::Key_Up ://上下左右移动光标
189 | if(cursor.pos().y()> PlView::pos().y() )//防止光标越界
190 | cursor.setPos((QPoint(cursor.pos().x(),cursor.pos().y()-8)));
191 | break;
192 | case Qt::Key_Down :
193 | if(cursor.pos().y() < (PlView::pos().y() + PlView::height()) )
194 | cursor.setPos((QPoint(cursor.pos().x(),cursor.pos().y()+8)));
195 | break;
196 | case Qt::Key_Left :
197 | if(cursor.pos().x() > PlView::pos().x() )
198 | {
199 | cursor.setPos((QPoint(cursor.pos().x()-8,cursor.pos().y())));
200 | }
201 | break;
202 | case Qt::Key_Right :
203 | if(cursor.pos().x() < (PlView::pos().x()+ PlView::width()))
204 | {
205 | cursor.setPos((QPoint(cursor.pos().x()+8,cursor.pos().y())));
206 | }
207 | break;
208 |
209 |
210 | case Qt::Key_Space : //管理途径点,以16x16的正方形和数字表示
211 | {
212 | QGraphicsItem *pItemAt = scene()->itemAt(QPoint(//若当前光标处有item,则删除
213 | mapFromGlobal(QCursor::pos()).x()-8,
214 | mapFromGlobal(QCursor::pos()).y()-8));
215 | static int i=1;
216 |
217 | if(pItemAt== 0) //添加
218 | {
219 | QGraphicsRectItem *rect = new QGraphicsRectItem (mapFromGlobal(QCursor::pos()).x()-8,
220 | mapFromGlobal(QCursor::pos()).y()-8,
221 | 16,16);
222 | QGraphicsSimpleTextItem *text = new QGraphicsSimpleTextItem(QString::number(i++));
223 | text->setPos(QPoint(mapFromGlobal(QCursor::pos()).x()-8,
224 | mapFromGlobal(QCursor::pos()).y()-12));
225 |
226 | scene()->addItem(rect);
227 | scene()->addItem(text);
228 | itemList.append(text);//存储item的指针,便于控制图形显示
229 | pointList.append(text->pos());//存储目标点的屏幕坐标
230 |
231 | // QLinkedList::iterator iter;
232 | // for(iter=itemList.begin();iter!= itemList.end();iter++)
233 | // qDebug()<<(*iter)->pos().x();
234 |
235 | }
236 |
237 | // XItem *item = new XItem;
238 | // item->setPos(mapFromGlobal(QCursor::pos()).x()-10,
239 | // mapFromGlobal(QCursor::pos()).y()-10);
240 | // scene()->addItem(item);
241 | // 自定义item不能被itemAt识别?无法正常删除
242 |
243 | else
244 | {
245 | //删除,鼠标itemAt-》获取指针-》通过指针控制图形-》修改itemList
246 | // ↓-》获取坐标-》修改pointList
247 | scene()->removeItem(pItemAt);//两次删除,分别删除数字和方框
248 | scene()->removeItem(scene()->itemAt(QPoint(mapFromGlobal(QCursor::pos()).x()-8,
249 | mapFromGlobal(QCursor::pos()).y()-8)));
250 | QLinkedList::iterator it
251 | =qFind(itemList.begin(),itemList.end(),pItemAt);
252 | if(it!=itemList.end())
253 | it = itemList.erase(it);
254 | else itemList.removeLast();//在链表中删除选中点,此时it指向被删除点的下一个点
255 | i--;
256 | while (it != itemList.end())
257 | {
258 | //此点及以后的点标号减一
259 | (*it)->setText(QString::number(
260 | (*it)->text().toInt()-1));
261 | it++;
262 | }
263 | }
264 | pointList.clear();//pointList与itemList同步
265 | QLinkedList::iterator it1;
266 | QLinkedList::iterator it2;
267 | for(it1=itemList.begin(),it2=pointList.begin(); it1!=itemList.end(); it1++,it2++)
268 | {
269 | (*it2) = coorCalc(mapToGlobal((*it1)->pos().toPoint()),viewWidth,viewHeight);
270 | // qDebug()<<(*it2).x();
271 | }
272 |
273 | }
274 | break;
275 |
276 | }
277 |
278 | }
279 |
280 | void PlView::dirGet(int i)
281 | {
282 | switch(i)
283 | {
284 | case 1://上
285 | {
286 | if(cursor.pos().y()> PlView::pos().y() )//防止光标越界
287 | cursor.setPos((QPoint(cursor.pos().x(),cursor.pos().y()-8)));
288 | }
289 | break;
290 |
291 | case 2://下
292 | {
293 | if(cursor.pos().y() < (PlView::pos().y() + PlView::height()) )
294 | cursor.setPos((QPoint(cursor.pos().x(),cursor.pos().y()+8)));
295 | }
296 | break;
297 |
298 | case 3://左
299 | {
300 | if(cursor.pos().x() > PlView::pos().x() )
301 | {
302 | cursor.setPos((QPoint(cursor.pos().x()-8,cursor.pos().y())));
303 | }
304 | }
305 | break;
306 |
307 | case 4://右
308 | {
309 | if(cursor.pos().x() < (PlView::pos().x()+ PlView::width()))
310 | {
311 | cursor.setPos((QPoint(cursor.pos().x()+8,cursor.pos().y())));
312 | }
313 | }
314 | break;
315 |
316 | case 5://点管理
317 | {
318 | QGraphicsItem *pItemAt = scene()->itemAt(QPoint(//若当前光标处有item,则删除
319 | mapFromGlobal(QCursor::pos()).x()-8,
320 | mapFromGlobal(QCursor::pos()).y()-8));
321 | static int i=1;
322 |
323 | if(pItemAt== 0) //添加
324 | {
325 | QGraphicsRectItem *rect = new QGraphicsRectItem (mapFromGlobal(QCursor::pos()).x()-8,
326 | mapFromGlobal(QCursor::pos()).y()-8,
327 | 16,16);
328 | QGraphicsSimpleTextItem *text = new QGraphicsSimpleTextItem(QString::number(i++));
329 | QFont font;
330 | font.setPointSize(50);
331 | text->setFont(font);
332 | text->setPos(QPoint(mapFromGlobal(QCursor::pos()).x()-8,
333 | mapFromGlobal(QCursor::pos()).y()-12));
334 |
335 | scene()->addItem(rect);
336 | scene()->addItem(text);
337 | itemList.append(text);//存储item的指针,便于控制图形显示
338 | pointList.append(text->pos());//存储目标点的屏幕坐标
339 |
340 | // QLinkedList::iterator iter;
341 | // for(iter=itemList.begin();iter!= itemList.end();iter++)
342 | // qDebug()<<(*iter)->pos().x();
343 |
344 | }
345 | /*
346 | XItem *item = new XItem;
347 | item->setPos(mapFromGlobal(QCursor::pos()).x()-10,
348 | mapFromGlobal(QCursor::pos()).y()-10);
349 | scene()->addItem(item);
350 | 自定义item不能被itemAt识别?无法正常删除
351 | */
352 | else
353 | {
354 | //删除,鼠标itemAt-》获取指针-》通过指针控制图形-》修改itemList
355 | // ↓-》获取坐标-》修改pointList
356 | scene()->removeItem(pItemAt);//两次删除,分别删除数字和方框
357 | scene()->removeItem(scene()->itemAt(QPoint(mapFromGlobal(QCursor::pos()).x()-8,
358 | mapFromGlobal(QCursor::pos()).y()-8)));
359 | QLinkedList::iterator it
360 | =qFind(itemList.begin(),itemList.end(),pItemAt);
361 | if(it!=itemList.end())
362 | it = itemList.erase(it);
363 | else itemList.removeLast();//在链表中删除选中点,此时it指向被删除点的下一个点
364 | i--;
365 | while (it != itemList.end())
366 | {
367 | //此点及以后的点标号减一
368 | (*it)->setText(QString::number(
369 | (*it)->text().toInt()-1));
370 | it++;
371 | }
372 | }
373 | pointList.clear();//pointList与itemList同步
374 | QLinkedList::iterator it1;
375 | QLinkedList::iterator it2;
376 | for(it1=itemList.begin(),it2=pointList.begin(); it1!=itemList.end(); it1++,it2++)
377 | {
378 | (*it2) = coorCalc(mapToGlobal((*it1)->pos().toPoint()),viewWidth,viewHeight);
379 | // qDebug()<<(*it2).x();
380 | }
381 | }
382 | // break;
383 | }
384 | }
385 |
386 |
387 |
--------------------------------------------------------------------------------
/plotter.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _PLOTTER_H_
3 | #define _PLOTTER_H_
4 | #include "stable.h"
5 |
6 |
7 |
8 | class PlView : public QGraphicsView
9 | {
10 | Q_OBJECT
11 | public:
12 | explicit PlView(QWidget *parent = 0);
13 | QPointF coorCalc(QPointF nowPos, int viewWidth, int viewHeight);
14 | QCursor cursor;
15 | QGraphicsItem *zero;
16 | QLinkedList itemList;
17 | int viewWidth,viewHeight;
18 | protected:
19 | void keyPressEvent(QKeyEvent *event);
20 | double cseCalc(QPoint nowPos, int viewWidth, int viewHeight);
21 | signals:
22 |
23 | public slots:
24 | void dirGet(int i);
25 | };
26 |
27 | class XItem : public QGraphicsItem
28 | {
29 | public:
30 | XItem();
31 | QRectF boundingRect() const;
32 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
33 | QWidget *widget);
34 | // void setColor(const QColor &color) { brushColor = color; }
35 | protected:
36 | private:
37 | public slots:
38 | signals:
39 |
40 | };
41 |
42 |
43 | class Plotter : public QWidget
44 | {
45 | Q_OBJECT
46 | public:
47 | Plotter(QWidget *parent=0);
48 |
49 | private:
50 | QLabel *settingLabel;
51 | QLabel *coordinateLabel;
52 | QLabel *SPDLabel;
53 | QLabel *CSELabel;
54 | PlView *plView;
55 | QGraphicsScene *scene;
56 | QString coordinatextring;
57 | QString SPDString;
58 | QString CSEString;
59 | QString settingString;
60 | QGridLayout *mainLayout;
61 |
62 | protected:
63 | // void mousePressEvent(QMouseEvent *event);
64 |
65 | public slots:
66 | void showTime();
67 |
68 | };
69 |
70 |
71 |
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/posix_qextserialport.cpp:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | \class Posix_QextSerialPort
4 | \version 1.0.0
5 | \author Stefan Sander
6 | \author Michal Policht
7 |
8 | A cross-platform serial port class.
9 | This class encapsulates the POSIX portion of QextSerialPort. The user will be notified of errors
10 | and possible portability conflicts at run-time by default - this behavior can be turned off by
11 | defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off portability
12 | warnings) in the project. Note that _TTY_NOWARN_ will also turn off portability warnings.
13 | */
14 |
15 | #include
16 | #include "posix_qextserialport.h"
17 |
18 | /*!
19 | \fn Posix_QextSerialPort::Posix_QextSerialPort()
20 | Default constructor. Note that the name of the device used by a QextSerialPort constructed with
21 | this constructor will be determined by #defined constants, or lack thereof - the default behavior
22 | is the same as _TTY_LINUX_. Possible naming conventions and their associated constants are:
23 |
24 | \verbatim
25 |
26 | Constant Used By Naming Convention
27 | ---------- ------------- ------------------------
28 | _TTY_WIN_ Windows COM1, COM2
29 | _TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2
30 | _TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0
31 | _TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb
32 | _TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02
33 | _TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1
34 | _TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1
35 | Linux /dev/ttyS0, /dev/ttyS1
36 | \endverbatim
37 |
38 | This constructor assigns the device name to the name of the first port on the specified system.
39 | See the other constructors if you need to open a different port.
40 | */
41 | Posix_QextSerialPort::Posix_QextSerialPort()
42 | : QextSerialBase()
43 | {
44 | Posix_File=new QFile();
45 | }
46 |
47 | /*!
48 | \fn Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort&)
49 | Copy constructor.
50 | */
51 | Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort& s)
52 | : QextSerialBase(s.port)
53 | {
54 | setOpenMode(s.openMode());
55 | port = s.port;
56 | Settings.BaudRate=s.Settings.BaudRate;
57 | Settings.DataBits=s.Settings.DataBits;
58 | Settings.Parity=s.Settings.Parity;
59 | Settings.StopBits=s.Settings.StopBits;
60 | Settings.FlowControl=s.Settings.FlowControl;
61 | lastErr=s.lastErr;
62 |
63 | Posix_File=new QFile();
64 | Posix_File=s.Posix_File;
65 | memcpy(&Posix_Timeout, &s.Posix_Timeout, sizeof(struct timeval));
66 | memcpy(&Posix_Copy_Timeout, &s.Posix_Copy_Timeout, sizeof(struct timeval));
67 | memcpy(&Posix_CommConfig, &s.Posix_CommConfig, sizeof(struct termios));
68 | }
69 |
70 | /*!
71 | \fn Posix_QextSerialPort::Posix_QextSerialPort(const QString & name)
72 | Constructs a serial port attached to the port specified by name.
73 | name is the name of the device, which is windowsystem-specific,
74 | e.g."COM1" or "/dev/ttyS0".
75 | */
76 | Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, QextSerialBase::QueryMode mode)
77 | : QextSerialBase(name)
78 | {
79 | Posix_File=new QFile();
80 | setQueryMode(mode);
81 | init();
82 | }
83 |
84 | /*!
85 | \fn Posix_QextSerialPort::Posix_QextSerialPort(const PortSettings& settings)
86 | Constructs a port with default name and specified settings.
87 | */
88 | Posix_QextSerialPort::Posix_QextSerialPort(const PortSettings& settings, QextSerialBase::QueryMode mode)
89 | : QextSerialBase()
90 | {
91 | setBaudRate(settings.BaudRate);
92 | setDataBits(settings.DataBits);
93 | setParity(settings.Parity);
94 | setStopBits(settings.StopBits);
95 | setFlowControl(settings.FlowControl);
96 |
97 | Posix_File=new QFile();
98 | setTimeout(settings.Timeout_Millisec);
99 | setQueryMode(mode);
100 | init();
101 | }
102 |
103 | /*!
104 | \fn Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, const PortSettings& settings)
105 | Constructs a port with specified name and settings.
106 | */
107 | Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, const PortSettings& settings, QextSerialBase::QueryMode mode)
108 | : QextSerialBase(name)
109 | {
110 | setBaudRate(settings.BaudRate);
111 | setDataBits(settings.DataBits);
112 | setParity(settings.Parity);
113 | setStopBits(settings.StopBits);
114 | setFlowControl(settings.FlowControl);
115 |
116 | Posix_File=new QFile();
117 | setTimeout(settings.Timeout_Millisec);
118 | setQueryMode(mode);
119 | init();
120 | }
121 |
122 | /*!
123 | \fn Posix_QextSerialPort& Posix_QextSerialPort::operator=(const Posix_QextSerialPort& s)
124 | Override the = operator.
125 | */
126 | Posix_QextSerialPort& Posix_QextSerialPort::operator=(const Posix_QextSerialPort& s)
127 | {
128 | setOpenMode(s.openMode());
129 | port = s.port;
130 | Settings.BaudRate=s.Settings.BaudRate;
131 | Settings.DataBits=s.Settings.DataBits;
132 | Settings.Parity=s.Settings.Parity;
133 | Settings.StopBits=s.Settings.StopBits;
134 | Settings.FlowControl=s.Settings.FlowControl;
135 | lastErr=s.lastErr;
136 |
137 | Posix_File=s.Posix_File;
138 | memcpy(&Posix_Timeout, &(s.Posix_Timeout), sizeof(struct timeval));
139 | memcpy(&Posix_Copy_Timeout, &(s.Posix_Copy_Timeout), sizeof(struct timeval));
140 | memcpy(&Posix_CommConfig, &(s.Posix_CommConfig), sizeof(struct termios));
141 | return *this;
142 | }
143 |
144 | void Posix_QextSerialPort::init()
145 | {
146 | if (queryMode() == QextSerialBase::EventDriven)
147 | qWarning("POSIX doesn't have event driven mechanism implemented yet");
148 | }
149 |
150 | /*!
151 | \fn Posix_QextSerialPort::~Posix_QextSerialPort()
152 | Standard destructor.
153 | */
154 | Posix_QextSerialPort::~Posix_QextSerialPort()
155 | {
156 | if (isOpen()) {
157 | close();
158 | }
159 | Posix_File->close();
160 | delete Posix_File;
161 | }
162 |
163 | /*!
164 | \fn void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate)
165 | Sets the baud rate of the serial port. Note that not all rates are applicable on
166 | all platforms. The following table shows translations of the various baud rate
167 | constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an *
168 | are speeds that are usable on both Windows and POSIX.
169 |
170 | \note
171 | BAUD76800 may not be supported on all POSIX systems. SGI/IRIX systems do not support
172 | BAUD1800.
173 |
174 | \verbatim
175 |
176 | RATE Windows Speed POSIX Speed
177 | ----------- ------------- -----------
178 | BAUD50 110 50
179 | BAUD75 110 75
180 | *BAUD110 110 110
181 | BAUD134 110 134.5
182 | BAUD150 110 150
183 | BAUD200 110 200
184 | *BAUD300 300 300
185 | *BAUD600 600 600
186 | *BAUD1200 1200 1200
187 | BAUD1800 1200 1800
188 | *BAUD2400 2400 2400
189 | *BAUD4800 4800 4800
190 | *BAUD9600 9600 9600
191 | BAUD14400 14400 9600
192 | *BAUD19200 19200 19200
193 | *BAUD38400 38400 38400
194 | BAUD56000 56000 38400
195 | *BAUD57600 57600 57600
196 | BAUD76800 57600 76800
197 | *BAUD115200 115200 115200
198 | BAUD128000 128000 115200
199 | BAUD256000 256000 115200
200 | \endverbatim
201 | */
202 | void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate)
203 | {
204 | LOCK_MUTEX();
205 | if (Settings.BaudRate!=baudRate) {
206 | switch (baudRate) {
207 | case BAUD14400:
208 | Settings.BaudRate=BAUD9600;
209 | break;
210 |
211 | case BAUD56000:
212 | Settings.BaudRate=BAUD38400;
213 | break;
214 |
215 | case BAUD76800:
216 |
217 | #ifndef B76800
218 | Settings.BaudRate=BAUD57600;
219 | #else
220 | Settings.BaudRate=baudRate;
221 | #endif
222 | break;
223 |
224 | case BAUD128000:
225 | case BAUD256000:
226 | Settings.BaudRate=BAUD115200;
227 | break;
228 |
229 | default:
230 | Settings.BaudRate=baudRate;
231 | break;
232 | }
233 | }
234 | if (isOpen()) {
235 | switch (baudRate) {
236 |
237 | /*50 baud*/
238 | case BAUD50:
239 | TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 50 baud operation.");
240 | #ifdef CBAUD
241 | Posix_CommConfig.c_cflag&=(~CBAUD);
242 | Posix_CommConfig.c_cflag|=B50;
243 | #else
244 | cfsetispeed(&Posix_CommConfig, B50);
245 | cfsetospeed(&Posix_CommConfig, B50);
246 | #endif
247 | break;
248 |
249 | /*75 baud*/
250 | case BAUD75:
251 | TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 75 baud operation.");
252 | #ifdef CBAUD
253 | Posix_CommConfig.c_cflag&=(~CBAUD);
254 | Posix_CommConfig.c_cflag|=B75;
255 | #else
256 | cfsetispeed(&Posix_CommConfig, B75);
257 | cfsetospeed(&Posix_CommConfig, B75);
258 | #endif
259 | break;
260 |
261 | /*110 baud*/
262 | case BAUD110:
263 | #ifdef CBAUD
264 | Posix_CommConfig.c_cflag&=(~CBAUD);
265 | Posix_CommConfig.c_cflag|=B110;
266 | #else
267 | cfsetispeed(&Posix_CommConfig, B110);
268 | cfsetospeed(&Posix_CommConfig, B110);
269 | #endif
270 | break;
271 |
272 | /*134.5 baud*/
273 | case BAUD134:
274 | TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 134.5 baud operation.");
275 | #ifdef CBAUD
276 | Posix_CommConfig.c_cflag&=(~CBAUD);
277 | Posix_CommConfig.c_cflag|=B134;
278 | #else
279 | cfsetispeed(&Posix_CommConfig, B134);
280 | cfsetospeed(&Posix_CommConfig, B134);
281 | #endif
282 | break;
283 |
284 | /*150 baud*/
285 | case BAUD150:
286 | TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 150 baud operation.");
287 | #ifdef CBAUD
288 | Posix_CommConfig.c_cflag&=(~CBAUD);
289 | Posix_CommConfig.c_cflag|=B150;
290 | #else
291 | cfsetispeed(&Posix_CommConfig, B150);
292 | cfsetospeed(&Posix_CommConfig, B150);
293 | #endif
294 | break;
295 |
296 | /*200 baud*/
297 | case BAUD200:
298 | TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 200 baud operation.");
299 | #ifdef CBAUD
300 | Posix_CommConfig.c_cflag&=(~CBAUD);
301 | Posix_CommConfig.c_cflag|=B200;
302 | #else
303 | cfsetispeed(&Posix_CommConfig, B200);
304 | cfsetospeed(&Posix_CommConfig, B200);
305 | #endif
306 | break;
307 |
308 | /*300 baud*/
309 | case BAUD300:
310 | #ifdef CBAUD
311 | Posix_CommConfig.c_cflag&=(~CBAUD);
312 | Posix_CommConfig.c_cflag|=B300;
313 | #else
314 | cfsetispeed(&Posix_CommConfig, B300);
315 | cfsetospeed(&Posix_CommConfig, B300);
316 | #endif
317 | break;
318 |
319 | /*600 baud*/
320 | case BAUD600:
321 | #ifdef CBAUD
322 | Posix_CommConfig.c_cflag&=(~CBAUD);
323 | Posix_CommConfig.c_cflag|=B600;
324 | #else
325 | cfsetispeed(&Posix_CommConfig, B600);
326 | cfsetospeed(&Posix_CommConfig, B600);
327 | #endif
328 | break;
329 |
330 | /*1200 baud*/
331 | case BAUD1200:
332 | #ifdef CBAUD
333 | Posix_CommConfig.c_cflag&=(~CBAUD);
334 | Posix_CommConfig.c_cflag|=B1200;
335 | #else
336 | cfsetispeed(&Posix_CommConfig, B1200);
337 | cfsetospeed(&Posix_CommConfig, B1200);
338 | #endif
339 | break;
340 |
341 | /*1800 baud*/
342 | case BAUD1800:
343 | TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation.");
344 | #ifdef CBAUD
345 | Posix_CommConfig.c_cflag&=(~CBAUD);
346 | Posix_CommConfig.c_cflag|=B1800;
347 | #else
348 | cfsetispeed(&Posix_CommConfig, B1800);
349 | cfsetospeed(&Posix_CommConfig, B1800);
350 | #endif
351 | break;
352 |
353 | /*2400 baud*/
354 | case BAUD2400:
355 | #ifdef CBAUD
356 | Posix_CommConfig.c_cflag&=(~CBAUD);
357 | Posix_CommConfig.c_cflag|=B2400;
358 | #else
359 | cfsetispeed(&Posix_CommConfig, B2400);
360 | cfsetospeed(&Posix_CommConfig, B2400);
361 | #endif
362 | break;
363 |
364 | /*4800 baud*/
365 | case BAUD4800:
366 | #ifdef CBAUD
367 | Posix_CommConfig.c_cflag&=(~CBAUD);
368 | Posix_CommConfig.c_cflag|=B4800;
369 | #else
370 | cfsetispeed(&Posix_CommConfig, B4800);
371 | cfsetospeed(&Posix_CommConfig, B4800);
372 | #endif
373 | break;
374 |
375 | /*9600 baud*/
376 | case BAUD9600:
377 | #ifdef CBAUD
378 | Posix_CommConfig.c_cflag&=(~CBAUD);
379 | Posix_CommConfig.c_cflag|=B9600;
380 | #else
381 | cfsetispeed(&Posix_CommConfig, B9600);
382 | cfsetospeed(&Posix_CommConfig, B9600);
383 | #endif
384 | break;
385 |
386 | /*14400 baud*/
387 | case BAUD14400:
388 | TTY_WARNING("Posix_QextSerialPort: POSIX does not support 14400 baud operation. Switching to 9600 baud.");
389 | #ifdef CBAUD
390 | Posix_CommConfig.c_cflag&=(~CBAUD);
391 | Posix_CommConfig.c_cflag|=B9600;
392 | #else
393 | cfsetispeed(&Posix_CommConfig, B9600);
394 | cfsetospeed(&Posix_CommConfig, B9600);
395 | #endif
396 | break;
397 |
398 | /*19200 baud*/
399 | case BAUD19200:
400 | #ifdef CBAUD
401 | Posix_CommConfig.c_cflag&=(~CBAUD);
402 | Posix_CommConfig.c_cflag|=B19200;
403 | #else
404 | cfsetispeed(&Posix_CommConfig, B19200);
405 | cfsetospeed(&Posix_CommConfig, B19200);
406 | #endif
407 | break;
408 |
409 | /*38400 baud*/
410 | case BAUD38400:
411 | #ifdef CBAUD
412 | Posix_CommConfig.c_cflag&=(~CBAUD);
413 | Posix_CommConfig.c_cflag|=B38400;
414 | #else
415 | cfsetispeed(&Posix_CommConfig, B38400);
416 | cfsetospeed(&Posix_CommConfig, B38400);
417 | #endif
418 | break;
419 |
420 | /*56000 baud*/
421 | case BAUD56000:
422 | TTY_WARNING("Posix_QextSerialPort: POSIX does not support 56000 baud operation. Switching to 38400 baud.");
423 | #ifdef CBAUD
424 | Posix_CommConfig.c_cflag&=(~CBAUD);
425 | Posix_CommConfig.c_cflag|=B38400;
426 | #else
427 | cfsetispeed(&Posix_CommConfig, B38400);
428 | cfsetospeed(&Posix_CommConfig, B38400);
429 | #endif
430 | break;
431 |
432 | /*57600 baud*/
433 | case BAUD57600:
434 | #ifdef CBAUD
435 | Posix_CommConfig.c_cflag&=(~CBAUD);
436 | Posix_CommConfig.c_cflag|=B57600;
437 | #else
438 | cfsetispeed(&Posix_CommConfig, B57600);
439 | cfsetospeed(&Posix_CommConfig, B57600);
440 | #endif
441 | break;
442 |
443 | /*76800 baud*/
444 | case BAUD76800:
445 | TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation.");
446 | #ifdef CBAUD
447 | Posix_CommConfig.c_cflag&=(~CBAUD);
448 |
449 | #ifdef B76800
450 | Posix_CommConfig.c_cflag|=B76800;
451 | #else
452 | TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud.");
453 | Posix_CommConfig.c_cflag|=B57600;
454 | #endif //B76800
455 | #else //CBAUD
456 | #ifdef B76800
457 | cfsetispeed(&Posix_CommConfig, B76800);
458 | cfsetospeed(&Posix_CommConfig, B76800);
459 | #else
460 | TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud.");
461 | cfsetispeed(&Posix_CommConfig, B57600);
462 | cfsetospeed(&Posix_CommConfig, B57600);
463 | #endif //B76800
464 | #endif //CBAUD
465 | break;
466 |
467 | /*115200 baud*/
468 | case BAUD115200:
469 | #ifdef CBAUD
470 | Posix_CommConfig.c_cflag&=(~CBAUD);
471 | Posix_CommConfig.c_cflag|=B115200;
472 | #else
473 | cfsetispeed(&Posix_CommConfig, B115200);
474 | cfsetospeed(&Posix_CommConfig, B115200);
475 | #endif
476 | break;
477 |
478 | /*128000 baud*/
479 | case BAUD128000:
480 | TTY_WARNING("Posix_QextSerialPort: POSIX does not support 128000 baud operation. Switching to 115200 baud.");
481 | #ifdef CBAUD
482 | Posix_CommConfig.c_cflag&=(~CBAUD);
483 | Posix_CommConfig.c_cflag|=B115200;
484 | #else
485 | cfsetispeed(&Posix_CommConfig, B115200);
486 | cfsetospeed(&Posix_CommConfig, B115200);
487 | #endif
488 | break;
489 |
490 | /*256000 baud*/
491 | case BAUD256000:
492 | TTY_WARNING("Posix_QextSerialPort: POSIX does not support 256000 baud operation. Switching to 115200 baud.");
493 | #ifdef CBAUD
494 | Posix_CommConfig.c_cflag&=(~CBAUD);
495 | Posix_CommConfig.c_cflag|=B115200;
496 | #else
497 | cfsetispeed(&Posix_CommConfig, B115200);
498 | cfsetospeed(&Posix_CommConfig, B115200);
499 | #endif
500 | break;
501 | }
502 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
503 | }
504 | UNLOCK_MUTEX();
505 | }
506 |
507 | /*!
508 | \fn void Posix_QextSerialPort::setDataBits(DataBitsType dataBits)
509 | Sets the number of data bits used by the serial port. Possible values of dataBits are:
510 | \verbatim
511 | DATA_5 5 data bits
512 | DATA_6 6 data bits
513 | DATA_7 7 data bits
514 | DATA_8 8 data bits
515 | \endverbatim
516 |
517 | \note
518 | This function is subject to the following restrictions:
519 | \par
520 | 5 data bits cannot be used with 2 stop bits.
521 | \par
522 | 8 data bits cannot be used with space parity on POSIX systems.
523 |
524 | */
525 | void Posix_QextSerialPort::setDataBits(DataBitsType dataBits)
526 | {
527 | LOCK_MUTEX();
528 | if (Settings.DataBits!=dataBits) {
529 | if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||
530 | (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5) ||
531 | (Settings.Parity==PAR_SPACE && dataBits==DATA_8)) {
532 | }
533 | else {
534 | Settings.DataBits=dataBits;
535 | }
536 | }
537 | if (isOpen()) {
538 | switch(dataBits) {
539 |
540 | /*5 data bits*/
541 | case DATA_5:
542 | if (Settings.StopBits==STOP_2) {
543 | TTY_WARNING("Posix_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
544 | }
545 | else {
546 | Settings.DataBits=dataBits;
547 | Posix_CommConfig.c_cflag&=(~CSIZE);
548 | Posix_CommConfig.c_cflag|=CS5;
549 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
550 | }
551 | break;
552 |
553 | /*6 data bits*/
554 | case DATA_6:
555 | if (Settings.StopBits==STOP_1_5) {
556 | TTY_WARNING("Posix_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
557 | }
558 | else {
559 | Settings.DataBits=dataBits;
560 | Posix_CommConfig.c_cflag&=(~CSIZE);
561 | Posix_CommConfig.c_cflag|=CS6;
562 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
563 | }
564 | break;
565 |
566 | /*7 data bits*/
567 | case DATA_7:
568 | if (Settings.StopBits==STOP_1_5) {
569 | TTY_WARNING("Posix_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
570 | }
571 | else {
572 | Settings.DataBits=dataBits;
573 | Posix_CommConfig.c_cflag&=(~CSIZE);
574 | Posix_CommConfig.c_cflag|=CS7;
575 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
576 | }
577 | break;
578 |
579 | /*8 data bits*/
580 | case DATA_8:
581 | if (Settings.StopBits==STOP_1_5) {
582 | TTY_WARNING("Posix_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
583 | }
584 | else {
585 | Settings.DataBits=dataBits;
586 | Posix_CommConfig.c_cflag&=(~CSIZE);
587 | Posix_CommConfig.c_cflag|=CS8;
588 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
589 | }
590 | break;
591 | }
592 | }
593 | UNLOCK_MUTEX();
594 | }
595 |
596 | /*!
597 | \fn void Posix_QextSerialPort::setParity(ParityType parity)
598 | Sets the parity associated with the serial port. The possible values of parity are:
599 | \verbatim
600 | PAR_SPACE Space Parity
601 | PAR_MARK Mark Parity
602 | PAR_NONE No Parity
603 | PAR_EVEN Even Parity
604 | PAR_ODD Odd Parity
605 | \endverbatim
606 |
607 | \note
608 | This function is subject to the following limitations:
609 | \par
610 | POSIX systems do not support mark parity.
611 | \par
612 | POSIX systems support space parity only if tricked into doing so, and only with
613 | fewer than 8 data bits. Use space parity very carefully with POSIX systems.
614 |
615 | */
616 | void Posix_QextSerialPort::setParity(ParityType parity)
617 | {
618 | LOCK_MUTEX();
619 | if (Settings.Parity!=parity) {
620 | if (parity==PAR_MARK || (parity==PAR_SPACE && Settings.DataBits==DATA_8)) {
621 | }
622 | else {
623 | Settings.Parity=parity;
624 | }
625 | }
626 | if (isOpen()) {
627 | switch (parity) {
628 |
629 | /*space parity*/
630 | case PAR_SPACE:
631 | if (Settings.DataBits==DATA_8) {
632 | TTY_PORTABILITY_WARNING("Posix_QextSerialPort: Space parity is only supported in POSIX with 7 or fewer data bits");
633 | }
634 | else {
635 |
636 | /*space parity not directly supported - add an extra data bit to simulate it*/
637 | Posix_CommConfig.c_cflag&=~(PARENB|CSIZE);
638 | switch(Settings.DataBits) {
639 | case DATA_5:
640 | Settings.DataBits=DATA_6;
641 | Posix_CommConfig.c_cflag|=CS6;
642 | break;
643 |
644 | case DATA_6:
645 | Settings.DataBits=DATA_7;
646 | Posix_CommConfig.c_cflag|=CS7;
647 | break;
648 |
649 | case DATA_7:
650 | Settings.DataBits=DATA_8;
651 | Posix_CommConfig.c_cflag|=CS8;
652 | break;
653 |
654 | case DATA_8:
655 | break;
656 | }
657 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
658 | }
659 | break;
660 |
661 | /*mark parity - WINDOWS ONLY*/
662 | case PAR_MARK:
663 | TTY_WARNING("Posix_QextSerialPort: Mark parity is not supported by POSIX.");
664 | break;
665 |
666 | /*no parity*/
667 | case PAR_NONE:
668 | Posix_CommConfig.c_cflag&=(~PARENB);
669 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
670 | break;
671 |
672 | /*even parity*/
673 | case PAR_EVEN:
674 | Posix_CommConfig.c_cflag&=(~PARODD);
675 | Posix_CommConfig.c_cflag|=PARENB;
676 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
677 | break;
678 |
679 | /*odd parity*/
680 | case PAR_ODD:
681 | Posix_CommConfig.c_cflag|=(PARENB|PARODD);
682 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
683 | break;
684 | }
685 | }
686 | UNLOCK_MUTEX();
687 | }
688 |
689 | /*!
690 | \fn void Posix_QextSerialPort::setStopBits(StopBitsType stopBits)
691 | Sets the number of stop bits used by the serial port. Possible values of stopBits are:
692 | \verbatim
693 | STOP_1 1 stop bit
694 | STOP_1_5 1.5 stop bits
695 | STOP_2 2 stop bits
696 | \endverbatim
697 | \note
698 | This function is subject to the following restrictions:
699 | \par
700 | 2 stop bits cannot be used with 5 data bits.
701 | \par
702 | POSIX does not support 1.5 stop bits.
703 |
704 | */
705 | void Posix_QextSerialPort::setStopBits(StopBitsType stopBits)
706 | {
707 | LOCK_MUTEX();
708 | if (Settings.StopBits!=stopBits) {
709 | if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || stopBits==STOP_1_5) {}
710 | else {
711 | Settings.StopBits=stopBits;
712 | }
713 | }
714 | if (isOpen()) {
715 | switch (stopBits) {
716 |
717 | /*one stop bit*/
718 | case STOP_1:
719 | Settings.StopBits=stopBits;
720 | Posix_CommConfig.c_cflag&=(~CSTOPB);
721 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
722 | break;
723 |
724 | /*1.5 stop bits*/
725 | case STOP_1_5:
726 | TTY_WARNING("Posix_QextSerialPort: 1.5 stop bit operation is not supported by POSIX.");
727 | break;
728 |
729 | /*two stop bits*/
730 | case STOP_2:
731 | if (Settings.DataBits==DATA_5) {
732 | TTY_WARNING("Posix_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
733 | }
734 | else {
735 | Settings.StopBits=stopBits;
736 | Posix_CommConfig.c_cflag|=CSTOPB;
737 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
738 | }
739 | break;
740 | }
741 | }
742 | UNLOCK_MUTEX();
743 | }
744 |
745 | /*!
746 | \fn void Posix_QextSerialPort::setFlowControl(FlowType flow)
747 | Sets the flow control used by the port. Possible values of flow are:
748 | \verbatim
749 | FLOW_OFF No flow control
750 | FLOW_HARDWARE Hardware (RTS/CTS) flow control
751 | FLOW_XONXOFF Software (XON/XOFF) flow control
752 | \endverbatim
753 | \note
754 | FLOW_HARDWARE may not be supported on all versions of UNIX. In cases where it is
755 | unsupported, FLOW_HARDWARE is the same as FLOW_OFF.
756 |
757 | */
758 | void Posix_QextSerialPort::setFlowControl(FlowType flow)
759 | {
760 | LOCK_MUTEX();
761 | if (Settings.FlowControl!=flow) {
762 | Settings.FlowControl=flow;
763 | }
764 | if (isOpen()) {
765 | switch(flow) {
766 |
767 | /*no flow control*/
768 | case FLOW_OFF:
769 | Posix_CommConfig.c_cflag&=(~CRTSCTS);
770 | Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY));
771 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
772 | break;
773 |
774 | /*software (XON/XOFF) flow control*/
775 | case FLOW_XONXOFF:
776 | Posix_CommConfig.c_cflag&=(~CRTSCTS);
777 | Posix_CommConfig.c_iflag|=(IXON|IXOFF|IXANY);
778 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
779 | break;
780 |
781 | case FLOW_HARDWARE:
782 | Posix_CommConfig.c_cflag|=CRTSCTS;
783 | Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY));
784 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
785 | break;
786 | }
787 | }
788 | UNLOCK_MUTEX();
789 | }
790 |
791 | /*!
792 | \fn void Posix_QextSerialPort::setTimeout(ulong sec);
793 | Sets the read and write timeouts for the port to millisec milliseconds.
794 | Note that this is a per-character timeout, i.e. the port will wait this long for each
795 | individual character, not for the whole read operation. This timeout also applies to the
796 | bytesWaiting() function.
797 |
798 | \note
799 | POSIX does not support millisecond-level control for I/O timeout values. Any
800 | timeout set using this function will be set to the next lowest tenth of a second for
801 | the purposes of detecting read or write timeouts. For example a timeout of 550 milliseconds
802 | will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and
803 | writing the port. However millisecond-level control is allowed by the select() system call,
804 | so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for
805 | the purpose of detecting available bytes in the read buffer.
806 |
807 | */
808 | void Posix_QextSerialPort::setTimeout(long millisec)
809 | {
810 | LOCK_MUTEX();
811 | Settings.Timeout_Millisec = millisec;
812 | Posix_Copy_Timeout.tv_sec = millisec / 1000;
813 | Posix_Copy_Timeout.tv_usec = millisec % 1000;
814 | if (isOpen()) {
815 | tcgetattr(Posix_File->handle(), &Posix_CommConfig);
816 | Posix_CommConfig.c_cc[VTIME] = millisec/100;
817 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
818 | }
819 | UNLOCK_MUTEX();
820 | }
821 |
822 | /*!
823 | \fn bool Posix_QextSerialPort::open(OpenMode mode)
824 | Opens the serial port associated to this class.
825 | This function has no effect if the port associated with the class is already open.
826 | The port is also configured to the current settings, as stored in the Settings structure.
827 | */
828 | bool Posix_QextSerialPort::open(OpenMode mode)
829 | {
830 | LOCK_MUTEX();
831 | if (mode == QIODevice::NotOpen)
832 | return isOpen();
833 | if (!isOpen()) {
834 | /*open the port*/
835 | Posix_File->setFileName(port);
836 | qDebug("Trying to open File");
837 | if (Posix_File->open(QIODevice::ReadWrite|QIODevice::Unbuffered)) {
838 | qDebug("Opened File succesfully");
839 | /*set open mode*/
840 | QIODevice::open(mode);
841 |
842 | /*configure port settings*/
843 | tcgetattr(Posix_File->handle(), &Posix_CommConfig);
844 |
845 | /*set up other port settings*/
846 | Posix_CommConfig.c_cflag|=CREAD|CLOCAL;
847 | Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG));
848 | Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY));
849 | Posix_CommConfig.c_oflag&=(~OPOST);
850 | Posix_CommConfig.c_cc[VMIN]=0;
851 | Posix_CommConfig.c_cc[VINTR] = _POSIX_VDISABLE;
852 | Posix_CommConfig.c_cc[VQUIT] = _POSIX_VDISABLE;
853 | Posix_CommConfig.c_cc[VSTART] = _POSIX_VDISABLE;
854 | Posix_CommConfig.c_cc[VSTOP] = _POSIX_VDISABLE;
855 | Posix_CommConfig.c_cc[VSUSP] = _POSIX_VDISABLE;
856 | setBaudRate(Settings.BaudRate);
857 | setDataBits(Settings.DataBits);
858 | setParity(Settings.Parity);
859 | setStopBits(Settings.StopBits);
860 | setFlowControl(Settings.FlowControl);
861 | setTimeout( Settings.Timeout_Millisec);
862 | tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
863 | } else {
864 | qDebug("Could not open File! Error code : %d", Posix_File->error());
865 | }
866 | }
867 | UNLOCK_MUTEX();
868 | return isOpen();
869 | }
870 |
871 | /*!
872 | \fn void Posix_QextSerialPort::close()
873 | Closes a serial port. This function has no effect if the serial port associated with the class
874 | is not currently open.
875 | */
876 | void Posix_QextSerialPort::close()
877 | {
878 | LOCK_MUTEX();
879 | Posix_File->close();
880 | QIODevice::close();
881 | UNLOCK_MUTEX();
882 | }
883 |
884 | /*!
885 | \fn void Posix_QextSerialPort::flush()
886 | Flushes all pending I/O to the serial port. This function has no effect if the serial port
887 | associated with the class is not currently open.
888 | */
889 | void Posix_QextSerialPort::flush()
890 | {
891 | LOCK_MUTEX();
892 | if (isOpen()) {
893 | Posix_File->flush();
894 | }
895 | UNLOCK_MUTEX();
896 | }
897 |
898 | /*!
899 | \fn qint64 Posix_QextSerialPort::size() const
900 | This function will return the number of bytes waiting in the receive queue of the serial port.
901 | It is included primarily to provide a complete QIODevice interface, and will not record errors
902 | in the lastErr member (because it is const). This function is also not thread-safe - in
903 | multithreading situations, use Posix_QextSerialPort::bytesWaiting() instead.
904 | */
905 | qint64 Posix_QextSerialPort::size() const
906 | {
907 | int numBytes;
908 | if (ioctl(Posix_File->handle(), FIONREAD, &numBytes)<0) {
909 | numBytes=0;
910 | }
911 | return (qint64)numBytes;
912 | }
913 |
914 | /*!
915 | \fn qint64 Posix_QextSerialPort::bytesAvailable()
916 | Returns the number of bytes waiting in the port's receive queue. This function will return 0 if
917 | the port is not currently open, or -1 on error. Error information can be retrieved by calling
918 | Posix_QextSerialPort::getLastError().
919 | */
920 | qint64 Posix_QextSerialPort::bytesAvailable()
921 | {
922 | LOCK_MUTEX();
923 | if (isOpen()) {
924 | int bytesQueued;
925 | fd_set fileSet;
926 | FD_ZERO(&fileSet);
927 | FD_SET(Posix_File->handle(), &fileSet);
928 |
929 | /*on Linux systems the Posix_Timeout structure will be altered by the select() call.
930 | Make sure we use the right timeout values*/
931 | //memcpy(&Posix_Timeout, &Posix_Copy_Timeout, sizeof(struct timeval));
932 | Posix_Timeout = Posix_Copy_Timeout;
933 | int n=select(Posix_File->handle()+1, &fileSet, NULL, &fileSet, &Posix_Timeout);
934 | if (!n) {
935 | lastErr=E_PORT_TIMEOUT;
936 | UNLOCK_MUTEX();
937 | return -1;
938 | }
939 | if (n==-1 || ioctl(Posix_File->handle(), FIONREAD, &bytesQueued)==-1) {
940 | translateError(errno);
941 | UNLOCK_MUTEX();
942 | return -1;
943 | }
944 | lastErr=E_NO_ERROR;
945 | UNLOCK_MUTEX();
946 | return bytesQueued + QIODevice::bytesAvailable();
947 | }
948 | UNLOCK_MUTEX();
949 | return 0;
950 | }
951 |
952 | /*!
953 | \fn void Posix_QextSerialPort::ungetChar(char)
954 | This function is included to implement the full QIODevice interface, and currently has no
955 | purpose within this class. This function is meaningless on an unbuffered device and currently
956 | only prints a warning message to that effect.
957 | */
958 | void Posix_QextSerialPort::ungetChar(char)
959 | {
960 | /*meaningless on unbuffered sequential device - return error and print a warning*/
961 | TTY_WARNING("Posix_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless");
962 | }
963 |
964 | /*!
965 | \fn void Posix_QextSerialPort::translateError(ulong error)
966 | Translates a system-specific error code to a QextSerialPort error code. Used internally.
967 | */
968 | void Posix_QextSerialPort::translateError(ulong error)
969 | {
970 | switch (error) {
971 | case EBADF:
972 | case ENOTTY:
973 | lastErr=E_INVALID_FD;
974 | break;
975 |
976 | case EINTR:
977 | lastErr=E_CAUGHT_NON_BLOCKED_SIGNAL;
978 | break;
979 |
980 | case ENOMEM:
981 | lastErr=E_NO_MEMORY;
982 | break;
983 | }
984 | }
985 |
986 | /*!
987 | \fn void Posix_QextSerialPort::setDtr(bool set)
988 | Sets DTR line to the requested state (high by default). This function will have no effect if
989 | the port associated with the class is not currently open.
990 | */
991 | void Posix_QextSerialPort::setDtr(bool set)
992 | {
993 | LOCK_MUTEX();
994 | if (isOpen()) {
995 | int status;
996 | ioctl(Posix_File->handle(), TIOCMGET, &status);
997 | if (set) {
998 | status|=TIOCM_DTR;
999 | }
1000 | else {
1001 | status&=~TIOCM_DTR;
1002 | }
1003 | ioctl(Posix_File->handle(), TIOCMSET, &status);
1004 | }
1005 | UNLOCK_MUTEX();
1006 | }
1007 |
1008 | /*!
1009 | \fn void Posix_QextSerialPort::setRts(bool set)
1010 | Sets RTS line to the requested state (high by default). This function will have no effect if
1011 | the port associated with the class is not currently open.
1012 | */
1013 | void Posix_QextSerialPort::setRts(bool set)
1014 | {
1015 | LOCK_MUTEX();
1016 | if (isOpen()) {
1017 | int status;
1018 | ioctl(Posix_File->handle(), TIOCMGET, &status);
1019 | if (set) {
1020 | status|=TIOCM_RTS;
1021 | }
1022 | else {
1023 | status&=~TIOCM_RTS;
1024 | }
1025 | ioctl(Posix_File->handle(), TIOCMSET, &status);
1026 | }
1027 | UNLOCK_MUTEX();
1028 | }
1029 |
1030 | /*!
1031 | \fn unsigned long Posix_QextSerialPort::lineStatus()
1032 | returns the line status as stored by the port function. This function will retrieve the states
1033 | of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines
1034 | can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned
1035 | long with specific bits indicating which lines are high. The following constants should be used
1036 | to examine the states of individual lines:
1037 |
1038 | \verbatim
1039 | Mask Line
1040 | ------ ----
1041 | LS_CTS CTS
1042 | LS_DSR DSR
1043 | LS_DCD DCD
1044 | LS_RI RI
1045 | LS_RTS RTS (POSIX only)
1046 | LS_DTR DTR (POSIX only)
1047 | LS_ST Secondary TXD (POSIX only)
1048 | LS_SR Secondary RXD (POSIX only)
1049 | \endverbatim
1050 |
1051 | This function will return 0 if the port associated with the class is not currently open.
1052 | */
1053 | unsigned long Posix_QextSerialPort::lineStatus()
1054 | {
1055 | unsigned long Status=0, Temp=0;
1056 | LOCK_MUTEX();
1057 | if (isOpen()) {
1058 | ioctl(Posix_File->handle(), TIOCMGET, &Temp);
1059 | if (Temp&TIOCM_CTS) {
1060 | Status|=LS_CTS;
1061 | }
1062 | if (Temp&TIOCM_DSR) {
1063 | Status|=LS_DSR;
1064 | }
1065 | if (Temp&TIOCM_RI) {
1066 | Status|=LS_RI;
1067 | }
1068 | if (Temp&TIOCM_CD) {
1069 | Status|=LS_DCD;
1070 | }
1071 | if (Temp&TIOCM_DTR) {
1072 | Status|=LS_DTR;
1073 | }
1074 | if (Temp&TIOCM_RTS) {
1075 | Status|=LS_RTS;
1076 | }
1077 | if (Temp&TIOCM_ST) {
1078 | Status|=LS_ST;
1079 | }
1080 | if (Temp&TIOCM_SR) {
1081 | Status|=LS_SR;
1082 | }
1083 | }
1084 | UNLOCK_MUTEX();
1085 | return Status;
1086 | }
1087 |
1088 | /*!
1089 | \fn qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize)
1090 | Reads a block of data from the serial port. This function will read at most maxSize bytes from
1091 | the serial port and place them in the buffer pointed to by data. Return value is the number of
1092 | bytes actually read, or -1 on error.
1093 |
1094 | \warning before calling this function ensure that serial port associated with this class
1095 | is currently open (use isOpen() function to check if port is open).
1096 | */
1097 | qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize)
1098 | {
1099 | LOCK_MUTEX();
1100 | int retVal=0;
1101 | retVal=Posix_File->read(data, maxSize);
1102 | if (retVal==-1)
1103 | lastErr=E_READ_FAILED;
1104 | UNLOCK_MUTEX();
1105 |
1106 | return retVal;
1107 | }
1108 |
1109 | /*!
1110 | \fn qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize)
1111 | Writes a block of data to the serial port. This function will write maxSize bytes
1112 | from the buffer pointed to by data to the serial port. Return value is the number
1113 | of bytes actually written, or -1 on error.
1114 |
1115 | \warning before calling this function ensure that serial port associated with this class
1116 | is currently open (use isOpen() function to check if port is open).
1117 | */
1118 | qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize)
1119 | {
1120 | LOCK_MUTEX();
1121 | int retVal=0;
1122 | retVal=Posix_File->write(data, maxSize);
1123 | if (retVal==-1)
1124 | lastErr=E_WRITE_FAILED;
1125 | UNLOCK_MUTEX();
1126 |
1127 | return retVal;
1128 | }
1129 |
--------------------------------------------------------------------------------
/posix_qextserialport.h:
--------------------------------------------------------------------------------
1 | #ifndef _POSIX_QEXTSERIALPORT_H_
2 | #define _POSIX_QEXTSERIALPORT_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include "qextserialbase.h"
12 |
13 | class Posix_QextSerialPort:public QextSerialBase
14 | {
15 | private:
16 | /*!
17 | * This method is a part of constructor.
18 | */
19 | void init();
20 |
21 | protected:
22 | QFile* Posix_File;
23 | struct termios Posix_CommConfig;
24 | struct timeval Posix_Timeout;
25 | struct timeval Posix_Copy_Timeout;
26 |
27 | virtual qint64 readData(char * data, qint64 maxSize);
28 | virtual qint64 writeData(const char * data, qint64 maxSize);
29 |
30 | public:
31 | Posix_QextSerialPort();
32 | Posix_QextSerialPort(const Posix_QextSerialPort& s);
33 | Posix_QextSerialPort(const QString & name, QextSerialBase::QueryMode mode = QextSerialBase::Polling);
34 | Posix_QextSerialPort(const PortSettings& settings, QextSerialBase::QueryMode mode = QextSerialBase::Polling);
35 | Posix_QextSerialPort(const QString & name, const PortSettings& settings, QextSerialBase::QueryMode mode = QextSerialBase::Polling);
36 | Posix_QextSerialPort& operator=(const Posix_QextSerialPort& s);
37 | virtual ~Posix_QextSerialPort();
38 |
39 | virtual void setBaudRate(BaudRateType);
40 | virtual void setDataBits(DataBitsType);
41 | virtual void setParity(ParityType);
42 | virtual void setStopBits(StopBitsType);
43 | virtual void setFlowControl(FlowType);
44 | virtual void setTimeout(long);
45 |
46 | virtual bool open(OpenMode mode);
47 | virtual void close();
48 | virtual void flush();
49 |
50 | virtual qint64 size() const;
51 | virtual qint64 bytesAvailable();
52 |
53 | virtual void ungetChar(char c);
54 |
55 | virtual void translateError(ulong error);
56 |
57 | virtual void setDtr(bool set=true);
58 | virtual void setRts(bool set=true);
59 | virtual ulong lineStatus();
60 |
61 | };
62 |
63 | #endif
64 |
--------------------------------------------------------------------------------
/qextserialbase.cpp:
--------------------------------------------------------------------------------
1 | #include "qextserialbase.h"
2 |
3 | /*!
4 | \fn QextSerialBase::QextSerialBase()
5 | Default constructor.
6 | */
7 | QextSerialBase::QextSerialBase()
8 | : QIODevice()
9 | {
10 |
11 | #ifdef _TTY_WIN_
12 | setPortName("COM1");
13 |
14 | #elif defined(_TTY_IRIX_)
15 | setPortName("/dev/ttyf1");
16 |
17 | #elif defined(_TTY_HPUX_)
18 | setPortName("/dev/tty1p0");
19 |
20 | #elif defined(_TTY_SUN_)
21 | setPortName("/dev/ttya");
22 |
23 | #elif defined(_TTY_DIGITAL_)
24 | setPortName("/dev/tty01");
25 |
26 | #elif defined(_TTY_FREEBSD_)
27 | setPortName("/dev/ttyd1");
28 |
29 | #else
30 | setPortName("/dev/ttyS0");
31 | #endif
32 |
33 | construct();
34 | }
35 |
36 | /*!
37 | \fn QextSerialBase::QextSerialBase(const QString & name)
38 | Construct a port and assign it to the device specified by the name parameter.
39 | */
40 | QextSerialBase::QextSerialBase(const QString & name)
41 | : QIODevice()
42 | {
43 | setPortName(name);
44 | construct();
45 | }
46 |
47 | /*!
48 | \fn QextSerialBase::~QextSerialBase()
49 | Standard destructor.
50 | */
51 | QextSerialBase::~QextSerialBase()
52 | {
53 | delete mutex;
54 | }
55 |
56 | /*!
57 | \fn void QextSerialBase::construct()
58 | Common constructor function for setting up default port settings.
59 | (115200 Baud, 8N1, Hardware flow control where supported, otherwise no flow control, and 0 ms timeout).
60 | */
61 | void QextSerialBase::construct()
62 | {
63 | Settings.BaudRate=BAUD115200;
64 | Settings.DataBits=DATA_8;
65 | Settings.Parity=PAR_NONE;
66 | Settings.StopBits=STOP_1;
67 | Settings.FlowControl=FLOW_HARDWARE;
68 | Settings.Timeout_Millisec=500;
69 | mutex = new QMutex( QMutex::Recursive );
70 | setOpenMode(QIODevice::NotOpen);
71 | }
72 |
73 | void QextSerialBase::setQueryMode(QueryMode mechanism)
74 | {
75 | _queryMode = mechanism;
76 | }
77 |
78 | /*!
79 | \fn void QextSerialBase::setPortName(const QString & name)
80 | Sets the name of the device associated with the object, e.g. "COM1", or "/dev/ttyS0".
81 | */
82 | void QextSerialBase::setPortName(const QString & name)
83 | {
84 | port = name;
85 | }
86 |
87 | /*!
88 | \fn QString QextSerialBase::portName() const
89 | Returns the name set by setPortName().
90 | */
91 | QString QextSerialBase::portName() const
92 | {
93 | return port;
94 | }
95 |
96 | /*!
97 | \fn BaudRateType QextSerialBase::baudRate(void) const
98 | Returns the baud rate of the serial port. For a list of possible return values see
99 | the definition of the enum BaudRateType.
100 | */
101 | BaudRateType QextSerialBase::baudRate(void) const
102 | {
103 | return Settings.BaudRate;
104 | }
105 |
106 | /*!
107 | \fn DataBitsType QextSerialBase::dataBits() const
108 | Returns the number of data bits used by the port. For a list of possible values returned by
109 | this function, see the definition of the enum DataBitsType.
110 | */
111 | DataBitsType QextSerialBase::dataBits() const
112 | {
113 | return Settings.DataBits;
114 | }
115 |
116 | /*!
117 | \fn ParityType QextSerialBase::parity() const
118 | Returns the type of parity used by the port. For a list of possible values returned by
119 | this function, see the definition of the enum ParityType.
120 | */
121 | ParityType QextSerialBase::parity() const
122 | {
123 | return Settings.Parity;
124 | }
125 |
126 | /*!
127 | \fn StopBitsType QextSerialBase::stopBits() const
128 | Returns the number of stop bits used by the port. For a list of possible return values, see
129 | the definition of the enum StopBitsType.
130 | */
131 | StopBitsType QextSerialBase::stopBits() const
132 | {
133 | return Settings.StopBits;
134 | }
135 |
136 | /*!
137 | \fn FlowType QextSerialBase::flowControl() const
138 | Returns the type of flow control used by the port. For a list of possible values returned
139 | by this function, see the definition of the enum FlowType.
140 | */
141 | FlowType QextSerialBase::flowControl() const
142 | {
143 | return Settings.FlowControl;
144 | }
145 |
146 | /*!
147 | \fn bool QextSerialBase::isSequential() const
148 | Returns true if device is sequential, otherwise returns false. Serial port is sequential device
149 | so this function always returns true. Check QIODevice::isSequential() documentation for more
150 | information.
151 | */
152 | bool QextSerialBase::isSequential() const
153 | {
154 | return true;
155 | }
156 |
157 | /*!
158 | \fn bool QextSerialBase::atEnd() const
159 | This function will return true if the input buffer is empty (or on error), and false otherwise.
160 | Call QextSerialBase::lastError() for error information.
161 | */
162 | bool QextSerialBase::atEnd() const
163 | {
164 | if (size()) {
165 | return true;
166 | }
167 | return false;
168 | }
169 |
170 | /*!
171 | \fn qint64 QextSerialBase::readLine(char * data, qint64 maxSize)
172 | This function will read a line of buffered input from the port, stopping when either maxSize bytes
173 | have been read, the port has no more data available, or a newline is encountered.
174 | The value returned is the length of the string that was read.
175 | */
176 | qint64 QextSerialBase::readLine(char * data, qint64 maxSize)
177 | {
178 | qint64 numBytes = bytesAvailable();
179 | char* pData = data;
180 |
181 | if (maxSize < 2) //maxSize must be larger than 1
182 | return -1;
183 |
184 | /*read a byte at a time for MIN(bytesAvail, maxSize - 1) iterations, or until a newline*/
185 | while (pData<(data+numBytes) && --maxSize) {
186 | readData(pData, 1);
187 | if (*pData++ == '\n') {
188 | break;
189 | }
190 | }
191 | *pData='\0';
192 |
193 | /*return size of data read*/
194 | return (pData-data);
195 | }
196 |
197 | /*!
198 | \fn ulong QextSerialBase::lastError() const
199 | Returns the code for the last error encountered by the port, or E_NO_ERROR if the last port
200 | operation was successful. Possible error codes are:
201 |
202 | \verbatim
203 | Error Explanation
204 | --------------------------- -------------------------------------------------------------
205 | E_NO_ERROR No Error has occured
206 | E_INVALID_FD Invalid file descriptor (port was not opened correctly)
207 | E_NO_MEMORY Unable to allocate memory tables (POSIX)
208 | E_CAUGHT_NON_BLOCKED_SIGNAL Caught a non-blocked signal (POSIX)
209 | E_PORT_TIMEOUT Operation timed out (POSIX)
210 | E_INVALID_DEVICE The file opened by the port is not a character device (POSIX)
211 | E_BREAK_CONDITION The port detected a break condition
212 | E_FRAMING_ERROR The port detected a framing error
213 | (usually caused by incorrect baud rate settings)
214 | E_IO_ERROR There was an I/O error while communicating with the port
215 | E_BUFFER_OVERRUN Character buffer overrun
216 | E_RECEIVE_OVERFLOW Receive buffer overflow
217 | E_RECEIVE_PARITY_ERROR The port detected a parity error in the received data
218 | E_TRANSMIT_OVERFLOW Transmit buffer overflow
219 | E_READ_FAILED General read operation failure
220 | E_WRITE_FAILED General write operation failure
221 | \endverbatim
222 | */
223 | ulong QextSerialBase::lastError() const
224 | {
225 | return lastErr;
226 | }
227 |
--------------------------------------------------------------------------------
/qextserialbase.h:
--------------------------------------------------------------------------------
1 | #ifndef _QEXTSERIALBASE_H_
2 | #define _QEXTSERIALBASE_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | /*if all warning messages are turned off, flag portability warnings to be turned off as well*/
10 | #ifdef _TTY_NOWARN_
11 | #define _TTY_NOWARN_PORT_
12 | #endif
13 |
14 | /*macros for thread support*/
15 | #define LOCK_MUTEX() mutex->lock()
16 | #define UNLOCK_MUTEX() mutex->unlock()
17 |
18 | /*macros for warning and debug messages*/
19 | #ifdef _TTY_NOWARN_PORT_
20 | #define TTY_PORTABILITY_WARNING(s)
21 | #else
22 | #define TTY_PORTABILITY_WARNING(s) qWarning(s)
23 | #endif /*_TTY_NOWARN_PORT_*/
24 | #ifdef _TTY_NOWARN_
25 | #define TTY_WARNING(s)
26 | #else
27 | #define TTY_WARNING(s) qWarning(s)
28 | #endif /*_TTY_NOWARN_*/
29 |
30 |
31 | /*line status constants*/
32 | #define LS_CTS 0x01
33 | #define LS_DSR 0x02
34 | #define LS_DCD 0x04
35 | #define LS_RI 0x08
36 | #define LS_RTS 0x10
37 | #define LS_DTR 0x20
38 | #define LS_ST 0x40
39 | #define LS_SR 0x80
40 |
41 | /*error constants*/
42 | #define E_NO_ERROR 0
43 | #define E_INVALID_FD 1
44 | #define E_NO_MEMORY 2
45 | #define E_CAUGHT_NON_BLOCKED_SIGNAL 3
46 | #define E_PORT_TIMEOUT 4
47 | #define E_INVALID_DEVICE 5
48 | #define E_BREAK_CONDITION 6
49 | #define E_FRAMING_ERROR 7
50 | #define E_IO_ERROR 8
51 | #define E_BUFFER_OVERRUN 9
52 | #define E_RECEIVE_OVERFLOW 10
53 | #define E_RECEIVE_PARITY_ERROR 11
54 | #define E_TRANSMIT_OVERFLOW 12
55 | #define E_READ_FAILED 13
56 | #define E_WRITE_FAILED 14
57 |
58 | /*!
59 | * Enums for port settings.
60 | */
61 | enum NamingConvention
62 | {
63 | WIN_NAMES,
64 | IRIX_NAMES,
65 | HPUX_NAMES,
66 | SUN_NAMES,
67 | DIGITAL_NAMES,
68 | FREEBSD_NAMES,
69 | LINUX_NAMES
70 | };
71 |
72 | enum BaudRateType
73 | {
74 | BAUD50, //POSIX ONLY
75 | BAUD75, //POSIX ONLY
76 | BAUD110,
77 | BAUD134, //POSIX ONLY
78 | BAUD150, //POSIX ONLY
79 | BAUD200, //POSIX ONLY
80 | BAUD300,
81 | BAUD600,
82 | BAUD1200,
83 | BAUD1800, //POSIX ONLY
84 | BAUD2400,
85 | BAUD4800,
86 | BAUD9600,
87 | BAUD14400, //WINDOWS ONLY
88 | BAUD19200,
89 | BAUD38400,
90 | BAUD56000, //WINDOWS ONLY
91 | BAUD57600,
92 | BAUD76800, //POSIX ONLY
93 | BAUD115200,
94 | BAUD128000, //WINDOWS ONLY
95 | BAUD256000 //WINDOWS ONLY
96 | };
97 |
98 | enum DataBitsType
99 | {
100 | DATA_5,
101 | DATA_6,
102 | DATA_7,
103 | DATA_8
104 | };
105 |
106 | enum ParityType
107 | {
108 | PAR_NONE,
109 | PAR_ODD,
110 | PAR_EVEN,
111 | PAR_MARK, //WINDOWS ONLY
112 | PAR_SPACE
113 | };
114 |
115 | enum StopBitsType
116 | {
117 | STOP_1,
118 | STOP_1_5, //WINDOWS ONLY
119 | STOP_2
120 | };
121 |
122 | enum FlowType
123 | {
124 | FLOW_OFF,
125 | FLOW_HARDWARE,
126 | FLOW_XONXOFF
127 | };
128 |
129 | /**
130 | * structure to contain port settings
131 | */
132 | struct PortSettings
133 | {
134 | BaudRateType BaudRate;
135 | DataBitsType DataBits;
136 | ParityType Parity;
137 | StopBitsType StopBits;
138 | FlowType FlowControl;
139 | long Timeout_Millisec;
140 | };
141 |
142 | /*!
143 | * \author Stefan Sander
144 | * \author Michal Policht
145 | *
146 | * A common base class for Win_QextSerialBase, Posix_QextSerialBase and QextSerialPort.
147 | */
148 | class QextSerialBase : public QIODevice
149 | {
150 | Q_OBJECT
151 |
152 | public:
153 | enum QueryMode {
154 | Polling,
155 | EventDriven
156 | };
157 |
158 | protected:
159 | QMutex* mutex;
160 | QString port;
161 | PortSettings Settings;
162 | ulong lastErr;
163 | QextSerialBase::QueryMode _queryMode;
164 |
165 | virtual qint64 readData(char * data, qint64 maxSize)=0;
166 | virtual qint64 writeData(const char * data, qint64 maxSize)=0;
167 |
168 | public:
169 | QextSerialBase();
170 | QextSerialBase(const QString & name);
171 | virtual ~QextSerialBase();
172 | virtual void construct();
173 | virtual void setPortName(const QString & name);
174 | virtual QString portName() const;
175 |
176 | /**!
177 | * Get query mode.
178 | * \return query mode.
179 | */
180 | inline QextSerialBase::QueryMode queryMode() const { return _queryMode; };
181 |
182 | /*!
183 | * Set desired serial communication handling style. You may choose from polling
184 | * or event driven approach. This function does nothing when port is open; to
185 | * apply changes port must be reopened.
186 | *
187 | * In event driven approach read() and write() functions are acting
188 | * asynchronously. They return immediately and the operation is performed in
189 | * the background, so they doesn't freeze the calling thread.
190 | * To determine when operation is finished, QextSerialPort runs separate thread
191 | * and monitors serial port events. Whenever the event occurs, adequate signal
192 | * is emitted.
193 | *
194 | * When polling is set, read() and write() are acting synchronously. Signals are
195 | * not working in this mode and some functions may not be available. The advantage
196 | * of polling is that it generates less overhead due to lack of signals emissions
197 | * and it doesn't start separate thread to monitor events.
198 | *
199 | * Generally event driven approach is more capable and friendly, although some
200 | * applications may need as low overhead as possible and then polling comes.
201 | *
202 | * \param mode query mode.
203 | */
204 | virtual void setQueryMode(QueryMode mode);
205 |
206 | // virtual void setBlockingRead(bool block) = 0; ///< @todo implement.
207 |
208 | virtual void setBaudRate(BaudRateType)=0;
209 | virtual BaudRateType baudRate() const;
210 | virtual void setDataBits(DataBitsType)=0;
211 | virtual DataBitsType dataBits() const;
212 | virtual void setParity(ParityType)=0;
213 | virtual ParityType parity() const;
214 | virtual void setStopBits(StopBitsType)=0;
215 | virtual StopBitsType stopBits() const;
216 | virtual void setFlowControl(FlowType)=0;
217 | virtual FlowType flowControl() const;
218 | virtual void setTimeout(long)=0;
219 |
220 | virtual bool open(OpenMode mode)=0;
221 | virtual bool isSequential() const;
222 | virtual void close()=0;
223 | virtual void flush()=0;
224 |
225 | virtual qint64 size() const=0;
226 | virtual qint64 bytesAvailable()=0;
227 | virtual bool atEnd() const;
228 |
229 | virtual void ungetChar(char c)=0;
230 | virtual qint64 readLine(char * data, qint64 maxSize);
231 |
232 | virtual ulong lastError() const;
233 | virtual void translateError(ulong error)=0;
234 |
235 | virtual void setDtr(bool set=true)=0;
236 | virtual void setRts(bool set=true)=0;
237 | virtual ulong lineStatus()=0;
238 |
239 | signals:
240 | /**
241 | * This signal is emitted whenever port settings are updated.
242 | * \param valid \p true if settings are valid, \p false otherwise.
243 | *
244 | * @todo implement.
245 | */
246 | // void validSettings(bool valid);
247 |
248 | /*!
249 | * This signal is emitted whenever dsr line has changed its state. You may
250 | * use this signal to check if device is connected.
251 | * \param status \p true when DSR signal is on, \p false otherwise.
252 | *
253 | * \see lineStatus().
254 | */
255 | void dsrChanged(bool status);
256 | };
257 |
258 | #endif
259 |
--------------------------------------------------------------------------------
/sea.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/azure42/handheld-navigator/2617750d3ff74949b30552ff1d5ae7fdf3922920/sea.jpg
--------------------------------------------------------------------------------
/src.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | style.qss
4 | background.jpg
5 | background3.png
6 | background3-2.png
7 | sea.jpg
8 |
9 |
10 |
--------------------------------------------------------------------------------
/stable.h:
--------------------------------------------------------------------------------
1 | #ifndef _STABLE_H
2 | #define _STABLE_H
3 | #include
4 | #include
5 | #endif
6 |
--------------------------------------------------------------------------------
/steering.cpp:
--------------------------------------------------------------------------------
1 | #include "steering.h"
2 | #include "um220.h"
3 | extern class um220 *beidouData;
4 | extern QLinkedList pointList;
5 |
6 | Steering::Steering(QWidget *parent) :
7 | QWidget(parent)
8 | {
9 | QCursor cursor ;
10 | cursor = QCursor(Qt::BlankCursor);
11 | setCursor(cursor);
12 |
13 | QTimer *timer = new QTimer(this);
14 | timer->start(200);
15 | QObject::connect(timer,SIGNAL(timeout()),this,SLOT(showTime()));
16 | QObject::connect(beidouData,SIGNAL(dataUpdate()),this,SLOT(showTime()));
17 |
18 | QFont font;
19 | font.setPointSize(45);
20 | rngLabel =new QLabel(tr("RNG"));
21 | rngLabel->setFont(font);
22 | cseLabel =new QLabel(tr("CSE"));
23 | cseLabel->setFont(font);
24 | spdLabel =new QLabel(tr("SPD"));
25 | spdLabel->setFont(font);
26 | ttgLabel =new QLabel(tr("TTG"));
27 | ttgLabel->setFont(font);
28 | brgLabel =new QLabel(tr("BRG"));
29 | brgLabel->setFont(font);
30 | etaLabel =new QLabel(tr("ETA"));
31 | etaLabel->setFont(font);
32 |
33 | stPainting =new stPaintingWidget;
34 | stPainting->show();
35 |
36 | mainLayout = new QGridLayout(this);
37 |
38 | mainLayout->addWidget(spdLabel,1,0);
39 | mainLayout->addWidget(rngLabel,2,0);
40 | mainLayout->addWidget(ttgLabel,3,0);
41 | mainLayout->addWidget(cseLabel,1,1);
42 | mainLayout->addWidget(brgLabel,2,1);
43 | mainLayout->addWidget(etaLabel,3,1);
44 | mainLayout->addWidget(stPainting,0,0,1,2);
45 |
46 | mainLayout->setRowStretch(0,3);
47 | mainLayout->setRowStretch(1,1);
48 | mainLayout->setRowStretch(2,1);
49 | mainLayout->setRowStretch(3,1);
50 | }
51 |
52 | void stPaintingWidget::paintEvent(QPaintEvent *event)
53 | {
54 | //手动计算paintingWidget的尺寸
55 | pWidth=QApplication::desktop()->width()-4*10;
56 | pHeight=(QApplication::desktop()->height()-7*10)/2;
57 |
58 | //代表船当前位置的箭头
59 | static const QPoint arrow[3] =
60 | {
61 | QPoint(pWidth/30, 0),
62 | QPoint(-pWidth/30, 0),
63 | QPoint(0, -pHeight/10)
64 | };
65 | setAutoFillBackground(true);
66 | QPalette palette;
67 | // palette.setColor(QPalette::Background, Qt::white);
68 | setPalette(palette);
69 |
70 | QPainter painter(this);
71 | painter.setRenderHint(QPainter::Antialiasing);
72 |
73 | //绘制边框
74 | QPen pen;
75 | pen.setWidth(5);
76 | painter.setPen(pen);
77 | painter.drawRect(QRectF(QPointF(pWidth/10.0,pHeight/9.5),
78 | QPointF(pWidth/10*9.0,pHeight/10*9.5)));
79 |
80 | const double kedu = pWidth/9.6;//每个刻度的像素长度(每个刻度15°)
81 | // const int cog0 = beidouData->cog.toDouble()/15*15;
82 | const int cog0 = beidouData->cog.toDouble()/15*15;
83 | // const double pianyi0 = pWidth/2-kedu*15/cog0;//恰比course小的刻度线坐标
84 | // const double pianyi0 = pWidth/2-kedu*15/(cog0/beidouData->cog.toDouble());//恰比course小的刻度线坐标
85 | const double pianyi0 = pWidth/2-kedu/15*beidouData->cog.toDouble();//恰比course小的刻度线坐标
86 |
87 |
88 | QFont font;
89 | font.setPixelSize(55);
90 | //绘制左半边刻度
91 | pen.setWidth(2);
92 | painter.setPen(pen);
93 | painter.setFont(font);
94 | int i=0;
95 | for(double tmp=pianyi0; tmp>pWidth/10.0; tmp-=kedu,i++)
96 | {
97 | if(tmp!=pWidth/2)
98 | {
99 | painter.drawLine(tmp,pHeight/10*9.5,tmp,pHeight*0.95-pHeight/10);
100 | if((cog0-i*15)>0)
101 | painter.drawText(QPoint(tmp,pHeight/10*8),QString::number(cog0-i*15));
102 | else
103 | painter.drawText(QPoint(tmp,pHeight/10*8),QString::number(360+cog0-i*15));
104 | }
105 | }
106 | //绘制右半边刻度
107 | for(double tmp=pianyi0,i=0; tmp0)
111 | painter.drawText(QPoint(tmp,pHeight/10*8),QString::number(cog0-i*15));
112 | // else
113 | // painter.drawText(QPoint(tmp,pHeight/10*8),QString::number(360+cog0-i*15));
114 | }
115 |
116 | font.setPixelSize(35);
117 | painter.setFont(font);
118 |
119 | painter.drawText(QPoint(pWidth/10.0,pHeight/2),QString("W"));
120 | painter.drawText(QPoint(pWidth/10.0*8.5,pHeight/2),QString("E"));
121 |
122 | //绘制代表船只位置的中心箭头
123 | painter.setPen(Qt::NoPen);
124 | painter.setBrush(Qt::darkRed);
125 | painter.translate(pWidth/2,pHeight/10*10.5);
126 | painter.drawConvexPolygon(arrow, 3);
127 | }
128 |
129 | void Steering::showTime()
130 | {
131 | rngString = "RNG:";
132 | if(pointList.isEmpty() == false)
133 | rngString.append(QString::number(
134 | beidouData->rngGet(pointList.first())));
135 | else rngString.append("NO POINT");
136 |
137 | rngLabel->setText(rngString);
138 | cseString = "CSE:";
139 | cseString.append(beidouData->cog);
140 | cseString.append("°");
141 | cseLabel->setText(cseString);
142 |
143 | spdString = "SPD:";
144 | spdString.append(beidouData->spd);
145 | spdString.append("kt");
146 | spdLabel->setText(spdString);
147 |
148 | ttgString = "TTG:";
149 | if(pointList.isEmpty() == false)
150 | {
151 | ttgString.append(QString::number(beidouData->rngGet(pointList.first())
152 | /beidouData->spd.toDouble()));
153 | ttgString.append("h");
154 | }
155 | else ttgString.append("NO POINT");
156 | ttgLabel->setText(ttgString);
157 |
158 | brgString = "BRG:";
159 | if(pointList.isEmpty() == false)
160 | {
161 | brgString.append(QString::number
162 | (beidouData->brgGet(pointList.first())));
163 | brgString.append("h");
164 | }
165 | else brgString.append("NO POINT");
166 | brgLabel->setText(brgString);
167 |
168 | etaString = "ETA:";
169 | if(pointList.isEmpty() == false)
170 | {
171 | QTime timeTemp;
172 | timeTemp.addSecs(beidouData->rngGet(pointList.first())
173 | /beidouData->spd.toDouble()*3600);
174 | etaString.append(timeTemp.toString("hh:mm:ss"));
175 | etaString.append("h");
176 | }
177 | else ttgString.append("NO POINT");
178 | etaLabel->setText(etaString);
179 |
180 |
181 | update();
182 | stPainting->update();
183 | }
184 |
185 |
186 |
--------------------------------------------------------------------------------
/steering.h:
--------------------------------------------------------------------------------
1 | #ifndef STEERING_H
2 | #define STEERING_H
3 | #include"stable.h"
4 | #include "um220.h"
5 |
6 | class stPaintingWidget : public QWidget
7 | {
8 | Q_OBJECT
9 | public:
10 | // double angelCalc(QPointF);
11 | protected:
12 | void paintEvent(QPaintEvent *event);
13 | int pWidth,pHeight;
14 | private:
15 | //private slots:
16 | // void showTime();
17 | };
18 |
19 |
20 | class Steering : public QWidget
21 | {
22 | Q_OBJECT
23 | public:
24 | Steering(QWidget *parent=0);
25 | stPaintingWidget *getStPainting() const;
26 | void setStPainting(stPaintingWidget *value);
27 |
28 | private:
29 | QLabel *paintingLabel;
30 | QLabel *rngLabel;
31 | QLabel *ttgLabel;
32 | QLabel *brgLabel;
33 | QLabel *etaLabel;
34 | QLabel *spdLabel;
35 | QLabel *cseLabel;
36 | QGridLayout *mainLayout;
37 |
38 | QString rngString;
39 | QString ttgString;
40 | QString brgString;
41 | QString etaString;
42 | QString spdString;
43 | QString cseString;
44 |
45 | protected:
46 | // void paintEvent(QPaintEvent *event);
47 | stPaintingWidget *stPainting;
48 |
49 | private slots:
50 | void showTime();
51 |
52 | };
53 | #endif
54 |
--------------------------------------------------------------------------------
/style.qss:
--------------------------------------------------------------------------------
1 | QLabel{
2 | /* color: black;*/
3 | /* background:black;*/
4 | background:url(:/background.jpg);
5 | border-style : outset;
6 | border-width : 5px;
7 | border-color : gray;
8 | border-radius : 10px;
9 | qproperty-alignment: 'AlignVCenter | AlignLeft';
10 | qproperty-wordWrap: true;
11 | }
12 |
13 | QStackedWidget
14 | {
15 | color:transparent;
16 | background:url(:/background3-2.png);
17 | /*内层框架*/
18 | }
19 |
20 | QSplitter
21 | {
22 | color:white;
23 | background:url(:/background3.png);
24 | /*外层框架*/
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/um220.cpp:
--------------------------------------------------------------------------------
1 | #include "stable.h"
2 | #include "um220.h"
3 | # define PI 3.14159
4 | #include
5 | #include"math.h"
6 |
7 | void um220::um220init()
8 | {
9 | Com = new Posix_QextSerialPort("/dev/ttySAC2",QextSerialBase::Polling);
10 | Com ->open(QIODevice::ReadWrite);
11 | Com->setBaudRate(BAUD115200);
12 | Com->setDataBits(DATA_8);
13 | Com->setParity(PAR_NONE);
14 | Com->setStopBits(STOP_1);
15 | Com->setFlowControl(FLOW_OFF);
16 | Com->setTimeout(400);
17 | rTimer = new QTimer(this);
18 | rTimer->start(200);
19 | connect(rTimer,SIGNAL(timeout()),this,SLOT(readCom()));
20 | }
21 | /**
22 | * @brief
23 | *
24 | */
25 | void um220::readCom()
26 | {
27 | QString temp = Com->readAll();
28 | if(temp[0]=='$')
29 | {
30 | all = temp;
31 | /*time = temp.mid(7,6);
32 | Lat = temp.mid(18,11);
33 | N = temp.mid(30,1);
34 | Lon = temp.mid(32,12);
35 | cog = temp.mid(55,7);
36 |
37 | E = temp.mid(45,1);
38 | FS = temp.mid(47,1);
39 | NoSV = temp.mid(49,1);
40 | spd = temp.mid(temp.indexOf("$GNRMC")+55,7);*/
41 |
42 | time = QString("123456");
43 | Lat = QString("123.4");
44 | N = QString("1");
45 | Lon = QString("78.4");
46 | E = QString("0");
47 |
48 | spd = QString("1");
49 | cog = QString("60.0123");
50 | //以上数据均需根据导航设备数据协议进行修改
51 | emit dataUpdate();
52 |
53 |
54 |
55 | }
56 | }
57 | /**
58 | * @brgGet
59 | *
60 | * @param 目标点地理坐标
61 | * @return 目标点与正北方向夹角-当前点与正北方向夹角
62 | * =当前点与目标点的夹角
63 | */
64 | double um220::brgGet(QPointF a)
65 | {
66 | double temp,vx=a.x(),vy=a.y();
67 | if (vx>0 && vy==0)
68 | temp=0;
69 | else if (vx>0 && vy>0)
70 | temp=180*(atan(vy/vx));
71 | else if (vx>0 && vy<0)
72 | temp=180*(atan(vy/vx)+2*PI);
73 | else if (vx<0 && vy==0)
74 | temp=180*(PI);
75 | else if (vx<0 && vy>0)
76 | temp=180*(atan(vy/vx)+PI);
77 | else if (vx<0 && vy>0)
78 | temp=180*(atan(vy/vx)+PI);
79 | //else if (vx==0 && vy==0)
80 | //printf ("您输入的是同一个点");
81 | else if (vx==0 && vy>0)
82 | temp=180*(PI/2);
83 | else
84 | temp=180*(PI*3/2);
85 |
86 | return (temp-cog.toDouble());
87 | }
88 |
89 | /**
90 | * @rngGet
91 | *
92 | * @param 目标点地理坐标
93 | * @return 当前点与目标点的距离(海里)
94 | */
95 | double um220::rad(double d)
96 | {
97 | return d * PI / 180.0;
98 | }
99 | double um220::rngGet(QPointF targetCoor)
100 | {
101 | const double EARTH_RADIUS = 6378.137;
102 | const double lat1=Lat.toDouble(),lng1=Lon.toDouble(),
103 | lat2=targetCoor.y(),lng2=targetCoor.x();
104 |
105 | double radLat1 = rad(lat1);
106 | double radLat2 = rad(lat2);
107 | double a = radLat1 - radLat2;
108 | double b = rad(lng1) - rad(lng2);
109 | double s = 2 * asin(sqrt(pow(sin(a/2),2) +
110 | cos(rad(lat1))*cos(rad(lat2))*pow(sin(b/2),2)));
111 | s = s * EARTH_RADIUS;
112 | return s;
113 | }
114 |
115 |
--------------------------------------------------------------------------------
/um220.h:
--------------------------------------------------------------------------------
1 | #ifndef UM220_H
2 | #define UM220_H
3 | #include "posix_qextserialport.h"
4 | #include
5 | #include
6 | #include
7 |
8 |
9 |
10 | class um220 : public QThread
11 | {
12 | Q_OBJECT
13 | public:
14 | Posix_QextSerialPort *Com;
15 | void um220init();
16 | // QTimer *rTimer;
17 |
18 | QString all;
19 | QString time;
20 | QString Lat;
21 | QString N;
22 | QString Lon;
23 | QString E;
24 | QString FS;
25 | QString NoSV;
26 | QString HDOP;
27 | QString msl;
28 | QString M;
29 | QString DiffAge;
30 | QString DiffStation;
31 | QString cs;
32 |
33 | QString spd;
34 | QString cog;
35 | QString date;
36 | QString mv;
37 | QString mvE;
38 | QString mode;
39 | double brgGet(QPointF a);
40 |
41 | double rngGet(QPointF targetCoor);
42 | private :
43 | QTimer *rTimer;
44 |
45 | double rad(double d);
46 | private slots:
47 | void readCom();
48 | signals:
49 | void dataUpdate(void);
50 | };
51 |
52 | #endif //UM220_H
53 |
--------------------------------------------------------------------------------