作者 王振宇

第一次修改控件版本

正在显示 30 个修改的文件 包含 4871 行增加0 行删除

要显示太多修改。

为保证性能只显示 30 of 30+ 个文件。

  1 +{
  2 + "git.ignoreLimitWarning": true
  3 +}
  1 +cmake_minimum_required(VERSION 2.8)
  2 +
  3 +if (NOT USE_SYSTEM_ARCH)
  4 + # select use platform 'LINUX' or 'RTOS' here, reset cache and reload cmake project
  5 + set(USE_SYSTEM_ARCH LINUX)
  6 +endif ()
  7 +
  8 +if (USE_SYSTEM_ARCH MATCHES RTOS)
  9 + cmake_minimum_required(VERSION 3.15)
  10 + set(CMAKE_C_COMPILER arm-none-eabi-gcc)
  11 + set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
  12 + set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
  13 + set(CMAKE_AR arm-none-eabi-ar)
  14 + set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
  15 + set(CMAKE_OBJDUMP arm-none-eabi-objdump)
  16 + set(SIZE arm-none-eabi-size)
  17 + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
  18 +endif ()
  19 +
  20 +project(entry)
  21 +
  22 +# Disable in-source builds to prevent source tree corruption.
  23 +if (" ${CMAKE_SOURCE_DIR}" STREQUAL " ${CMAKE_BINARY_DIR}")
  24 + message(FATAL_ERROR "FATAL: In-source builds are not allowed.
  25 + You should create a separate directory for build files.")
  26 +endif ()
  27 +
  28 +if (USE_SYSTEM_ARCH MATCHES LINUX)
  29 + add_definitions(-DSYSTEM_ARCH_LINUX)
  30 + add_subdirectory(samples/sample_c/platform/linux/manifold2)
  31 +
  32 + message("-- Attention: If you want to use opencv C++ sample, please uncomment the next line.")
  33 +# add_subdirectory(samples/sample_c++/platform/linux/manifold2)
  34 +
  35 + set(LIBRARY_PATH psdk_lib/lib/x86_64-linux-gnu-gcc)
  36 +
  37 + install(FILES ${LIBRARY_PATH}/libpayloadsdk.a
  38 + DESTINATION "${CMAKE_INSTALL_PREFIX}/lib"
  39 + )
  40 +
  41 + install(DIRECTORY psdk_lib/include
  42 + DESTINATION "${CMAKE_INSTALL_PREFIX}"
  43 + )
  44 +elseif (USE_SYSTEM_ARCH MATCHES RTOS)
  45 + add_definitions(-DSYSTEM_ARCH_RTOS)
  46 + add_subdirectory(samples/sample_c/platform/rtos_freertos/stm32f4_discovery/project/armgcc)
  47 +endif ()
  48 +
  49 +add_custom_target(${PROJECT_NAME} ALL)
  1 +END USER LICENSE AGREEMENT
  2 +YOU AGREE TO USE THE SDK SOLELY IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF THIS END USER LICENSE AGREEMENT (THE “AGREEMENT”), AND YOU AGREE THAT YOU ARE BOUND BY AND ARE A PARTY TO THIS AGREEMENT. YOU WARRANT THAT YOU ARE AT LEAST EIGHTEEN YEARS OLD AND THAT YOU HAVE THE LEGAL CAPACITY TO ENTER INTO CONTRACTS. IF YOU ARE AGREEING TO BE BOUND BY THIS AGREEMENT ON BEHALF OF A COMPANY, ORGANIZATION, OR OTHER ENTITY, THEN (i) “YOU” INCLUDES YOU AND THAT COMPANY, ORGANIZATION OR ENTITY, AND (ii) YOU REPRESENT AND WARRANT THAT YOU ARE AN AUTHORIZED REPRESENTATIVE OF SUCH COMPANY, ORGANIZATION OR ENTITY WITH THE AUTHORITY TO BIND SUCH COMPANY, ORGANIZATION OR ENTITY TO THIS AGREEMENT.
  3 +YOUR USE OF THE SDK IS EXPRESSLY CONDITIONED ON YOUR ACCEPTANCE OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT, YOU MAY NOT INSTALL OR USE THE SDK.
  4 + 1. About This Agreement.
  5 + 1.1 Generally. This Agreement applies to the SDK made available by GDU to you.
  6 + 1.2 Additional Terms. Certain additional and/or different terms may apply to certain types of users. If you are a federal, state, or local government entity (including but not limited to any agency or other sub-governmental organization thereof) utilizing the SDK in your official capacity, and to whom GDU has agreed to provide the SDK, then our Government Terms apply to you.
  7 + 2. Definitions
  8 +“Analytics Data” means information collected from a GDU Product (e.g., a GDU UAV) that is used in connection with an Application and/or devices used to operate the GDU Product (e.g., a mobile device). The Analytics Data may include Header Data and/or Event Data. Analytics Data may be used by GDU for any lawful purpose, including without limitation, for research or to improve its SDK or GDU Products.
  9 +“Application” means a software program that is developed by you using the SDK for use with GDU Products.
  10 +“Confidential Information” means the SDK and all other information disclosed to you by GDU that would reasonably be considered to be confidential, or is or was considered by GDU to be confidential, except for information which you can demonstrate: (a) is previously rightfully known to you without restriction on disclosure; (b) is or becomes, from no act or failure to act on your part, generally known in the relevant industry or public domain; (c) is disclosed to you by a third-party as a matter of right and without restriction on disclosure; or (d) is or was independently developed by you without access to, use of, or reference to the Confidential Information.
  11 +“Documentation” means any online read me, help files, technical specifications, or other related explanatory materials that are contained in the SDK or that accompany the SDK.
  12 +“GDU” means SZ GDU TECHNOLOGY CO., LTD. and its affiliates.
  13 +“GDU Products” means GDU hardware, software, and services, such as unmanned aerial vehicles (UAVs), flight controllers, sensors, s, gimbals, remote controllers, accessories, etc.
  14 +“Event Data” means information about time of operation or events, session identification numbers, event types, and flight operation information, including but not limited to GPS data, navigation, operation, speed, distance, modes, mission, command, altitude, takeoff and landing, payload and other component use, battery levels, etc.
  15 +“Header Data” means information about the software (including but not limited to installation identification, app key, SDK version of an Application) and hardware (including but not limited to product identifiers and names of UAVs, payloads, remote controllers, etc.).
  16 +“Licensee Disclosure” means any information that you may provide to GDU in connection with this Agreement, including, for example, feedback on errors and improvements within or relating to the SDK.
  17 +“Privacy Policy” means GDU’s privacy policy located at https://developer.gdu.com/policies/privacy/.
  18 +“SDK” or “Software Development Kit” means software (source code and object code), applications, tools, sample code, templates, fonts, logos, icons, images, libraries, interfaces, Updates, Documentation, application programming interfaces (APIs), information, data, files, and other materials, whether tangible or intangible, in whatever form or medium provided to you by GDU for use by you in connection with your Application. For the purpose of this Agreement, SDK includes, without limitation, (a) the GDU “Guidance” software development kit (https://developer.gdu.com/guidance-sdk/), (b) the GDU “Mobile” software development kit (https://developer.gdu.com/mobile-sdk/), (c) the GDU “Payload” software development kit (https://developer.gdu.com/payload-sdk/, and/or (d) the GDU “Onboard” software development kit (https://developer.gdu.com/onboard-sdk/).
  19 +“Open-Source Component” means software, interfaces and firmware subject to an open-source software license, which means any software license approved as open-source licenses by the Open Source Initiative or any substantially similar licenses, including without limitation any license that, as a condition of distribution of the software licensed under such license, requires that the distributor make the software available in source code format.
  20 +“Third-Party Component” means software, interfaces and firmware licensed by GDU from a third-party (e.g., a supplier of GDU) for incorporation into the SDK and distributed as an integral part of the SDK, as applicable. Third-Party Components may include Open-Source Components.
  21 +“Updates” means bug fixes, service packs, hot fixes, updates, upgrades, enhancements, modifications, and new releases of versions of the SDK.
  22 +“Warranty Logs” means information provided to and/or received by the SDK that is necessary for determining warranty eligibility and product reliability, including without limitation SDK function calls (including without limitation time, function name, results/feedback, etc.), protocol or commands sent from or to a mobile device, an Application, and/or a remote controller (including without limitation time, name, type, command/action, etc.).
  23 +
  24 + 3. License.
  25 + 3.1 License Grants. The SDK is licensed, not sold, to you by GDU and/or, if applicable, its suppliers and licensors. Subject to the terms and conditions of this Agreement, you are hereby granted a limited, worldwide, non-exclusive, non-sublicensable, and nontransferable right to use the SDK solely in the manner described in the Documentation and solely to develop, test, and operate Applications in connection with GDU products.
  26 + 3.2 Use Restrictions. You may not use the SDK except as permitted in this Agreement and any additional terms and conditions that GDU provides pursuant to Section 3.1. Except with GDU’s prior written consent or otherwise provided herein, you may not: (a) alter, modify or create any derivative works of the SDK, including the underlying source code, or the Documentation in any way, including without limitation customization, translation or localization; (b) port, reverse compile, reverse assemble, reverse engineer, or otherwise attempt to separate any of the components of the SDK or derive the source code for the SDK (except to the extent applicable laws specifically prohibit such restriction); (c) copy, redistribute, encumber, sell, rent, lease, sublicense, or otherwise transfer rights to the SDK; (d) remove or alter any trademark, logo, copyright or other proprietary notices, legends, symbols or labels in the SDK; (e) block, disable, or otherwise affect any advertising, advertisement banner window, links to other sites and services, or other features that constitute an integral part of the SDK; or (f) use any part of the SDK to develop applications for use with hardware devices that are not GDU Products, unless they are the devices running the applications or are devices connected (directly or indirectly) to GDU Product(s) the SDK interfaces with. You may not release the results of any performance or functional evaluation of any of the SDK to any third-party without prior written approval of GDU for each such release. You may not cause or permit any third-party to do any of the foregoing.
  27 + 3.3 Distribution of Object Code. You may distribute your Application with object code of the SDK, provided that you must: (1) distribute such object code of the SDK in execution form only; (2) distribute such code only as a part of your Applications; (3) not distribute any portion of the SDK that is not object code, including but not limited to source code, header files and Documentation; (4) not charge a separate price or fee for the object code of the SDK that is distinct from the fee you charge for your Application; (5) not distribute, link, or integrate the object code of the SDK such that any part of the object code of the SDK becomes subject to an open source license; and (6) include the following copyright notice within your Application’s source code in the same locations as your own copyright notice: “Portions copyright (c) 2014–Present GDU. All rights reserved.”. To the extent that any source code is provided to you as part of the SDK, you may use, modify and compile the source code solely for the purposes of developing your Applications.
  28 + 3.4 Third-Party Components. You acknowledge that the SDK may contain Third-Party Components. All third-party licensors and suppliers retain all right, title and interest in and to such Third-Party Components and all copies thereof, including all copyright and other intellectual property rights. Your use of any Third-Party Components shall be subject to, and you shall comply with, the terms and conditions of this Agreement, and the applicable restrictions and other terms and conditions set forth in any Third-Party Components documentation or printed materials, including without limitation an end user license agreement.
  29 + 3.5 Open-Source Components. The SDK may include Open-Source Components that are subject to open-source software licenses. The Documentation accompanying the SDK includes copies of the licenses applicable to the Open-Source Components. To the extent there is conflict between the license terms covering the Open-Source Components and this Agreement, the terms of such licenses will apply in lieu of the terms of this Agreement. To the extent the terms of the licenses applicable to Open-Source Components prohibit any of the restrictions in this Agreement with respect to such Open-Source Component, such restrictions will not apply to such Open-Source Component.
  30 + 4. Reservation of Rights. GDU and its licensors reserve all rights, including but not limited to ownership and intellectual property rights, including in the SDK, not expressly granted to you. GDU’s licensors are the intended third-party beneficiaries of this Agreement and have the express right to rely upon and directly enforce the terms set forth herein. There are no implied licenses granted by GDU under this Agreement. Except as specified above, you shall have no rights to the SDK. You acknowledge and agree that the form and nature of the SDK that GDU provides may change without prior notice to you and that future versions of the SDK may be incompatible with Applications developed on previous versions of the SDK. You acknowledge and agree that GDU may stop providing the SDK or any features of the SDK permanently or temporarily to you or users generally at GDU’s sole discretion, without prior notice to you. If the SDK is a “beta” release, you acknowledge and agree that the SDK is a “beta” release for evaluation purposes only and may contain bugs, defects and errors and that the SDK may fail, return inaccurate results, and/or be subject to other malfunctions.
  31 + 5. Your Applications and Use of the SDK.
  32 + 5.1 Rights in Your Applications. Subject to Section 4 above, GDU agrees that it obtains no right, title, or interest from you (or your licensors) under this Agreement in or to any Applications that you develop using the SDK, including any sole and separate intellectual property rights of yours that subsist in those Applications.
  33 + 5.2 Permitted Applications. You agree to use the SDK and develop Applications solely for purposes that are permitted by: (a) this Agreement; (b) the GDU Developer Policy available at https://developer.gdu.com/policies/developer/; and (c) any applicable law, rule, regulation, or generally accepted practice or guideline in the relevant jurisdiction, including but not limited to laws, rules, or regulations regarding the export of data or software to and from the United States or other relevant countries, and national, public, and personal security.
  34 + 5.3 Your Responsibilities. You agree that you are solely responsible for, and that GDU has no responsibility to you or any third-party for, or access to: (a) any data, content, or resources that you create, transmit, or display through the Applications you develop on or with the SDK (whether originating with you or a third-party), and for the consequences of your actions (including any loss or damage suffered by GDU) by doing so; and (b) any breach of your obligations under this Agreement, any applicable third-party contract or terms of service, or any applicable law, rule, or regulation, and for the consequences (including any loss or damage suffered by GDU) of any such breach.
  35 + 5.4 Compliance with Law; Safety. For the avoidance of doubt, you agree that you shall at all times strictly comply with all applicable laws, rules and regulations and shall not threaten the safety of national security, public security, or the health, privacy, or safety of any person.
  36 + 6. Privacy and Automatically Collected Information.
  37 + 6.1 SDK Use and User Information. In order to continually improve the SDK, GDU may automatically collect certain usage statistics including, but not limited to, unique identifiers, associated IP address, and other information on which tools and services in the SDK are being used and how they are being used. This data is collected in the aggregate to improve the SDK and is maintained in accordance with GDU’s Privacy Policy. We may also collect certain personal information from you, including but not limited to your legal name, mailing address, phone number, email address, and other contact or personal information. We may also collect additional information in order to verify your identity or provide certain functions. This information will be maintained in accordance with GDU’s Privacy Policy, and you hereby agree that we may share this information with our third-party business partners for purposes of verifying your identity or provide certain functions and as otherwise permitted by our Privacy Policy.
  38 + 6.2 Application User Information. The SDK may automatically collect Analytics Data, such as Header Data and/or Event Data. The Analytics Data may be provided to GDU and used by GDU for any use in research or improving its SDK or GDU Products. The Analytics Data may be used by GDU for any lawful purpose, including without limitation, for research or to improve its SDK or GDU Products. Certain SDK (e.g., Mobile SDK) may also automatically collect Warranty Log information, for example, for the purpose of determining warranty eligibility and product reliability. The Warranty Logs are stored locally on a device running the Application (e.g., mobile device) and are not automatically transmitted to GDU without prior user consent. You may be required to make the Warranty Logs available to GDU to support any warranty claims regarding the SDK. By using the SDK and creating an Application, you represent and warrant that you will provide clear and conspicuous notice to each user of the Application of the automatic collection, storage, and GDU’s use of the Analytics Data and Warranty Logs, and that you will obtain any legally-required consents for GDU to receive and use the Analytics Data and Warranty Logs for the purposes specified herein. The Application User Information is maintained in accordance with GDU’s Privacy Policy located at https://developer.gdu.com/policies/privacy/.
  39 + 7. Proprietary Rights. You acknowledge and agree that the SDK belongs to GDU or its licensors. You agree that you neither own nor hereby acquire any claim or right of ownership to the SDK or to any related patents, copyrights, trademarks, or other intellectual property. GDU and its licensors retain all right, title, and interest in and to all copies of the SDK at all times, regardless of the form or media in or on which the original or other copies may subsequently exist. This license is not a sale of the original or any subsequent copy. The SDK is protected by copyright and other intellectual property laws and by international treaties. You may not make any copies of the SDK except as otherwise permitted by this Agreement. Any and all other copies of the SDK made by you are in violation of this license. All content accessed through the SDK is the property of the applicable content owner and may be protected by applicable copyright law. This license gives you no rights to such content. All trademarks used in connection with the SDK are owned by GDU, its affiliates and/or its licensors and other suppliers, and no license to use any such trademarks is provided hereunder.
  40 + 8. Information Submitted to GDU Not Deemed Confidential. GDU works with many application developers and some of their products may be similar to or compete with Your Applications. GDU may also be developing its own similar or competing applications, or may decide to do so in the future. To avoid potential misunderstandings, GDU CANNOT AGREE, AND EXPRESSLY DISCLAIMS, ANY CONFIDENTIALITY OBLIGATIONS OR USE RESTRICTIONS, EXPRESS OR IMPLIED, WITH RESPECT TO ANY LICENSEE DISCLOSURE. Such licensee disclosure may include, for example, feedback on errors and improvements within or relating to the SDK. You agree any such licensee disclosure will be non-confidential. GDU will be free to use and disclose any licensee disclosure on an unrestricted basis without notifying or compensating you. You release GDU from all liability and obligations that may arise from the receipt, review, use, or disclosure of any portion of any licensee disclosure. Any physical materials you submit to GDU will become GDU property and GDU will have no obligation to return those materials to you or to certify their destruction.
  41 + 9. No Support. This Agreement does not entitle you to receive from GDU or its licensors hard-copy documentation, support, telephone assistance, or enhancements or updates to the SDK.
  42 + 10. Term and Termination. This Agreement and your right to use the SDK may be terminated by you or by GDU at any time upon written notice. This Agreement automatically terminates if you fail to comply with its terms and conditions. Immediately upon termination, you shall return or destroy all copies of the SDK in your possession, custody, or control and, if requested by GDU, you shall certify to GDU in writing that such return or destruction has occurred. The following Sections of this Agreement survive any expiration or termination hereof: 1, 2, 3.2, 3.3, 3.4, 3.5, and 4 through 18 (inclusive).
  43 + 11. No warranty. YOU AGREE THAT THE SDK IS PROVIDED “AS IS” AND THAT GDU AND ITS LICENSORS MAKE NO OTHER WARRANTY AS TO THE SDK, INCLUDING, BUT NOT LIMITED TO, UNINTERRUPTED USE, ACCURACY, AND DATA LOSS. GDU AND ITS LICENSORS DISCLAIM ALL OTHER WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, PRIVACY, SECURITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE (EVEN IF GDU KNOWS OR SHOULD HAVE KNOWN OF SUCH PURPOSE), RELATED TO THE SDK, ITS USE OR ANY INABILITY TO USE IT, THE RESULTS OF ITS USE AND THIS AGREEMENT. GDU AND ITS LICENSORS DO NOT WARRANT THAT THE SDK OR ANY RESULTS OF USE THEREOF WILL BE FREE OF DEFECTS, ERRORS OR VIRUSES, RELIABLE OR ABLE TO OPERATE ON AN UNINTERRUPTED BASIS OR IN A PARTICULAR ENVIRONMENT OR THAT ERRORS THEREIN, IF ANY, WILL BE CORRECTED.
  44 + 12. Limitation of Liability. TO THE FULLEST EXTENT PERMITTED BY LAW, GDU AND ITS AFFILIATES AND LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES, WHETHER IN CONTRACT OR TORT (INCLUDING NEGLIGENCE) OR ANY OTHER LEGAL OR EQUITABLE THEORY, ARISING FROM THIS AGREEMENT AND/OR YOUR USE OF THE SDK OR DEVELOPMENT OR DISTRIBUTION OF ANY APPLICATION, INCLUDING WITHOUT LIMITATION ANY INDIRECT, CONSEQUENTIAL, SPECIAL, EXEMPLARY, INCIDENTAL DAMAGES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. YOU AGREE THAT YOU SHALL HAVE THE SOLE RESPONSIBILITY FOR PROTECTING YOUR DATA, BY PERIODIC BACKUP OR OTHERWISE, USED IN CONNECTION WITH THE SDK. IN ANY CASE, GDU AND ITS AFFILIATES AND LICENSORS’ SOLE LIABILITY AND YOUR EXCLUSIVE REMEDY UNDER ANY PROVISION OF THIS AGREEMENT SHALL BE TO STOP USING THE SDK, WITH THE EXCEPTION OF DEATH OR PERSONAL INJURY CAUSED BY THE SOLE NEGLIGENCE OF GDU, AND SOLELY TO THE EXTENT APPLICABLE LAW PROHIBITS THE LIMITATION OF DAMAGES IN SUCH CASES.
  45 + 13. Indemnification. TO THE MAXIMUM EXTENT PERMITTED BY LAW, YOU AGREE TO DEFEND, INDEMNIFY, AND HOLD HARMLESS GDU, ITS AFFILIATES AND THEIR RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, AND AGENTS FROM AND AGAINST ANY AND ALL CLAIMS, ACTIONS, SUITS, OR PROCEEDINGS, AS WELL AS ANY AND ALL LOSSES, LIABILITIES, DAMAGES, COSTS, AND EXPENSES (INCLUDING REASONABLE ATTORNEYS’ FEES) ARISING OUT OF OR ACCRUING FROM: (A) YOUR USE OF THE SDK, INCLUDING THIRD-PARTY SOFTWARE AND/OR DOCUMENTATION; (B) ANY APPLICATION YOU DEVELOP ON OR WITH THE SDK THAT IS ALLEGED TO OR DETERMINED TO INFRINGE ANY PATENT, COPYRIGHT, TRADEMARK, OR OTHER INTELLECTUAL PROPERTY OR PROPRIETARY RIGHT OF A THIRD PARTY; AND (C) YOUR NONCOMPLIANCE WITH ANY TERM OF THIS AGREEMENT, EXCEPT FOR DEATH OR PERSONAL INJURY CAUSED BY THE SOLE NEGLIGENCE OF GDU.
  46 + 14. Confidentiality. You shall use your best efforts to preserve and protect the confidentiality of the Confidential Information at all times, both during the term hereof and for a period of at least 3 years after termination of this Agreement, provided, however, that any source code you receive shall be held in confidence in perpetuity. You shall not disclose, disseminate, or otherwise publish or communicate Confidential Information to any person, firm, corporation or other third-party without the prior written consent of GDU. You shall not use any Confidential Information other than in the course of the activities permitted hereunder. You agree to use your best efforts to prevent and protect the contents of the SDK from unauthorized disclosure or use. You shall notify GDU in writing immediately upon discovery of any unauthorized use or disclosure of Confidential Information or any other breach of this Agreement, and will cooperate with GDU in every reasonable way to regain possession of Confidential Information and prevent any further unauthorized use.
  47 +If you are legally compelled to disclose any of the Confidential Information, then, prior to such disclosure, you will (i) immediately notify GDU prior to such disclosure to allow GDU an opportunity to contest the disclosure, (ii) assert the privileged and confidential nature of the Confidential Information, and (iii) cooperate fully with GDU in protecting against any such disclosure and/or obtaining a protective order narrowing the scope of such disclosure and/or use of the Confidential Information. In the event such protection is not obtained, you shall disclose the Confidential Information only to the extent necessary to comply with the applicable legal requirements.
  48 + 15. Injunctive Relief. You acknowledge and agree that your breach or threatened breach of this Agreement shall cause GDU irreparable damage for which recovery of money damages would be inadequate and that GDU therefore may obtain timely injunctive relief to protect its rights under this Agreement in addition to any and all other remedies available at law or in equity.
  49 + 16. Export Controls. The SDK and the underlying information and technology may not be downloaded or otherwise exported or re-exported (a) into (or to a national or resident of) any country to which the U.S. has embargoed goods; or (b) to or through or involve any party on any U.S. government screening or prohibited list (including those as updated from time-to-time on the U.S. Consolidated Screening List (available at http://export.gov/ecr/eg_main_023148.asp). By downloading or using the SDK and/or Documentation, you are agreeing to the foregoing and you represent and warrant that you are not located in, under the control of, or a national or resident of any such country or on any such list and you agree to comply with all export laws and other applicable laws.
  50 + 17. Miscellaneous. (a) This Agreement, together with any amendments and any additional agreements you may enter into with GDU in connection with the use of SDK, shall constitute the entire agreement between the parties concerning the subject matter hereof, which may only be modified by a written amendment signed by an authorized executive of GDU. (b) Any dispute, controversy, difference or claim arising out of or relating to this contract, including the existence, validity, interpretation, performance, breach or termination thereof or any dispute regarding non-contractual obligations arising out of or relating to it shall be referred to and finally resolved by arbitration administered by the Hong Kong International Arbitration Centre (“HKIAC”) under the HKIAC Administered Arbitration Rules in force when the Notice of Arbitration is submitted. The law of this arbitration clause shall be Hong Kong law, excluding its conflict of law provisions. The seat of arbitration shall be Hong Kong. The number of arbitrators shall be three (3) in accordance with such rules. The arbitration proceedings shall be conducted in English. Any awards of shall be final and binding upon the applicable parties. (c) This Agreement shall not be governed by the United Nations Convention on Contracts for the International Sale of Goods. (d) If any part of this Agreement is held invalid or unenforceable, that part shall be construed to reflect the parties' original intent, and the remaining portions remain in full force and effect, or GDU may at its option terminate this Agreement. (e) The controlling language of this Agreement is English. If you have received a translation into another language, it has been provided for your convenience only. (f) A waiver by either party of any term or condition of this Agreement or any breach thereof, in any one instance, shall not waive such term or condition or any subsequent breach thereof. (g) You may not assign or otherwise transfer by operation of law or otherwise this Agreement or any rights or obligations herein. GDU may assign this Agreement to any entity at its sole discretion. (h) This Agreement shall be binding upon and shall inure to the benefit of the parties, their successors and permitted assigns.
  51 + 18. User Outside the People’s Republic of China. If you are using the SDK outside the People’s Republic of China, then the following shall apply: (a) You confirm that this Agreement and all related documentation is and will be in the English language; (b) you are responsible for complying with any local laws in your jurisdiction which might impact your right to import, export or use the SDK, and you represent that you have complied with any regulations or registration procedures required by applicable law to make this license enforceable.
  52 +
  53 +This End User License Agreement was last modified on December 11, 2017.
  1 +The following portions of the GDU’s Payload SDK (“Software” referred to in the terms below) are made available to you under the terms of the MIT License. A copy of the MIT license is available at https://opensource.org/licenses/MIT.
  2 +
  3 +.
  4 +├── CMakeLists.txt
  5 +├── doc
  6 +│   ├── gdu_sdk_code_style
  7 +│   │   ├── gdu_sdk_template.c
  8 +│   │   └── gdu_sdk_template.h
  9 +│   └── simple_model
  10 +│   ├── M300_OSDK_Adapter.stp
  11 +│   ├── M300_RTK_1.stp
  12 +│   ├── M300_RTK_2.stp
  13 +│   ├── M300_RTK_3.stp
  14 +│   ├── Skyport_Adapter_2.stp
  15 +│   └── X-Port 80mm.stp
  16 +├── EULA.txt
  17 +├── LICENSE.txt
  18 +├── psdk_lib
  19 +│   ├── include
  20 +│   │   ├── gdu_aircraft_info.h
  21 +│   │   ├── gdu__manager.h
  22 +│   │   ├── gdu_core.h
  23 +│   │   ├── gdu_error.h
  24 +│   │   ├── gdu_fc_subscription.h
  25 +│   │   ├── gdu_flight_controller.h
  26 +│   │   ├── gdu_gimbal.h
  27 +│   │   ├── gdu_gimbal_manager.h
  28 +│   │   ├── gdu_high_speed_data_channel.h
  29 +│   │   ├── gdu_hms.h
  30 +│   │   ├── gdu_hms_info_table.h
  31 +│   │   ├── gdu_liveview.h
  32 +│   │   ├── gdu_logger.h
  33 +│   │   ├── gdu_low_speed_data_channel.h
  34 +│   │   ├── gdu_mop_channel.h
  35 +│   │   ├── gdu_payload_.h
  36 +│   │   ├── gdu_perception.h
  37 +│   │   ├── gdu_platform.h
  38 +│   │   ├── gdu_positioning.h
  39 +│   │   ├── gdu_power_management.h
  40 +│   │   ├── gdu_time_sync.h
  41 +│   │   ├── gdu_typedef.h
  42 +│   │   ├── gdu_upgrade.h
  43 +│   │   ├── gdu_version.h
  44 +│   │   ├── gdu_waypoint_v2.h
  45 +│   │   ├── gdu_waypoint_v2_type.h
  46 +│   │   ├── gdu_widget.h
  47 +│   │   ├── gdu_xport.h
  48 +│   │   └── legacy_psdk2.x
  49 +│   │   ├── psdk_aircraft_info.h
  50 +│   │   ├── psdk_core.h
  51 +│   │   ├── psdk_data_channel.h
  52 +│   │   ├── psdk_data_subscription.h
  53 +│   │   ├── psdk_data_transmission.h
  54 +│   │   ├── psdk_error.h
  55 +│   │   ├── psdk_gimbal.h
  56 +│   │   ├── psdk_logger.h
  57 +│   │   ├── psdk_mop_channel.h
  58 +│   │   ├── psdk_payload_.h
  59 +│   │   ├── psdk_payload_collaboration.h
  60 +│   │   ├── psdk_platform.h
  61 +│   │   ├── psdk_positioning.h
  62 +│   │   ├── psdk_power_management.h
  63 +│   │   ├── psdk_product_info.h
  64 +│   │   ├── psdk_time_sync.h
  65 +│   │   ├── psdk_typedef.h
  66 +│   │   ├── psdk_upgrade.h
  67 +│   │   ├── psdk_version.h
  68 +│   │   ├── psdk_widget.h
  69 +│   │   └── psdk_xport.h
  70 +│   └── lib
  71 +│   ├── aarch64-himix100-linux-gcc
  72 +│   │   └── libpayloadsdk.a
  73 +│   ├── aarch64-linux-android-gcc
  74 +│   │   └── libpayloadsdk.a
  75 +│   ├── aarch64-linux-gnu-gcc
  76 +│   │   └── libpayloadsdk.a
  77 +│   ├── armcc_cortex-m4
  78 +│   │   └── libpayloadsdk.lib
  79 +│   ├── arm-himix100-linux-gcc
  80 +│   │   └── libpayloadsdk.a
  81 +│   ├── arm-himix200-linux-gcc
  82 +│   │   └── libpayloadsdk.a
  83 +│   ├── arm-hisiv300-linux-gcc
  84 +│   │   └── libpayloadsdk.a
  85 +│   ├── arm-hisiv400-linux-gcc
  86 +│   │   └── libpayloadsdk.a
  87 +│   ├── arm-hisiv500-linux-gcc
  88 +│   │   └── libpayloadsdk.a
  89 +│   ├── arm-hisiv600-linux-gcc
  90 +│   │   └── libpayloadsdk.a
  91 +│   ├── arm-linux-androideabi-gcc
  92 +│   │   └── libpayloadsdk.a
  93 +│   ├── arm-linux-gnueabi-gcc
  94 +│   │   └── libpayloadsdk.a
  95 +│   ├── arm-linux-gnueabihf-gcc
  96 +│   │   └── libpayloadsdk.a
  97 +│   ├── arm-none-eabi-gcc
  98 +│   │   └── libpayloadsdk.a
  99 +│   └── x86_64-linux-gnu-gcc
  100 +│   └── libpayloadsdk.a
  101 +├── README.md
  102 +├── samples
  103 +│   ├── sample_c
  104 +│   │   ├── module_sample
  105 +│   │   │   ├── _emu
  106 +│   │   │   │   ├── gdu_media_file_manage
  107 +│   │   │   │   │   ├── gdu_media_file_core.c
  108 +│   │   │   │   │   ├── gdu_media_file_core.h
  109 +│   │   │   │   │   ├── gdu_media_file_jpg.c
  110 +│   │   │   │   │   ├── gdu_media_file_jpg.h
  111 +│   │   │   │   │   ├── gdu_media_file_mp4.c
  112 +│   │   │   │   │   └── gdu_media_file_mp4.h
  113 +│   │   │   │   ├── media_file
  114 +│   │   │   │   │   ├── out.h264
  115 +│   │   │   │   │   ├── PSDK_0001_ORG.jpg
  116 +│   │   │   │   │   ├── PSDK_0002_ORG.jpg
  117 +│   │   │   │   │   ├── PSDK_0003_ORG.jpg
  118 +│   │   │   │   │   ├── PSDK_0004_ORG.mp4
  119 +│   │   │   │   │   └── PSDK_0005.h264
  120 +│   │   │   │   ├── test_payload_cam_emu_base.c
  121 +│   │   │   │   ├── test_payload_cam_emu_base.h
  122 +│   │   │   │   ├── test_payload_cam_emu_media.c
  123 +│   │   │   │   └── test_payload_cam_emu_media.h
  124 +│   │   │   ├── _manager
  125 +│   │   │   │   ├── test__manager.c
  126 +│   │   │   │   └── test__manager.h
  127 +│   │   │   ├── data_transmission
  128 +│   │   │   │   ├── test_data_transmission.c
  129 +│   │   │   │   └── test_data_transmission.h
  130 +│   │   │   ├── fc_subscription
  131 +│   │   │   │   ├── test_fc_subscription.c
  132 +│   │   │   │   └── test_fc_subscription.h
  133 +│   │   │   ├── flight_control
  134 +│   │   │   │   ├── test_flight_control.c
  135 +│   │   │   │   └── test_flight_control.h
  136 +│   │   │   ├── gimbal_emu
  137 +│   │   │   │   ├── test_payload_gimbal_emu.c
  138 +│   │   │   │   └── test_payload_gimbal_emu.h
  139 +│   │   │   ├── gimbal_manager
  140 +│   │   │   │   ├── test_gimbal_manager.c
  141 +│   │   │   │   └── test_gimbal_manager.h
  142 +│   │   │   ├── hms
  143 +│   │   │   │   ├── test_hms.c
  144 +│   │   │   │   └── test_hms.h
  145 +│   │   │   ├── liveview
  146 +│   │   │   │   ├── test_liveview.c
  147 +│   │   │   │   └── test_liveview.h
  148 +│   │   │   ├── mop_channel
  149 +│   │   │   │   ├── mop_channel_test_file
  150 +│   │   │   │   │   └── mop_send_test_file.mp4
  151 +│   │   │   │   ├── test_mop_channel.c
  152 +│   │   │   │   └── test_mop_channel.h
  153 +│   │   │   ├── payload_collaboration
  154 +│   │   │   │   ├── test_payload_collaboration.c
  155 +│   │   │   │   └── test_payload_collaboration.h
  156 +│   │   │   ├── perception
  157 +│   │   │   │   ├── test_perception.c
  158 +│   │   │   │   └── test_perception.h
  159 +│   │   │   ├── positioning
  160 +│   │   │   │   ├── test_positioning.c
  161 +│   │   │   │   └── test_positioning.h
  162 +│   │   │   ├── power_management
  163 +│   │   │   │   ├── test_power_management.c
  164 +│   │   │   │   └── test_power_management.h
  165 +│   │   │   ├── time_sync
  166 +│   │   │   │   ├── test_time_sync.c
  167 +│   │   │   │   └── test_time_sync.h
  168 +│   │   │   ├── upgrade
  169 +│   │   │   │   ├── test_upgrade.c
  170 +│   │   │   │   ├── test_upgrade_common_file_transfer.c
  171 +│   │   │   │   ├── test_upgrade_common_file_transfer.h
  172 +│   │   │   │   ├── test_upgrade.h
  173 +│   │   │   │   ├── test_upgrade_platform_opt.c
  174 +│   │   │   │   └── test_upgrade_platform_opt.h
  175 +│   │   │   ├── utils
  176 +│   │   │   │   ├── util_buffer.c
  177 +│   │   │   │   ├── util_buffer.h
  178 +│   │   │   │   ├── util_file.c
  179 +│   │   │   │   ├── util_file.h
  180 +│   │   │   │   ├── util_md5.c
  181 +│   │   │   │   ├── util_md5.h
  182 +│   │   │   │   ├── util_misc.c
  183 +│   │   │   │   ├── util_misc.h
  184 +│   │   │   │   ├── util_time.c
  185 +│   │   │   │   └── util_time.h
  186 +│   │   │   ├── waypoint_v2
  187 +│   │   │   │   ├── test_waypoint_v2.c
  188 +│   │   │   │   └── test_waypoint_v2.h
  189 +│   │   │   ├── widget
  190 +│   │   │   │   ├── file_binary_array_list_en.c
  191 +│   │   │   │   ├── file_binary_array_list_en.h
  192 +│   │   │   │   ├── test_widget.c
  193 +│   │   │   │   ├── test_widget.h
  194 +│   │   │   │   ├── widget_file
  195 +│   │   │   │   │   ├── cn_big_screen
  196 +│   │   │   │   │   │   ├── icon_button1.png
  197 +│   │   │   │   │   │   ├── icon_button2.png
  198 +│   │   │   │   │   │   ├── icon_list_item1.png
  199 +│   │   │   │   │   │   ├── icon_list_item2.png
  200 +│   │   │   │   │   │   ├── icon_scale.png
  201 +│   │   │   │   │   │   ├── icon_switch_select.png
  202 +│   │   │   │   │   │   ├── icon_switch_unselect.png
  203 +│   │   │   │   │   │   └── widget_config.json
  204 +│   │   │   │   │   └── en_big_screen
  205 +│   │   │   │   │   ├── icon_button1.png
  206 +│   │   │   │   │   ├── icon_button2.png
  207 +│   │   │   │   │   ├── icon_list_item1.png
  208 +│   │   │   │   │   ├── icon_list_item2.png
  209 +│   │   │   │   │   ├── icon_scale.png
  210 +│   │   │   │   │   ├── icon_switch_select.png
  211 +│   │   │   │   │   ├── icon_switch_unselect.png
  212 +│   │   │   │   │   └── widget_config.json
  213 +│   │   │   │   └── widget_file_c
  214 +│   │   │   │   └── en_big_screen
  215 +│   │   │   │   ├── icon_button1_png.h
  216 +│   │   │   │   ├── icon_button2_png.h
  217 +│   │   │   │   ├── icon_list_item1_png.h
  218 +│   │   │   │   ├── icon_list_item2_png.h
  219 +│   │   │   │   ├── icon_scale_png.h
  220 +│   │   │   │   ├── icon_switch_select_png.h
  221 +│   │   │   │   ├── icon_switch_unselect_png.h
  222 +│   │   │   │   └── widget_config_json.h
  223 +│   │   │   ├── widget_interaction_test
  224 +│   │   │   │   ├── file_binary_array_list_en.c
  225 +│   │   │   │   ├── file_binary_array_list_en.h
  226 +│   │   │   │   ├── test_widget_interaction.c
  227 +│   │   │   │   ├── test_widget_interaction.h
  228 +│   │   │   │   ├── widget_file
  229 +│   │   │   │   │   ├── cn_big_screen
  230 +│   │   │   │   │   │   ├── icon_button1.png
  231 +│   │   │   │   │   │   ├── icon_button2.png
  232 +│   │   │   │   │   │   ├── icon_list_item1.png
  233 +│   │   │   │   │   │   ├── icon_list_item2.png
  234 +│   │   │   │   │   │   ├── icon_scale.png
  235 +│   │   │   │   │   │   ├── icon_switch_select.png
  236 +│   │   │   │   │   │   ├── icon_switch_unselect.png
  237 +│   │   │   │   │   │   └── widget_config.json
  238 +│   │   │   │   │   └── en_big_screen
  239 +│   │   │   │   │   ├── icon_button1.png
  240 +│   │   │   │   │   ├── icon_button2.png
  241 +│   │   │   │   │   ├── icon_list_item1.png
  242 +│   │   │   │   │   ├── icon_list_item2.png
  243 +│   │   │   │   │   ├── icon_scale.png
  244 +│   │   │   │   │   ├── icon_switch_select.png
  245 +│   │   │   │   │   ├── icon_switch_unselect.png
  246 +│   │   │   │   │   └── widget_config.json
  247 +│   │   │   │   └── widget_file_c
  248 +│   │   │   │   └── en_big_screen
  249 +│   │   │   │   ├── icon_button1_png.h
  250 +│   │   │   │   ├── icon_button2_png.h
  251 +│   │   │   │   ├── icon_list_item1_png.h
  252 +│   │   │   │   ├── icon_list_item2_png.h
  253 +│   │   │   │   ├── icon_scale_png.h
  254 +│   │   │   │   ├── icon_switch_select_png.h
  255 +│   │   │   │   ├── icon_switch_unselect_png.h
  256 +│   │   │   │   └── widget_config_json.h
  257 +│   │   │   └── xport
  258 +│   │   │   ├── test_payload_xport.c
  259 +│   │   │   └── test_payload_xport.h
  260 +│   │   └── platform
  261 +│   │   ├── linux
  262 +│   │   │   ├── common
  263 +│   │   │   │   ├── 3rdparty
  264 +│   │   │   │   │   └── ffmpeg
  265 +│   │   │   │   │   └── FindFFMPEG.cmake
  266 +│   │   │   │   ├── monitor
  267 +│   │   │   │   │   ├── sys_monitor.c
  268 +│   │   │   │   │   └── sys_monitor.h
  269 +│   │   │   │   ├── osal
  270 +│   │   │   │   │   ├── osal.c
  271 +│   │   │   │   │   ├── osal_fs.c
  272 +│   │   │   │   │   ├── osal_fs.h
  273 +│   │   │   │   │   ├── osal.h
  274 +│   │   │   │   │   ├── osal_socket.c
  275 +│   │   │   │   │   └── osal_socket.h
  276 +│   │   │   │   └── upgrade_platform_opt
  277 +│   │   │   │   ├── upgrade_platform_opt_linux.c
  278 +│   │   │   │   └── upgrade_platform_opt_linux.h
  279 +│   │   │   └── manifold2
  280 +│   │   │   ├── application
  281 +│   │   │   │   ├── gdu_sdk_app_info.h
  282 +│   │   │   │   ├── gdu_sdk_config.h
  283 +│   │   │   │   └── main.c
  284 +│   │   │   ├── CMakeLists.txt
  285 +│   │   │   └── hal
  286 +│   │   │   ├── hal_network.c
  287 +│   │   │   ├── hal_network.h
  288 +│   │   │   ├── hal_uart.c
  289 +│   │   │   ├── hal_uart.h
  290 +│   │   │   ├── hal_usb_bulk.c
  291 +│   │   │   └── hal_usb_bulk.h
  292 +│   │   └── rtos_freertos
  293 +│   │   ├── common
  294 +│   │   │   └── osal
  295 +│   │   │   ├── osal.c
  296 +│   │   │   └── osal.h
  297 +│   │   └── stm32f4_discovery
  298 +│   │   ├── application
  299 +│   │   │   ├── application.c
  300 +│   │   │   ├── application.h
  301 +│   │   │   ├── gdu_sdk_app_info.h
  302 +│   │   │   ├── gdu_sdk_config.h
  303 +│   │   │   ├── FreeRTOSConfig.h
  304 +│   │   │   └── main.c
  305 +│   │   ├── drivers
  306 +│   │   │   ├── BSP
  307 +│   │   │   │   ├── apply_high_power.c
  308 +│   │   │   │   ├── apply_high_power.h
  309 +│   │   │   │   ├── gdu_ringbuffer.c
  310 +│   │   │   │   ├── gdu_ringbuffer.h
  311 +│   │   │   │   ├── freertos.c
  312 +│   │   │   │   ├── led.c
  313 +│   │   │   │   ├── led.h
  314 +│   │   │   │   ├── pps.c
  315 +│   │   │   │   ├── pps.h
  316 +│   │   │   │   ├── startup_stm32f407vgtx.s
  317 +│   │   │   │   ├── stm32f4xx_hal_conf.h
  318 +│   │   │   │   ├── stm32f4xx_hal_msp.c
  319 +│   │   │   │   ├── stm32f4xx_hal_timebase_tim.c
  320 +│   │   │   │   ├── stm32f4xx_it.c
  321 +│   │   │   │   ├── stm32f4xx_it.h
  322 +│   │   │   │   ├── syscalls.c
  323 +│   │   │   │   ├── sysmem.c
  324 +│   │   │   │   ├── system_stm32f4xx.c
  325 +│   │   │   │   ├── uart.c
  326 +│   │   │   │   └── uart.h
  327 +│   │   │   ├── CMSIS
  328 +│   │   │   │   ├── Device
  329 +│   │   │   │   │   └── ST
  330 +│   │   │   │   │   └── STM32F4xx
  331 +│   │   │   │   │   ├── Include
  332 +│   │   │   │   │   └── Source
  333 +│   │   │   │   └── Include
  334 +│   │   │   ├── STM32F4xx_HAL_Driver
  335 +│   │   │   │   ├── Inc
  336 +│   │   │   │   └── Src
  337 +│   │   │   └── USB_HOST
  338 +│   │   │   ├── App
  339 +│   │   │   │   ├── usb_host.c
  340 +│   │   │   │   └── usb_host.h
  341 +│   │   │   └── Target
  342 +│   │   │   ├── usbh_conf.c
  343 +│   │   │   └── usbh_conf.h
  344 +│   │   ├── hal
  345 +│   │   │   ├── hal_uart.c
  346 +│   │   │   └── hal_uart.h
  347 +│   │   ├── middlewares
  348 +│   │   │   ├── ST
  349 +│   │   │   │   └── STM32_USB_Host_Library
  350 +│   │   │   │   ├── Class
  351 +│   │   │   │   │   └── CDC
  352 +│   │   │   │   │   ├── Inc
  353 +│   │   │   │   │   │   └── usbh_cdc.h
  354 +│   │   │   │   │   └── Src
  355 +│   │   │   │   │   └── usbh_cdc.c
  356 +│   │   │   │   └── Core
  357 +│   │   │   │   ├── Inc
  358 +│   │   │   │   │   ├── usbh_core.h
  359 +│   │   │   │   │   ├── usbh_ctlreq.h
  360 +│   │   │   │   │   ├── usbh_def.h
  361 +│   │   │   │   │   ├── usbh_ioreq.h
  362 +│   │   │   │   │   └── usbh_pipes.h
  363 +│   │   │   │   └── Src
  364 +│   │   │   │   ├── usbh_core.c
  365 +│   │   │   │   ├── usbh_ctlreq.c
  366 +│   │   │   │   ├── usbh_ioreq.c
  367 +│   │   │   │   └── usbh_pipes.c
  368 +│   │   │   └── Third_Party
  369 +│   │   │   └── FreeRTOS
  370 +│   │   │   └── Source
  371 +│   │   │   ├── CMSIS_RTOS
  372 +│   │   │   ├── croutine.c
  373 +│   │   │   ├── event_groups.c
  374 +│   │   │   ├── include
  375 +│   │   │   ├── list.c
  376 +│   │   │   ├── portable
  377 +│   │   │   ├── queue.c
  378 +│   │   │   ├── stream_buffer.c
  379 +│   │   │   ├── tasks.c
  380 +│   │   │   └── timers.c
  381 +│   │   └── project
  382 +│   │   ├── clion_app
  383 +│   │   │   ├── CMakeLists.txt
  384 +│   │   │   ├── STM32F407VGTX_FLASH.ld
  385 +│   │   │   └── stm32f4discovery.cfg
  386 +│   │   └── mdk_app
  387 +│   │   └── mdk_app.uvprojx
  388 +│   └── sample_c++
  389 +│   ├── module_sample
  390 +│   │   ├── liveview
  391 +│   │   │   ├── data
  392 +│   │   │   │   ├── cars.xml
  393 +│   │   │   │   ├── haarcascade_frontalface_alt.xml
  394 +│   │   │   │   └── tensorflow
  395 +│   │   │   │   ├── frozen_inference_graph.pb
  396 +│   │   │   │   └── ssd_inception_v2_coco_2017_11_17.pbtxt
  397 +│   │   │   ├── gdu__image_handler.cpp
  398 +│   │   │   ├── gdu__image_handler.hpp
  399 +│   │   │   ├── gdu__stream_decoder.cpp
  400 +│   │   │   ├── gdu__stream_decoder.hpp
  401 +│   │   │   ├── test_liveview.cpp
  402 +│   │   │   ├── test_liveview_entry.cpp
  403 +│   │   │   ├── test_liveview_entry.hpp
  404 +│   │   │   └── test_liveview.hpp
  405 +│   │   └── perception
  406 +│   │   ├── test_perception.cpp
  407 +│   │   ├── test_perception_entry.cpp
  408 +│   │   ├── test_perception_entry.hpp
  409 +│   │   └── test_perception.hpp
  410 +│   └── platform
  411 +│   └── linux
  412 +│   ├── common
  413 +│   │   └── osal
  414 +│   │   ├── osal.c
  415 +│   │   └── osal.h
  416 +│   └── manifold2
  417 +│   ├── application
  418 +│   │   ├── application.cpp
  419 +│   │   ├── application.hpp
  420 +│   │   ├── gdu_sdk_app_info.h
  421 +│   │   └── main.cpp
  422 +│   ├── CMakeLists.txt
  423 +│   ├── FindFFMPEG.cmake
  424 +│   └── hal
  425 +│   ├── hal_network.c
  426 +│   ├── hal_network.h
  427 +│   ├── hal_uart.c
  428 +│   ├── hal_uart.h
  429 +│   ├── hal_usb_bulk.c
  430 +│ └── hal_usb_bulk.h
  431 +└── tools
  432 + └── file2c
  433 + ├── file2c.exe
  434 + └── readme.txt
  435 +
  436 +Unless otherwise agreed, all other portions of GDU’s Payload SDK are and will be made available under the SDK End User License Agreement (EULA). A copy of the SDK EULA is distributed with this software and is available at https://developer.gdu.com/policies/eula/.
  437 +-------------------------------------------------------------
  438 +Copyright (c) 2021 GDU.
  439 +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  440 +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  441 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  442 +===============================================================
  443 +GDU’s Payload SDK uses libraries of List and MD5, whose license is as below.
  444 +
  445 +-------------------------------------------------------------
  446 +crypto-algorithms
  447 +=================
  448 +About
  449 +---
  450 +These are basic implementations of standard cryptography algorithms, written by Brad Conte (brad@bradconte.com) from
  451 +scratch and without any cross-licensing. They exist to provide publically accessible, restriction-free implementations
  452 +of popular cryptographic algorithms, like AES and SHA-1. These are primarily intended for educational and pragmatic
  453 +purposes (such as comparing a specification to actual implementation code, or for building an internal application
  454 +that computes test vectors for a product). The algorithms have been tested against standard test vectors.
  455 +This code is released into the public domain free of any restrictions. The author requests acknowledgement if the code
  456 +is used, but does not require it. This code is provided free of any liability and without any quality claims by the
  457 +author.
  458 +Note that these are *not* cryptographically secure implementations. They have no resistence to side-channel attacks
  459 +and should not be used in contexts that need cryptographically secure implementations.
  460 +These algorithms are not optimized for speed or space. They are primarily designed to be easy to read, although some
  461 +basic optimization techniques have been employed.
  462 +Building
  463 +The source code for each algorithm will come in a pair of a source code file and a header file. There should be no
  464 +inter-header file dependencies, no additional libraries, no platform-specific header files, or any other complicating
  465 +matters. Compiling them should be as easy as adding the relevent source code to the project.
  466 +===============================================================
  467 +GDU’s Payload SDK uses libraries of CMSIS (https://developer.arm.com/tools-and-software/embedded/cmsis), which is licensed under the Apache License, Version 2.0. A copy of the Apache license is provided below and is also available at http://www.apache.org/licenses/LICENSE-2.0.
  468 +
  469 +-------------------------------------------------------------
  470 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
  471 +
  472 +1. Definitions.
  473 +
  474 +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
  475 +
  476 +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
  477 +
  478 +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
  479 +
  480 +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
  481 +
  482 +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
  483 +
  484 +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
  485 +
  486 +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
  487 +
  488 +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
  489 +
  490 +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
  491 +
  492 +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
  493 +
  494 +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
  495 +
  496 +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
  497 +
  498 +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
  499 +
  500 +You must give any other recipients of the Work or Derivative Works a copy of this License; and
  501 +You must cause any modified files to carry prominent notices stating that You changed the files; and
  502 +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
  503 +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
  504 +
  505 +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
  506 +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
  507 +
  508 +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
  509 +
  510 +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
  511 +
  512 +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
  513 +
  514 +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
  515 +
  516 +END OF TERMS AND CONDITIONS
  517 +===============================================================
  518 +GDU’s Payload SDK uses unmodified libraries of cJSON, whose license is as below.
  519 +
  520 +-------------------------------------------------------------
  521 + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
  522 +
  523 + Permission is hereby granted, free of charge, to any person obtaining a copy
  524 + of this software and associated documentation files (the "Software"), to deal
  525 + in the Software without restriction, including without limitation the rights
  526 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  527 + copies of the Software, and to permit persons to whom the Software is
  528 + furnished to do so, subject to the following conditions:
  529 +
  530 + The above copyright notice and this permission notice shall be included in
  531 + all copies or substantial portions of the Software.
  532 +
  533 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  534 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  535 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  536 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  537 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  538 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  539 + THE SOFTWARE.
  540 +===============================================================
  541 +GDU’s Payload SDK uses unmodified libraries of freeRTOS (http://www.FreeRTOS.org), which is licensed under the MIT License. Full license text is available on the following link: http://www.freertos.org/a00114.html. A copy of the MIT license is provided below and is also available at https://opensource.org/licenses/MIT.
  542 +
  543 +-------------------------------------------------------------
  544 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  545 +this software and associated documentation files (the "Software"), to deal in
  546 +the Software without restriction, including without limitation the rights to
  547 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  548 +the Software, and to permit persons to whom the Software is furnished to do so,
  549 +subject to the following conditions:
  550 +
  551 +The above copyright notice and this permission notice shall be included in all
  552 +copies or substantial portions of the Software.
  553 +
  554 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  555 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  556 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  557 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  558 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  559 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  560 +
  561 +===============================================================
  562 +GDU’s Payload SDK uses unmodified libraries of STM32F4xx_HAL_Driver, BSP STM324xG_EVAL libraries and STM32 Projects libraries in STM32CubeF4 package, which is licensed by ST under BSD 3-Clause license. A copy of the license is provided below and is also available at opensource.org/licenses/BSD-3-Clause.
  563 +
  564 +-------------------------------------------------------------
  565 +Note: This license has also been called the "New BSD License" or "Modified BSD License". See also the 2-clause BSD License.
  566 +
  567 +Copyright <YEAR> <COPYRIGHT HOLDER>
  568 +
  569 +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  570 +
  571 +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  572 +
  573 +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  574 +
  575 +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  576 +
  577 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1 +{
  2 + "CurrentProjectSetting": "无配置"
  3 +}
  1 +{
  2 + "ExpandedNodes": [
  3 + "",
  4 + "\\sample_c",
  5 + "\\sample_c\\platform",
  6 + "\\sample_c\\platform\\linux",
  7 + "\\sample_c\\platform\\linux\\H3",
  8 + "\\sample_c\\platform\\linux\\H3\\music"
  9 + ],
  10 + "SelectedNode": "\\sample_c\\platform\\linux\\H3\\music\\music.c",
  11 + "PreviewInSolutionExplorer": false
  12 +}
  1 +/**
  2 + ********************************************************************
  3 + * @file test_data_transmission.c
  4 + * @brief
  5 + *
  6 + * @copyright (c) 2021 GDU. All rights reserved.
  7 + *
  8 + * All information contained herein is, and remains, the property of GDU.
  9 + * The intellectual and technical concepts contained herein are proprietary
  10 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  11 + * and protected by trade secret or copyright law. Dissemination of this
  12 + * information, including but not limited to data and other proprietary
  13 + * material(s) incorporated within the information, in any form, is strictly
  14 + * prohibited without the express written consent of GDU.
  15 + *
  16 + * If you receive this source code without GDU’s authorization, you may not
  17 + * further disseminate the information, and you must immediately remove the
  18 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  19 + * legal actions against you for any loss(es) or damage(s) caused by your
  20 + * failure to do so.
  21 + *
  22 + *********************************************************************
  23 + */
  24 +
  25 +
  26 +/* Includes ------------------------------------------------------------------*/
  27 +#include "test_data_transmission.h"
  28 +#include "gdu_logger.h"
  29 +#include "gdu_platform.h"
  30 +#include "utils/util_misc.h"
  31 +#include "gdu_data_transmission.h"
  32 +#include "gdu_aircraft_info.h"
  33 +
  34 +/* Private constants ---------------------------------------------------------*/
  35 +#define DATA_TRANSMISSION_TASK_FREQ (1)
  36 +#define DATA_TRANSMISSION_TASK_STACK_SIZE (2048)
  37 +
  38 +/* Private types -------------------------------------------------------------*/
  39 +
  40 +/* Private functions declaration ---------------------------------------------*/
  41 +static void *UserDataTransmission_Task(void *arg);
  42 +static T_GduReturnCode ReceiveDataFromMobile(const uint8_t *data, uint16_t len);
  43 +static T_GduReturnCode ReceiveDataFromCloud(const uint8_t *data, uint16_t len);
  44 +static T_GduReturnCode ReceiveDataFromExtensionPort(const uint8_t *data, uint16_t len);
  45 +static T_GduReturnCode ReceiveDataFromPayload(const uint8_t *data, uint16_t len);
  46 +
  47 +/* Private variables ---------------------------------------------------------*/
  48 +static T_GduTaskHandle s_userDataTransmissionThread;
  49 +static T_GduAircraftInfoBaseInfo s_aircraftInfoBaseInfo;
  50 +
  51 +/* Exported functions definition ---------------------------------------------*/
  52 +T_GduReturnCode GduTest_DataTransmissionStartService(void)
  53 +{
  54 + T_GduReturnCode gduStat;
  55 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  56 + E_GduChannelAddress channelAddress;
  57 + char ipAddr[GDU_IP_ADDR_STR_SIZE_MAX];
  58 + uint16_t port;
  59 +
  60 + gduStat = GduLowSpeedDataChannel_Init();
  61 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  62 + USER_LOG_ERROR("init data transmission module error.");
  63 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  64 + }
  65 +
  66 + gduStat = GduAircraftInfo_GetBaseInfo(&s_aircraftInfoBaseInfo);
  67 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  68 + USER_LOG_ERROR("get aircraft base info error");
  69 + return GDU_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
  70 + }
  71 +
  72 + channelAddress = GDU_CHANNEL_ADDRESS_MASTER_RC_APP;
  73 + gduStat = GduLowSpeedDataChannel_RegRecvDataCallback(channelAddress, ReceiveDataFromMobile);
  74 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  75 + USER_LOG_ERROR("register receive data from mobile error.");
  76 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  77 + }
  78 +
  79 + if (osalHandler->TaskCreate("user_transmission_task", UserDataTransmission_Task,
  80 + DATA_TRANSMISSION_TASK_STACK_SIZE, NULL, &s_userDataTransmissionThread) !=
  81 + GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  82 + USER_LOG_ERROR("user data transmission task create error.");
  83 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  84 + }
  85 +
  86 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  87 +}
  88 +
  89 +T_GduReturnCode GduTest_DataTransmissionStopService(void)
  90 +{
  91 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  92 + T_GduReturnCode returnCode;
  93 +
  94 + if (osalHandler->TaskDestroy(s_userDataTransmissionThread) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  95 + USER_LOG_ERROR("user data transmission task destroy error.");
  96 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  97 + }
  98 +
  99 + returnCode = GduLowSpeedDataChannel_DeInit();
  100 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  101 + USER_LOG_ERROR("deinit data transmission module error.");
  102 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  103 + }
  104 +
  105 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  106 +}
  107 +
  108 +/* Private functions definition-----------------------------------------------*/
  109 +#ifndef __CC_ARM
  110 +#pragma GCC diagnostic push
  111 +#pragma GCC diagnostic ignored "-Wmissing-noreturn"
  112 +#pragma GCC diagnostic ignored "-Wreturn-type"
  113 +#endif
  114 +
  115 +static void *UserDataTransmission_Task(void *arg)
  116 +{
  117 + T_GduReturnCode gduStat;
  118 + const uint8_t dataToBeSent[10] = {0x00, 0x11, 0x22, 0x33, 0x44,0x55,0x66,0x77,0x88,0x99};
  119 + T_GduDataChannelState state = {0};
  120 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  121 + E_GduChannelAddress channelAddress;
  122 +
  123 + USER_UTIL_UNUSED(arg);
  124 +
  125 + while (1) {
  126 + osalHandler->TaskSleepMs(1000 / DATA_TRANSMISSION_TASK_FREQ);
  127 +
  128 + channelAddress = GDU_CHANNEL_ADDRESS_MASTER_RC_APP;
  129 + gduStat = GduLowSpeedDataChannel_SendData(channelAddress, dataToBeSent, sizeof(dataToBeSent));
  130 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
  131 + USER_LOG_ERROR("send data to mobile error.");
  132 +
  133 + }
  134 +}
  135 +
  136 +#ifndef __CC_ARM
  137 +#pragma GCC diagnostic pop
  138 +#endif
  139 +
  140 +static T_GduReturnCode ReceiveDataFromMobile(const uint8_t *data, uint16_t len)
  141 +{
  142 + char *printData = NULL;
  143 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  144 +
  145 + printData = osalHandler->Malloc(len + 1);
  146 + if (printData == NULL) {
  147 + USER_LOG_ERROR("malloc memory for printData fail.");
  148 + return GDU_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
  149 + }
  150 +
  151 + strncpy(printData, (const char *) data, len);
  152 + printData[len] = '\0';
  153 + USER_LOG_INFO("receive data from mobile: %s, len:%d.", printData, len);
  154 + GduTest_WidgetLogAppend("receive data: %s, len:%d.", printData, len);
  155 +
  156 + osalHandler->Free(printData);
  157 +
  158 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  159 +}
  160 +
  161 +static T_GduReturnCode ReceiveDataFromCloud(const uint8_t *data, uint16_t len)
  162 +{
  163 + char *printData = NULL;
  164 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  165 +
  166 + printData = osalHandler->Malloc(len + 1);
  167 + if (printData == NULL) {
  168 + USER_LOG_ERROR("malloc memory for printData fail.");
  169 + return GDU_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
  170 + }
  171 +
  172 + strncpy(printData, (const char *) data, len);
  173 + printData[len] = '\0';
  174 + USER_LOG_INFO("receive data from cloud: %s, len:%d.", printData, len);
  175 + GduTest_WidgetLogAppend("receive data: %s, len:%d.", printData, len);
  176 +
  177 + osalHandler->Free(printData);
  178 +
  179 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  180 +}
  181 +
  182 +static T_GduReturnCode ReceiveDataFromExtensionPort(const uint8_t *data, uint16_t len)
  183 +{
  184 + char *printData = NULL;
  185 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  186 +
  187 + printData = osalHandler->Malloc(len + 1);
  188 + if (printData == NULL) {
  189 + USER_LOG_ERROR("malloc memory for printData fail.");
  190 + return GDU_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
  191 + }
  192 +
  193 + strncpy(printData, (const char *) data, len);
  194 + printData[len] = '\0';
  195 + USER_LOG_INFO("receive data from extension port: %s, len:%d.", printData, len);
  196 + GduTest_WidgetLogAppend("receive data: %s, len:%d.", printData, len);
  197 +
  198 + osalHandler->Free(printData);
  199 +
  200 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  201 +}
  202 +
  203 +static T_GduReturnCode ReceiveDataFromPayload(const uint8_t *data, uint16_t len)
  204 +{
  205 + char *printData = NULL;
  206 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  207 +
  208 + printData = osalHandler->Malloc(len + 1);
  209 + if (printData == NULL) {
  210 + USER_LOG_ERROR("malloc memory for printData fail.");
  211 + return GDU_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
  212 + }
  213 +
  214 + strncpy(printData, (const char *) data, len);
  215 + printData[len] = '\0';
  216 + USER_LOG_INFO("receive data from payload port: %s, len:%d.", printData, len);
  217 + GduTest_WidgetLogAppend("receive data: %s, len:%d.", printData, len);
  218 +
  219 + osalHandler->Free(printData);
  220 +
  221 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  222 +}
  223 +
  224 +/****************** (C) COPYRIGHT GDU Innovations *****END OF FILE****/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_data_transmission.h
  4 + * @brief This is the header file for "test_data_transmission.c", defining the structure and
  5 + * (exported) function prototypes.
  6 + *
  7 + * @copyright (c) 2021 GDU. All rights reserved.
  8 + *
  9 + * All information contained herein is, and remains, the property of GDU.
  10 + * The intellectual and technical concepts contained herein are proprietary
  11 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  12 + * and protected by trade secret or copyright law. Dissemination of this
  13 + * information, including but not limited to data and other proprietary
  14 + * material(s) incorporated within the information, in any form, is strictly
  15 + * prohibited without the express written consent of GDU.
  16 + *
  17 + * If you receive this source code without GDU’s authorization, you may not
  18 + * further disseminate the information, and you must immediately remove the
  19 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  20 + * legal actions against you for any loss(es) or damage(s) caused by your
  21 + * failure to do so.
  22 + *
  23 + *********************************************************************
  24 + */
  25 +
  26 +/* Define to prevent recursive inclusion -------------------------------------*/
  27 +#ifndef TEST_DATA_TRANSMISSION_H
  28 +#define TEST_DATA_TRANSMISSION_H
  29 +
  30 +/* Includes ------------------------------------------------------------------*/
  31 +#include "gdu_typedef.h"
  32 +
  33 +#ifdef __cplusplus
  34 +extern "C" {
  35 +#endif
  36 +
  37 +/* Exported constants --------------------------------------------------------*/
  38 +
  39 +
  40 +/* Exported types ------------------------------------------------------------*/
  41 +
  42 +/* Exported functions --------------------------------------------------------*/
  43 +T_GduReturnCode GduTest_DataTransmissionStartService(void);
  44 +T_GduReturnCode GduTest_DataTransmissionStopService(void);
  45 +
  46 +#ifdef __cplusplus
  47 +}
  48 +#endif
  49 +
  50 +#endif // TEST_DATA_TRANSMISSION_H
  51 +
  52 +/************************ (C) COPYRIGHT GDU Innovations *******END OF FILE******/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_fc_subscription.c
  4 + * @brief
  5 + *
  6 + * @copyright (c) 2021 GDU. All rights reserved.
  7 + *
  8 + * All information contained herein is, and remains, the property of GDU.
  9 + * The intellectual and technical concepts contained herein are proprietary
  10 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  11 + * and protected by trade secret or copyright law. Dissemination of this
  12 + * information, including but not limited to data and other proprietary
  13 + * material(s) incorporated within the information, in any form, is strictly
  14 + * prohibited without the express written consent of GDU.
  15 + *
  16 + * If you receive this source code without GDU’s authorization, you may not
  17 + * further disseminate the information, and you must immediately remove the
  18 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  19 + * legal actions against you for any loss(es) or damage(s) caused by your
  20 + * failure to do so.
  21 + *
  22 + *********************************************************************
  23 + */
  24 +
  25 +/* Includes ------------------------------------------------------------------*/
  26 +#include <utils/util_misc.h>
  27 +#include <math.h>
  28 +#include <stdlib.h>
  29 +#include <pthread.h>
  30 +#include "test_fc_subscription.h"
  31 +#include "gdu_logger.h"
  32 +#include "gdu_platform.h"
  33 +
  34 +
  35 +/* Private constants ---------------------------------------------------------*/
  36 +#define FC_SUBSCRIPTION_TASK_FREQ (50)
  37 +#define FC_SUBSCRIPTION_TASK_STACK_SIZE (2048)
  38 +
  39 +/* Private types -------------------------------------------------------------*/
  40 +
  41 +/********************** mycode *******************************/
  42 +
  43 +#define Is_Show_Debug false
  44 +
  45 +//共享变量
  46 +gdu_f64_t lampAngle = 0; //转换后舵机的角度
  47 +
  48 +extern int gimbalLinkageState;
  49 +extern pthread_mutex_t gimbalMutex;
  50 +/********************** mycode *******************************/
  51 +
  52 +/* Private functions declaration ---------------------------------------------*/
  53 +static void *UserFcSubscription_Task(void *arg);
  54 +static T_GduReturnCode GduTest_FcSubscriptionReceiveQuaternionCallback(const uint8_t *data, uint16_t dataSize,
  55 + const T_GduDataTimestamp *timestamp);
  56 +/* Private variables ---------------------------------------------------------*/
  57 +static T_GduTaskHandle s_userFcSubscriptionThread;
  58 +static bool s_userFcSubscriptionDataShow = false;
  59 +static uint8_t s_totalSatelliteNumberUsed = 0;
  60 +
  61 +/* Exported functions definition ---------------------------------------------*/
  62 +
  63 +T_GduReturnCode GduReceiveGpsPositionCallback(const uint8_t *data, uint16_t dataSize, const T_GduDataTimestamp *timestamp)
  64 +{
  65 + T_GduFcSubscriptionGpsPosition *pos = (T_GduFcSubscriptionGpsPosition *)data;
  66 +
  67 + //USER_LOG_DEBUG("gps position is :%d, %d, %d", pos->x, pos->y, pos->z);
  68 +
  69 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  70 +}
  71 +
  72 +T_GduReturnCode GduTest_FcSubscriptionStartService(void)
  73 +{
  74 + T_GduReturnCode gduStat;
  75 + T_GduOsalHandler *osalHandler = NULL;
  76 +
  77 + osalHandler = GduPlatform_GetOsalHandler();
  78 +
  79 + gduStat = GduFcSubscription_Init();
  80 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  81 + USER_LOG_ERROR("init data subscription module error.");
  82 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  83 + }
  84 +
  85 +// gduStat = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_QUATERNION, GDU_DATA_SUBSCRIPTION_TOPIC_10_HZ,
  86 +// GduTest_FcSubscriptionReceiveQuaternionCallback);
  87 +// if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  88 +// USER_LOG_ERROR("Subscribe topic quaternion error.");
  89 +// return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  90 +// } else {
  91 +// USER_LOG_DEBUG("Subscribe topic quaternion success.");
  92 +// }
  93 +//
  94 +// gduStat = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_VELOCITY, GDU_DATA_SUBSCRIPTION_TOPIC_1_HZ,
  95 +// NULL);
  96 +// if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  97 +// USER_LOG_ERROR("Subscribe topic velocity error.");
  98 +// return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  99 +// } else {
  100 +// USER_LOG_DEBUG("Subscribe topic velocity success.");
  101 +// }
  102 +
  103 + // gduStat = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_GPS_POSITION, GDU_DATA_SUBSCRIPTION_TOPIC_1_HZ,
  104 + // GduReceiveGpsPositionCallback);
  105 + // if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  106 + // USER_LOG_ERROR("Subscribe topic gps position error.");
  107 + // return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  108 + // } else {
  109 + // USER_LOG_DEBUG("Subscribe topic gps position success.");
  110 + // }
  111 +
  112 + gduStat = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_GIMBAL_ANGLES, GDU_DATA_SUBSCRIPTION_TOPIC_50_HZ,
  113 + NULL);
  114 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  115 + USER_LOG_ERROR("Subscribe topic gimbal angles error.");
  116 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  117 + } else {
  118 + USER_LOG_DEBUG("Subscribe topic gimbal angles success.");
  119 + }
  120 +
  121 +
  122 + // gduStat = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_GPS_DETAILS, GDU_DATA_SUBSCRIPTION_TOPIC_1_HZ,
  123 +// NULL);
  124 +// if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  125 +// USER_LOG_ERROR("Subscribe topic gps details error.");
  126 +// return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  127 +// } else {
  128 +// USER_LOG_DEBUG("Subscribe topic gps details success.");
  129 +// }
  130 +
  131 + pthread_mutex_init(&gimbalMutex,NULL);//初始化互斥锁
  132 +
  133 + if (osalHandler->TaskCreate("user_subscription_task", UserFcSubscription_Task,
  134 + FC_SUBSCRIPTION_TASK_STACK_SIZE, NULL, &s_userFcSubscriptionThread) !=
  135 + GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  136 + USER_LOG_ERROR("user data subscription task create error.");
  137 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  138 + }
  139 +
  140 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  141 +}
  142 +
  143 +T_GduReturnCode GduTest_FcSubscriptionRunSample(void)
  144 +{
  145 + T_GduReturnCode gduStat;
  146 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  147 + T_GduFcSubscriptionVelocity velocity = {0};
  148 + T_GduDataTimestamp timestamp = {0};
  149 + T_GduFcSubscriptionGpsPosition gpsPosition = {0};
  150 + T_GduFcSubscriptionSingleBatteryInfo singleBatteryInfo = {0};
  151 +
  152 + USER_LOG_INFO("Fc subscription sample start");
  153 +
  154 + USER_LOG_INFO("--> Step 1: Init fc subscription module");
  155 + gduStat = GduFcSubscription_Init();
  156 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  157 + USER_LOG_ERROR("init data subscription module error.");
  158 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  159 + }
  160 +
  161 + USER_LOG_INFO("--> Step 2: Subscribe the topics of quaternion, velocity and gps position");
  162 + gduStat = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_QUATERNION, GDU_DATA_SUBSCRIPTION_TOPIC_10_HZ,
  163 + GduTest_FcSubscriptionReceiveQuaternionCallback);
  164 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  165 + USER_LOG_ERROR("Subscribe topic quaternion error.");
  166 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  167 + }
  168 +
  169 + gduStat = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_VELOCITY, GDU_DATA_SUBSCRIPTION_TOPIC_1_HZ,
  170 + NULL);
  171 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  172 + USER_LOG_ERROR("Subscribe topic velocity error.");
  173 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  174 + }
  175 +
  176 + gduStat = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_GPS_POSITION, GDU_DATA_SUBSCRIPTION_TOPIC_1_HZ,
  177 + NULL);
  178 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  179 + USER_LOG_ERROR("Subscribe topic gps position error.");
  180 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  181 + }
  182 +
  183 + USER_LOG_INFO("--> Step 3: Get latest value of the subscribed topics in the next 20s\r\n");
  184 +
  185 + for (int i = 0; i < 10; ++i) {
  186 + osalHandler->TaskSleepMs(1000 / FC_SUBSCRIPTION_TASK_FREQ);
  187 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_VELOCITY,
  188 + (uint8_t *) &velocity,
  189 + sizeof(T_GduFcSubscriptionVelocity),
  190 + &timestamp);
  191 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  192 + USER_LOG_ERROR("get value of topic velocity error.");
  193 + } else {
  194 + USER_LOG_INFO("velocity: x = %f y = %f z = %f healthFlag = %d.", velocity.data.x, velocity.data.y,
  195 + velocity.data.z, velocity.health);
  196 + }
  197 +
  198 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_GPS_POSITION,
  199 + (uint8_t *) &gpsPosition,
  200 + sizeof(T_GduFcSubscriptionGpsPosition),
  201 + &timestamp);
  202 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  203 + USER_LOG_ERROR("get value of topic gps position error.");
  204 + } else {
  205 + USER_LOG_INFO("gps position: x = %d y = %d z = %d.", gpsPosition.x, gpsPosition.y, gpsPosition.z);
  206 + }
  207 +
  208 + //Attention: if you want to subscribe the single battery info on M300 RTK, you need connect USB cable to
  209 + //OSDK device or use topic GDU_FC_SUBSCRIPTION_TOPIC_BATTERY_INFO instead.
  210 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_BATTERY_SINGLE_INFO_INDEX1,
  211 + (uint8_t *) &singleBatteryInfo,
  212 + sizeof(T_GduFcSubscriptionSingleBatteryInfo),
  213 + &timestamp);
  214 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  215 + USER_LOG_ERROR("get value of topic battery single info index1 error.");
  216 + } else {
  217 + USER_LOG_INFO(
  218 + "battery single info index1: capacity percent = %ld% voltage = %ldV temperature = %.2f degree.",
  219 + singleBatteryInfo.batteryCapacityPercent,
  220 + singleBatteryInfo.currentVoltage / 1000,
  221 + (gdu_f32_t) singleBatteryInfo.batteryTemperature / 10);
  222 + }
  223 +
  224 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_BATTERY_SINGLE_INFO_INDEX2,
  225 + (uint8_t *) &singleBatteryInfo,
  226 + sizeof(T_GduFcSubscriptionSingleBatteryInfo),
  227 + &timestamp);
  228 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  229 + USER_LOG_ERROR("get value of topic battery single info index2 error.");
  230 + } else {
  231 + USER_LOG_INFO(
  232 + "battery single info index2: capacity percent = %ld% voltage = %ldV temperature = %.2f degree.\r\n",
  233 + singleBatteryInfo.batteryCapacityPercent,
  234 + singleBatteryInfo.currentVoltage / 1000,
  235 + (gdu_f32_t) singleBatteryInfo.batteryTemperature / 10);
  236 + }
  237 + }
  238 +
  239 + USER_LOG_INFO("--> Step 4: Deinit fc subscription module");
  240 +
  241 + gduStat = GduFcSubscription_DeInit();
  242 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  243 + USER_LOG_ERROR("Deinit fc subscription error.");
  244 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  245 + }
  246 +
  247 + USER_LOG_INFO("Fc subscription sample end");
  248 +
  249 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  250 +}
  251 +
  252 +T_GduReturnCode GduTest_FcSubscriptionDataShowTrigger(void)
  253 +{
  254 + s_userFcSubscriptionDataShow = !s_userFcSubscriptionDataShow;
  255 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  256 +}
  257 +
  258 +T_GduReturnCode GduTest_FcSubscriptionGetTotalSatelliteNumber(uint8_t *number)
  259 +{
  260 + *number = s_totalSatelliteNumberUsed;
  261 +
  262 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  263 +}
  264 +
  265 +/* Private functions definition-----------------------------------------------*/
  266 +#ifndef __CC_ARM
  267 +#pragma GCC diagnostic push
  268 +#pragma GCC diagnostic ignored "-Wmissing-noreturn"
  269 +#pragma GCC diagnostic ignored "-Wreturn-type"
  270 +#endif
  271 +
  272 +static void *UserFcSubscription_Task(void *arg)
  273 +{
  274 + T_GduReturnCode gduStat;
  275 + T_GduFcSubscriptionVelocity velocity = {0};
  276 + T_GduDataTimestamp timestamp = {0};
  277 + T_GduFcSubscriptionGpsPosition gpsPosition = {0};
  278 + T_GduFcSubscriptionGpsDetails gpsDetails = {0};
  279 + T_GduOsalHandler *osalHandler = NULL;
  280 + T_GduFcSubscriptionGpsTime gpsTime = 0;
  281 +
  282 + T_GduFcSubscriptionGimbalAngles gimbalangle = {0}; //存储云台角度信息
  283 + T_GduFcSubscriptionQuaternion quaternion = {0};
  284 + T_GduFcSubscriptionPositionFused PositionFused = {0}; //融合位置信息
  285 +
  286 + USER_UTIL_UNUSED(arg);
  287 + osalHandler = GduPlatform_GetOsalHandler();
  288 +
  289 + while (1) {
  290 + osalHandler->TaskSleepMs(1000 / FC_SUBSCRIPTION_TASK_FREQ);
  291 +
  292 + // gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_VELOCITY,
  293 + // (uint8_t *) &velocity,
  294 + // sizeof(T_GduFcSubscriptionVelocity),
  295 + // &timestamp);
  296 + // if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  297 + // USER_LOG_ERROR("get value of topic velocity error.");
  298 + // }
  299 + // USER_LOG_INFO("velocity: x %f y %f z %f, healthFlag %d.", velocity.data.x, velocity.data.y,
  300 + // velocity.data.z, velocity.health);
  301 + // if (s_userFcSubscriptionDataShow == true) {
  302 + // USER_LOG_INFO("velocity: x %f y %f z %f, healthFlag %d.", velocity.data.x, velocity.data.y,
  303 + // velocity.data.z, velocity.health);
  304 + // }
  305 + // else
  306 + // {
  307 + // printf("s_userFcSubscriptionDataShow == false\n");
  308 + // }
  309 +
  310 + pthread_mutex_lock(&gimbalMutex);
  311 + //获取相机云台角度信息
  312 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_GIMBAL_ANGLES,
  313 + (uint8_t *) &gimbalangle,
  314 + sizeof(T_GduFcSubscriptionGimbalAngles),
  315 + &timestamp);
  316 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  317 + USER_LOG_ERROR("get value of topic gimbal angle error.");
  318 + }
  319 + else
  320 + {
  321 + //USER_LOG_INFO(" = %f ",gimbalangle.x);
  322 + if(gimbalangle.x >= 0)
  323 + {
  324 + lampAngle = 0;
  325 + }
  326 + else
  327 + {
  328 + lampAngle = abs(gimbalangle.x);
  329 +
  330 + }
  331 + }
  332 + pthread_mutex_unlock(&gimbalMutex);
  333 +
  334 +
  335 + // gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_GPS_POSITION,
  336 + // (uint8_t *) &gpsPosition,
  337 + // sizeof(T_GduFcSubscriptionGpsPosition),
  338 + // &timestamp);
  339 + // if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  340 + // USER_LOG_ERROR("get value of topic gps position error.");
  341 + // }
  342 +
  343 + // if (s_userFcSubscriptionDataShow == true) {
  344 + // USER_LOG_INFO("gps position: x %d y %d z %d.", gpsPosition.x, gpsPosition.y, gpsPosition.z);
  345 + // }
  346 +
  347 + // gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_GPS_DETAILS,
  348 + // (uint8_t *) &gpsDetails,
  349 + // sizeof(T_GduFcSubscriptionGpsDetails),
  350 + // &timestamp);
  351 + // if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  352 + // USER_LOG_ERROR("get value of topic gps details error.");
  353 + // }
  354 +
  355 + // gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_GPS_TIME,
  356 + // (uint8_t *) &gpsTime,
  357 + // sizeof(T_GduFcSubscriptionGpsTime),
  358 + // &timestamp);
  359 + // if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  360 + // USER_LOG_ERROR("get value of topic gps time error.");
  361 + // }
  362 +
  363 + // gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_GPS_DATE,
  364 + // (uint8_t *) &gpsTime,
  365 + // sizeof(T_GduFcSubscriptionGpsTime),
  366 + // &timestamp);
  367 + // if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  368 + // USER_LOG_ERROR("get value of topic gps time error.");
  369 + // }
  370 +
  371 + // if (s_userFcSubscriptionDataShow == true) {
  372 + // USER_LOG_INFO("gps total satellite number used: %d %d %d.",
  373 + // gpsDetails.gpsSatelliteNumberUsed,
  374 + // gpsDetails.glonassSatelliteNumberUsed,
  375 + // gpsDetails.totalSatelliteNumberUsed);
  376 + // s_totalSatelliteNumberUsed = gpsDetails.totalSatelliteNumberUsed;
  377 + // }
  378 +
  379 + }
  380 +}
  381 +
  382 +#ifndef __CC_ARM
  383 +#pragma GCC diagnostic pop
  384 +#endif
  385 +
  386 +static T_GduReturnCode GduTest_FcSubscriptionReceiveQuaternionCallback(const uint8_t *data, uint16_t dataSize,
  387 + const T_GduDataTimestamp *timestamp)
  388 +{
  389 + T_GduFcSubscriptionQuaternion *quaternion = (T_GduFcSubscriptionQuaternion *) data;
  390 + gdu_f64_t pitch, yaw, roll;
  391 +
  392 + USER_UTIL_UNUSED(dataSize);
  393 +
  394 + pitch = (gdu_f64_t) asinf(-2 * quaternion->q1 * quaternion->q3 + 2 * quaternion->q0 * quaternion->q2) * 57.3;
  395 + roll = (gdu_f64_t) atan2f(2 * quaternion->q1 * quaternion->q2 + 2 * quaternion->q0 * quaternion->q3,
  396 + -2 * quaternion->q2 * quaternion->q2 - 2 * quaternion->q3 * quaternion->q3 + 1) *
  397 + 57.3;
  398 + yaw = (gdu_f64_t) atan2f(2 * quaternion->q2 * quaternion->q3 + 2 * quaternion->q0 * quaternion->q1,
  399 + -2 * quaternion->q1 * quaternion->q1 - 2 * quaternion->q2 * quaternion->q2 + 1) * 57.3;
  400 +
  401 + if (s_userFcSubscriptionDataShow == true) {
  402 + USER_LOG_INFO("receive quaternion data.");
  403 +
  404 + USER_LOG_INFO("timestamp: millisecond %u microsecond %u.", timestamp->millisecond,
  405 + timestamp->microsecond);
  406 + USER_LOG_INFO("quaternion: %f %f %f %f.\r\n", quaternion->q0, quaternion->q1, quaternion->q2, quaternion->q3);
  407 + USER_LOG_INFO("euler angles: pitch = %.2f roll = %.2f yaw = %.2f.", pitch, yaw, roll);
  408 + //GduTest_WidgetLogAppend("pitch = %.2f roll = %.2f yaw = %.2f.", pitch, yaw, roll);
  409 + }
  410 +
  411 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  412 +}
  413 +
  414 +/****************** (C) COPYRIGHT GDU Innovations *****END OF FILE****/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_fc_subscription.h
  4 + * @brief This is the header file for "test_fc_subscription.c", defining the structure and
  5 + * (exported) function prototypes.
  6 + *
  7 + * @copyright (c) 2021 GDU. All rights reserved.
  8 + *
  9 + * All information contained herein is, and remains, the property of GDU.
  10 + * The intellectual and technical concepts contained herein are proprietary
  11 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  12 + * and protected by trade secret or copyright law. Dissemination of this
  13 + * information, including but not limited to data and other proprietary
  14 + * material(s) incorporated within the information, in any form, is strictly
  15 + * prohibited without the express written consent of GDU.
  16 + *
  17 + * If you receive this source code without GDU’s authorization, you may not
  18 + * further disseminate the information, and you must immediately remove the
  19 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  20 + * legal actions against you for any loss(es) or damage(s) caused by your
  21 + * failure to do so.
  22 + *
  23 + *********************************************************************
  24 + */
  25 +
  26 +/* Define to prevent recursive inclusion -------------------------------------*/
  27 +#ifndef TEST_FC_SUBSCRIPTION_H
  28 +#define TEST_FC_SUBSCRIPTION_H
  29 +
  30 +/* Includes ------------------------------------------------------------------*/
  31 +#include "gdu_typedef.h"
  32 +#include "gdu_fc_subscription.h"
  33 +
  34 +#ifdef __cplusplus
  35 +extern "C" {
  36 +#endif
  37 +
  38 +/* Exported constants --------------------------------------------------------*/
  39 +
  40 +
  41 +/* Exported types ------------------------------------------------------------*/
  42 +
  43 +
  44 +/* Exported functions --------------------------------------------------------*/
  45 +T_GduReturnCode GduTest_FcSubscriptionStartService(void);
  46 +T_GduReturnCode GduTest_FcSubscriptionRunSample(void);
  47 +T_GduReturnCode GduTest_FcSubscriptionDataShowTrigger(void);
  48 +T_GduReturnCode GduTest_FcSubscriptionGetTotalSatelliteNumber(uint8_t *number);
  49 +
  50 +#ifdef __cplusplus
  51 +}
  52 +#endif
  53 +
  54 +#endif // TEST_FC_SUBSCRIPTION_H
  55 +/************************ (C) COPYRIGHT GDU Innovations *******END OF FILE******/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_flight_control.c
  4 + * @brief
  5 + *
  6 + * @copyright (c) 2021 GDU. All rights reserved.
  7 + *
  8 + * All information contained herein is, and remains, the property of GDU.
  9 + * The intellectual and technical concepts contained herein are proprietary
  10 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  11 + * and protected by trade secret or copyright law. Dissemination of this
  12 + * information, including but not limited to data and other proprietary
  13 + * material(s) incorporated within the information, in any form, is strictly
  14 + * prohibited without the express written consent of GDU.
  15 + *
  16 + * If you receive this source code without GDU’s authorization, you may not
  17 + * further disseminate the information, and you must immediately remove the
  18 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  19 + * legal actions against you for any loss(es) or damage(s) caused by your
  20 + * failure to do so.
  21 + *
  22 + *********************************************************************
  23 + */
  24 +
  25 +/* Includes ------------------------------------------------------------------*/
  26 +#include "gdu_flight_controller.h"
  27 +#include "test_flight_control.h"
  28 +#include "gdu_fc_subscription.h"
  29 +#include "gdu_platform.h"
  30 +#include "gdu_logger.h"
  31 +#include <math.h>
  32 +//#include <widget_interaction_test/test_widget_interaction.h>
  33 +/* Private constants ---------------------------------------------------------*/
  34 +
  35 +/* Private types -------------------------------------------------------------*/
  36 +#pragma pack(1)
  37 +typedef struct {
  38 + gdu_f32_t x;
  39 + gdu_f32_t y;
  40 + gdu_f32_t z;
  41 +} T_GduTestFlightControlVector3f; // pack(1)
  42 +#pragma pack()
  43 +
  44 +typedef struct {
  45 + E_GduFcSubscriptionDisplayMode displayMode;
  46 + char *displayModeStr;
  47 +} T_GduTestFlightControlDisplayModeStr;
  48 +
  49 +/* Private values -------------------------------------------------------------*/
  50 +static T_GduOsalHandler *s_osalHandler = NULL;
  51 +static const double s_earthCenter = 6378137.0;
  52 +static const double s_degToRad = 0.01745329252;
  53 +
  54 +static const T_GduTestFlightControlDisplayModeStr s_flightControlDisplayModeStr[] = {
  55 + {.displayMode = GDU_FC_SUBSCRIPTION_DISPLAY_MODE_ATTITUDE, .displayModeStr = "attitude mode"},
  56 + {.displayMode = GDU_FC_SUBSCRIPTION_DISPLAY_MODE_P_GPS, .displayModeStr = "p_gps mode"},
  57 + {.displayMode = GDU_FC_SUBSCRIPTION_DISPLAY_MODE_ASSISTED_TAKEOFF, .displayModeStr = "assisted takeoff mode"},
  58 + {.displayMode = GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_TAKEOFF, .displayModeStr = "auto takeoff mode"},
  59 + {.displayMode = GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_LANDING, .displayModeStr = "auto landing mode"},
  60 + {.displayMode = GDU_FC_SUBSCRIPTION_DISPLAY_MODE_NAVI_GO_HOME, .displayModeStr = "go home mode"},
  61 + {.displayMode = GDU_FC_SUBSCRIPTION_DISPLAY_MODE_FORCE_AUTO_LANDING, .displayModeStr = "force landing mode"},
  62 + {.displayMode = GDU_FC_SUBSCRIPTION_DISPLAY_MODE_ENGINE_START, .displayModeStr = "engine start mode"},
  63 + {.displayMode = 0xFF, .displayModeStr = "unknown mode"}
  64 +};
  65 +
  66 +/* Private functions declaration ---------------------------------------------*/
  67 +static uint8_t GduTest_FlightControlGetDisplayModeIndex(E_GduFcSubscriptionDisplayMode displayMode);
  68 +static T_GduFcSubscriptionFlightStatus GduTest_FlightControlGetValueOfFlightStatus(void);
  69 +static T_GduFcSubscriptionDisplaymode GduTest_FlightControlGetValueOfDisplayMode(void);
  70 +static T_GduFcSubscriptionAvoidData GduTest_FlightControlGetValueOfAvoidData(void);
  71 +static T_GduFcSubscriptionQuaternion GduTest_FlightControlGetValueOfQuaternion(void);
  72 +static T_GduFcSubscriptionPositionFused GduTest_FlightControlGetValueOfPositionFused(void);
  73 +static gdu_f32_t GduTest_FlightControlGetValueOfRelativeHeight(void);
  74 +static bool GduTest_FlightControlMotorStartedCheck(void);
  75 +static bool GduTest_FlightControlTakeOffInAirCheck(void);
  76 +static bool GduTest_FlightControlLandFinishedCheck(void);
  77 +static bool GduTest_FlightControlMonitoredTakeoff(void);
  78 +static bool GduTest_FlightControlCheckActionStarted(E_GduFcSubscriptionDisplayMode mode);
  79 +static bool GduTest_FlightControlMonitoredLanding(void);
  80 +static bool GduTest_FlightControlGoHomeAndConfirmLanding(void);
  81 +static T_GduTestFlightControlVector3f GduTest_FlightControlQuaternionToEulerAngle(T_GduFcSubscriptionQuaternion quat);
  82 +static T_GduTestFlightControlVector3f
  83 +GduTest_FlightControlLocalOffsetFromGpsAndFusedHeightOffset(T_GduFcSubscriptionPositionFused target,
  84 + T_GduFcSubscriptionPositionFused origin,
  85 + gdu_f32_t targetHeight,
  86 + gdu_f32_t originHeight);
  87 +static T_GduTestFlightControlVector3f
  88 +GduTest_FlightControlVector3FSub(T_GduTestFlightControlVector3f vectorA, T_GduTestFlightControlVector3f vectorB);
  89 +static int GduTest_FlightControlSignOfData(gdu_f32_t data);
  90 +static void GduTest_FlightControlHorizCommandLimit(gdu_f32_t speedFactor, gdu_f32_t *commandX, gdu_f32_t *commandY);
  91 +static gdu_f32_t GduTest_FlightControlVectorNorm(T_GduTestFlightControlVector3f v);
  92 +static T_GduReturnCode
  93 +GduTest_FlightControlJoystickCtrlAuthSwitchEventCallback(T_GduFlightControllerJoystickCtrlAuthorityEventInfo eventData);
  94 +static bool
  95 +GduTest_FlightControlMoveByPositionOffset(T_GduTestFlightControlVector3f offsetDesired, float yawDesiredInDeg,
  96 + float posThresholdInM,
  97 + float yawThresholdInDeg);
  98 +static void
  99 +GduTest_FlightControlVelocityAndYawRateCtrl(T_GduTestFlightControlVector3f offsetDesired, float yawRate,
  100 + uint32_t timeMs);
  101 +static T_GduReturnCode GduTest_FlightControlInit(void);
  102 +static T_GduReturnCode GduTest_FlightControlDeInit(void);
  103 +static void GduTest_FlightControlTakeOffLandingSample(void);
  104 +static void GduTest_FlightControlPositionControlSample(void);
  105 +static void GduTest_FlightControlGoHomeForceLandingSample(void);
  106 +static void GduTest_FlightControlVelocityControlSample(void);
  107 +static void GduTest_FlightControlArrestFlyingSample(void);
  108 +static void GduTest_FlightControlSample(E_GduTestFlightCtrlSampleSelect flightCtrlSampleSelect);
  109 +
  110 +/* Exported functions definition ---------------------------------------------*/
  111 +T_GduReturnCode GduTest_FlightControlRunSample(E_GduTestFlightCtrlSampleSelect flightCtrlSampleSelect)
  112 +{
  113 + T_GduReturnCode returnCode;
  114 +
  115 + USER_LOG_DEBUG("Init flight Control Sample");
  116 + GduTest_WidgetLogAppend("Init flight Control Sample");
  117 +
  118 + returnCode = GduTest_FlightControlInit();
  119 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  120 + USER_LOG_ERROR("Init flight Control sample failed,error code:0x%08llX", returnCode);
  121 + return returnCode;
  122 + }
  123 +
  124 + GduTest_FlightControlSample(flightCtrlSampleSelect);
  125 +
  126 + USER_LOG_DEBUG("Deinit Flight Control Sample");
  127 + GduTest_WidgetLogAppend("Deinit Flight Control Sample");
  128 + returnCode = GduTest_FlightControlDeInit();
  129 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  130 + USER_LOG_ERROR("Deinit Flight Control sample failed,error code:0x%08llX", returnCode);
  131 + return returnCode;
  132 + }
  133 +
  134 + return returnCode;
  135 +}
  136 +
  137 +/* Private functions definition-----------------------------------------------*/
  138 +T_GduReturnCode GduTest_FlightControlInit(void)
  139 +{
  140 + T_GduReturnCode returnCode;
  141 +
  142 + s_osalHandler = GduPlatform_GetOsalHandler();
  143 + if (!s_osalHandler) return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  144 +
  145 + returnCode = GduFlightController_Init();
  146 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  147 + USER_LOG_ERROR("Init flight controller module failed, error code:0x%08llX", returnCode);
  148 + return returnCode;
  149 + }
  150 +
  151 + returnCode = GduFcSubscription_Init();
  152 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  153 + USER_LOG_ERROR("Init data subscription module failed, error code:0x%08llX", returnCode);
  154 + return returnCode;
  155 + }
  156 +
  157 + /*! subscribe fc data */
  158 + returnCode = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_STATUS_FLIGHT,
  159 + GDU_DATA_SUBSCRIPTION_TOPIC_10_HZ,
  160 + NULL);
  161 +
  162 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  163 + USER_LOG_ERROR("Subscribe topic flight status failed, error code:0x%08llX", returnCode);
  164 + return returnCode;
  165 + }
  166 +
  167 + returnCode = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_STATUS_DISPLAYMODE,
  168 + GDU_DATA_SUBSCRIPTION_TOPIC_10_HZ,
  169 + NULL);
  170 +
  171 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  172 + USER_LOG_ERROR("Subscribe topic display mode failed, error code:0x%08llX", returnCode);
  173 + return returnCode;
  174 + }
  175 +
  176 + returnCode = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_AVOID_DATA,
  177 + GDU_DATA_SUBSCRIPTION_TOPIC_10_HZ,
  178 + NULL);
  179 +
  180 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  181 + USER_LOG_ERROR("Subscribe topic avoid data failed,error code:0x%08llX", returnCode);
  182 + return returnCode;
  183 + }
  184 +
  185 + returnCode = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_QUATERNION,
  186 + GDU_DATA_SUBSCRIPTION_TOPIC_10_HZ,
  187 + NULL);
  188 +
  189 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  190 + USER_LOG_ERROR("Subscribe topic quaternion failed,error code:0x%08llX", returnCode);
  191 + return returnCode;
  192 + }
  193 +
  194 + returnCode = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_POSITION_FUSED,
  195 + GDU_DATA_SUBSCRIPTION_TOPIC_10_HZ,
  196 + NULL);
  197 +
  198 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  199 + USER_LOG_ERROR("Subscribe topic position fused failed,error code:0x%08llX", returnCode);
  200 + return returnCode;
  201 + }
  202 +
  203 + returnCode = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_ALTITUDE_FUSED,
  204 + GDU_DATA_SUBSCRIPTION_TOPIC_10_HZ,
  205 + NULL);
  206 +
  207 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  208 + USER_LOG_ERROR("Subscribe topic altitude fused failed,error code:0x%08llX", returnCode);
  209 + return returnCode;
  210 + }
  211 +
  212 + returnCode = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_ALTITUDE_OF_HOMEPOINT,
  213 + GDU_DATA_SUBSCRIPTION_TOPIC_1_HZ,
  214 + NULL);
  215 +
  216 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  217 + USER_LOG_ERROR("Subscribe topic altitude of home point failed,error code:0x%08llX", returnCode);
  218 + return returnCode;
  219 + }
  220 +
  221 + returnCode = GduFlightController_RegJoystickCtrlAuthorityEventCallback(
  222 + GduTest_FlightControlJoystickCtrlAuthSwitchEventCallback);
  223 +
  224 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS && returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT) {
  225 + USER_LOG_ERROR("Register joystick control authority event callback failed,error code:0x%08llX", returnCode);
  226 + return returnCode;
  227 + }
  228 +
  229 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  230 +}
  231 +
  232 +T_GduReturnCode GduTest_FlightControlDeInit(void)
  233 +{
  234 + T_GduReturnCode returnCode;
  235 +
  236 + returnCode = GduFlightController_Deinit();
  237 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  238 + USER_LOG_ERROR("Deinit flight controller module failed, error code:0x%08llX",
  239 + returnCode);
  240 + return returnCode;
  241 + }
  242 +
  243 + returnCode = GduFcSubscription_DeInit();
  244 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  245 + USER_LOG_ERROR("Deinit data subscription module failed, error code:0x%08llX",
  246 + returnCode);
  247 + return returnCode;
  248 + }
  249 +
  250 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  251 +}
  252 +
  253 +void GduTest_FlightControlTakeOffLandingSample()
  254 +{
  255 + T_GduReturnCode returnCode;
  256 +
  257 + USER_LOG_INFO("Flight control takeoff-landing sample start");
  258 + GduTest_WidgetLogAppend("Flight control takeoff-landing sample start");
  259 + USER_LOG_INFO("--> Step 1: Obtain joystick control authority.");
  260 + GduTest_WidgetLogAppend("--> Step 1: Obtain joystick control authority.");
  261 + returnCode = GduFlightController_ObtainJoystickCtrlAuthority();
  262 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  263 + USER_LOG_ERROR("Obtain joystick authority failed, error code: 0x%08X", returnCode);
  264 + goto out;
  265 + }
  266 + s_osalHandler->TaskSleepMs(1000);
  267 +
  268 + USER_LOG_INFO("--> Step 2: Take off\r\n");
  269 + GduTest_WidgetLogAppend("--> Step 2: Take off\r\n");
  270 + if (!GduTest_FlightControlMonitoredTakeoff()) {
  271 + USER_LOG_ERROR("Take off failed");
  272 + goto out;
  273 + }
  274 + USER_LOG_INFO("Successful take off\r\n");
  275 + GduTest_WidgetLogAppend("Successful take off\r\n");
  276 + s_osalHandler->TaskSleepMs(4000);
  277 +
  278 + USER_LOG_INFO("--> Step 3: Landing\r\n");
  279 + GduTest_WidgetLogAppend("--> Step 3: Landing\r\n");
  280 + if (!GduTest_FlightControlMonitoredLanding()) {
  281 + USER_LOG_ERROR("Landing failed");
  282 + goto out;
  283 + }
  284 + USER_LOG_INFO("Successful landing\r\n");
  285 + GduTest_WidgetLogAppend("Successful landing\r\n");
  286 +
  287 + USER_LOG_INFO("--> Step 4: Release joystick authority");
  288 + GduTest_WidgetLogAppend("--> Step 4: Release joystick authority");
  289 + returnCode = GduFlightController_ReleaseJoystickCtrlAuthority();
  290 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  291 + USER_LOG_ERROR("Release joystick authority failed, error code: 0x%08X", returnCode);
  292 + goto out;
  293 + }
  294 +
  295 +out:
  296 + USER_LOG_INFO("Flight control takeoff-landing sample end");
  297 + GduTest_WidgetLogAppend("Flight control takeoff-landing sample end");
  298 +}
  299 +
  300 +void GduTest_FlightControlPositionControlSample()
  301 +{
  302 + T_GduReturnCode returnCode;
  303 +
  304 + USER_LOG_INFO("Flight control move-by-position sample start");
  305 + GduTest_WidgetLogAppend("Flight control move-by-position sample start");
  306 +
  307 + USER_LOG_INFO("--> Step 1: Obtain joystick control authority.");
  308 + GduTest_WidgetLogAppend("--> Step 1: Obtain joystick control authority.");
  309 + returnCode = GduFlightController_ObtainJoystickCtrlAuthority();
  310 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  311 + USER_LOG_ERROR("Obtain joystick authority failed, error code: 0x%08X", returnCode);
  312 + goto out;
  313 + }
  314 + s_osalHandler->TaskSleepMs(1000);
  315 +
  316 + USER_LOG_INFO("--> Step 2: Take off\r\n");
  317 + GduTest_WidgetLogAppend("--> Step 2: Take off\r\n");
  318 + if (!GduTest_FlightControlMonitoredTakeoff()) {
  319 + USER_LOG_ERROR("Take off failed");
  320 + goto out;
  321 + }
  322 + USER_LOG_INFO("Successful take off\r\n");
  323 + GduTest_WidgetLogAppend("Successful take off\r\n");
  324 +
  325 + USER_LOG_INFO("--> Step 3: Move to north:0(m), earth:6(m), up:6(m) , yaw:30(degree) from current point");
  326 + GduTest_WidgetLogAppend("--> Step 3: Move to north:0(m), earth:6(m), up:6(m) , yaw:30(degree) from current point");
  327 + if (!GduTest_FlightControlMoveByPositionOffset((T_GduTestFlightControlVector3f) {0, 6, 6}, 30, 0.8, 1)) {
  328 + USER_LOG_ERROR("Move to north:0(m), earth:6(m), up:6(m) , yaw:30(degree) from current point failed");
  329 + goto out;
  330 + };
  331 +
  332 + USER_LOG_INFO("--> Step 4: Move to north:6(m), earth:0(m), up:-3(m) , yaw:-30(degree) from current point");
  333 + GduTest_WidgetLogAppend(
  334 + "--> Step 4: Move to north:6(m), earth:0(m), up:-3(m) , yaw:-30(degree) from current point");
  335 + if (!GduTest_FlightControlMoveByPositionOffset((T_GduTestFlightControlVector3f) {6, 0, -3}, -30, 0.8, 1)) {
  336 + USER_LOG_ERROR("Move to north:6(m), earth:0(m), up:-3(m) , yaw:-30(degree) from current point failed");
  337 + goto out;
  338 + };
  339 +
  340 + USER_LOG_INFO("--> Step 5: Move to north:-6(m), earth:-6(m), up:0(m) , yaw:0(degree) from current point");
  341 + GduTest_WidgetLogAppend("--> Step 5: Move to north:-6(m), earth:-6(m), up:0(m) , yaw:0(degree) from current point");
  342 + if (!GduTest_FlightControlMoveByPositionOffset((T_GduTestFlightControlVector3f) {-6, -6, 0}, 0, 0.8, 1)) {
  343 + USER_LOG_ERROR("Move to north:-6(m), earth:-6(m), up:0(m) , yaw:0(degree) from current point failed");
  344 + goto out;
  345 + }
  346 +
  347 + USER_LOG_INFO("--> Step 6: Landing\r\n");
  348 + GduTest_WidgetLogAppend("--> Step 6: Landing\r\n");
  349 + if (!GduTest_FlightControlMonitoredLanding()) {
  350 + USER_LOG_ERROR("Landing failed");
  351 + goto out;
  352 + }
  353 + USER_LOG_INFO("Successful landing\r\n");
  354 + GduTest_WidgetLogAppend("Successful landing\r\n");
  355 +
  356 + USER_LOG_INFO("--> Step 7: Release joystick authority");
  357 + GduTest_WidgetLogAppend("--> Step 7: Release joystick authority");
  358 + returnCode = GduFlightController_ReleaseJoystickCtrlAuthority();
  359 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  360 + USER_LOG_ERROR("Release joystick authority failed, error code: 0x%08X", returnCode);
  361 + goto out;
  362 + }
  363 +
  364 +out:
  365 + USER_LOG_INFO("Flight control move-by-position sample end");
  366 + GduTest_WidgetLogAppend("Flight control move-by-position sample end");
  367 +}
  368 +
  369 +void GduTest_FlightControlGoHomeForceLandingSample()
  370 +{
  371 + T_GduReturnCode returnCode;
  372 +
  373 + USER_LOG_INFO("Flight control go-home-force-landing sample start");
  374 + GduTest_WidgetLogAppend("Flight control go-home-force-landing sample start");
  375 +
  376 + //no need Obtain joystick control authority
  377 +// USER_LOG_INFO("--> Step 1: Obtain joystick control authority");
  378 +// GduTest_WidgetLogAppend("--> Step 1: Obtain joystick control authority");
  379 +// returnCode = GduFlightController_ObtainJoystickCtrlAuthority();
  380 +// if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  381 +// USER_LOG_ERROR("Obtain joystick authority failed, error code: 0x%08X", returnCode);
  382 +// goto out;
  383 +// }
  384 +// s_osalHandler->TaskSleepMs(1000);
  385 +
  386 + USER_LOG_INFO("--> Step 2: Take off\r\n");
  387 + GduTest_WidgetLogAppend("--> Step 2: Take off\r\n");
  388 + if (!GduTest_FlightControlMonitoredTakeoff()) {
  389 + USER_LOG_ERROR("Take off failed");
  390 + goto out;
  391 + }
  392 + USER_LOG_INFO("Successful take off\r\n");
  393 + GduTest_WidgetLogAppend("Successful take off\r\n");
  394 +
  395 + USER_LOG_INFO("--> Step 3: Move to north:0(m), earth:0(m), up:30(m) , yaw:0(degree) from current point");
  396 + GduTest_WidgetLogAppend("--> Step 3: Move to north:0(m), earth:0(m), up:30(m) , yaw:0(degree) from current point");
  397 + if (!GduTest_FlightControlMoveByPositionOffset((T_GduTestFlightControlVector3f) {0, 0, 30}, 0, 0.8, 1)) {
  398 + USER_LOG_ERROR("Move to north:0(m), earth:0(m), up:30(m) , yaw:0(degree) from current point failed");
  399 + goto out;
  400 + }
  401 +
  402 + USER_LOG_INFO("--> Step 4: Move to north:10(m), earth:0(m), up:0(m) , yaw:0(degree) from current point");
  403 + GduTest_WidgetLogAppend("--> Step 4: Move to north:10(m), earth:0(m), up:0(m) , yaw:0(degree) from current point");
  404 + if (!GduTest_FlightControlMoveByPositionOffset((T_GduTestFlightControlVector3f) {10, 0, 0}, 0, 0.8, 1)) {
  405 + USER_LOG_ERROR("Move to north:10(m), earth:0(m), up:0(m) , yaw:0(degree) from current point failed");
  406 + goto out;
  407 + }
  408 +
  409 + USER_LOG_INFO("--> Step 5: Set aircraft current position as new home location!");
  410 + GduTest_WidgetLogAppend("--> Step 5: Set aircraft current position as new home location!");
  411 + returnCode = GduFlightController_SetHomeLocationUsingCurrentAircraftLocation();
  412 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  413 + USER_LOG_ERROR("Set aircraft current position as new home location failed, error code: 0x%08X", returnCode);
  414 + goto out;
  415 + }
  416 +
  417 + USER_LOG_INFO("--> Step 6: Set go home altitude to 50(m)\r\n");
  418 + GduTest_WidgetLogAppend("--> Step 6: Set go home altitude to 50(m)\r\n");
  419 + returnCode = GduFlightController_SetGoHomeAltitude(50);
  420 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  421 + USER_LOG_ERROR("Set go home altitude to 50(m) failed, error code: 0x%08X", returnCode);
  422 + goto out;
  423 + }
  424 +
  425 + /*! get go home altitude */
  426 + E_GduFlightControllerGoHomeAltitude goHomeAltitude;
  427 + returnCode = GduFlightController_GetGoHomeAltitude(&goHomeAltitude);
  428 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  429 + USER_LOG_ERROR("Get go home altitude failed, error code: 0x%08X", returnCode);
  430 + goto out;
  431 + }
  432 + USER_LOG_INFO("Current go home altitude is %d m\r\n", goHomeAltitude);
  433 + GduTest_WidgetLogAppend("Current go home altitude is %d m\r\n", goHomeAltitude);
  434 +
  435 + USER_LOG_INFO("--> Step 7: Move to north:20(m), earth:0(m), up:0(m) , yaw:0(degree) from current point");
  436 + GduTest_WidgetLogAppend("--> Step 7: Move to north:20(m), earth:0(m), up:0(m) , yaw:0(degree) from current point");
  437 + if (!GduTest_FlightControlMoveByPositionOffset((T_GduTestFlightControlVector3f) {20, 0, 0}, 0, 0.8, 1)) {
  438 + USER_LOG_ERROR("Move to north:20(m), earth:0(m), up:0(m) , yaw:0(degree) from current point failed");
  439 + goto out;
  440 + }
  441 +
  442 + USER_LOG_INFO("--> Step 8: Go home and confirm force landing\r\n");
  443 + GduTest_WidgetLogAppend("--> Step 8: Go home and confirm force landing\r\n");
  444 + if (!GduTest_FlightControlGoHomeAndConfirmLanding()) {
  445 + USER_LOG_ERROR("Go home and confirm force landing failed");
  446 + goto out;
  447 + }
  448 + USER_LOG_INFO("Successful go home and confirm force landing\r\n");
  449 + GduTest_WidgetLogAppend("Successful go home and confirm force landing\r\n");
  450 +
  451 + USER_LOG_INFO("-> Step 9: Release joystick authority");
  452 + GduTest_WidgetLogAppend("-> Step 9: Release joystick authority");
  453 + returnCode = GduFlightController_ReleaseJoystickCtrlAuthority();
  454 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  455 + USER_LOG_ERROR("Release joystick authority failed, error code: 0x%08X", returnCode);
  456 + goto out;
  457 + }
  458 +
  459 +out:
  460 + USER_LOG_INFO("Flight control go-home-force-landing sample end");
  461 + GduTest_WidgetLogAppend("Flight control go-home-force-landing sample end");
  462 +}
  463 +
  464 +void GduTest_FlightControlVelocityControlSample()
  465 +{
  466 + T_GduReturnCode returnCode;
  467 +
  468 + USER_LOG_INFO("Flight control move-by-velocity sample start");
  469 + GduTest_WidgetLogAppend("Flight control move-by-velocity sample start");
  470 +
  471 + USER_LOG_INFO("--> Step 1: Obtain joystick control authority");
  472 + GduTest_WidgetLogAppend("--> Step 1: Obtain joystick control authority");
  473 + returnCode = GduFlightController_ObtainJoystickCtrlAuthority();
  474 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  475 + USER_LOG_ERROR("Obtain joystick authority failed, error code: 0x%08X", returnCode);
  476 + goto out;
  477 + }
  478 + s_osalHandler->TaskSleepMs(1000);
  479 +
  480 + USER_LOG_INFO("--> Step 2: Take off\r\n");
  481 + GduTest_WidgetLogAppend("--> Step 2: Take off\r\n");
  482 + if (!GduTest_FlightControlMonitoredTakeoff()) {
  483 + USER_LOG_ERROR("Take off failed");
  484 + goto out;
  485 + }
  486 + USER_LOG_INFO("Successful take off\r\n");
  487 + GduTest_WidgetLogAppend("Successful take off\r\n");
  488 +
  489 + USER_LOG_INFO(
  490 + "--> Step 3: Move with north:0(m/s), earth:0(m/s), up:5(m/s), yaw:0(deg/s) from current point for 2s!");
  491 + GduTest_WidgetLogAppend(
  492 + "--> Step 3: Move with north:0(m/s), earth:0(m/s), up:5(m/s), yaw:0(deg/s) from current point for 2s!");
  493 + GduTest_FlightControlVelocityAndYawRateCtrl((T_GduTestFlightControlVector3f) {0, 0, 5.0}, 0, 2000);
  494 +
  495 + USER_LOG_INFO("--> Step 4: Emergency brake for 2s");
  496 + GduTest_WidgetLogAppend("--> Step 4: Emergency brake for 2s");
  497 + returnCode = GduFlightController_ExecuteEmergencyBrakeAction();
  498 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  499 + USER_LOG_ERROR("Emergency brake failed, error code: 0x%08X", returnCode);
  500 + goto out;
  501 + }
  502 + s_osalHandler->TaskSleepMs(2000);
  503 + returnCode = GduFlightController_CancelEmergencyBrakeAction();
  504 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  505 + USER_LOG_ERROR("Cancel emergency brake action failed, error code: 0x%08X", returnCode);
  506 + goto out;
  507 + }
  508 +
  509 + USER_LOG_INFO(
  510 + "--> Step 5: Move with north:-1.5(m/s), earth:2(m/s), up:0(m/s), yaw:20(deg/s) from current point for 2s!");
  511 + GduTest_WidgetLogAppend(
  512 + "--> Step 5: Move with north:-1.5(m/s), earth:2(m/s), up:0(m/s), yaw:20(deg/s) from current point for 2s!");
  513 + GduTest_FlightControlVelocityAndYawRateCtrl((T_GduTestFlightControlVector3f) {-1.5, 2, 0}, 20, 2000);
  514 +
  515 + USER_LOG_INFO("--> Step 6: Emergency brake for 2s");
  516 + GduTest_WidgetLogAppend("--> Step 6: Emergency brake for 2s");
  517 + returnCode = GduFlightController_ExecuteEmergencyBrakeAction();
  518 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  519 + USER_LOG_ERROR("Emergency brake failed, error code: 0x%08X", returnCode);
  520 + goto out;
  521 + }
  522 + s_osalHandler->TaskSleepMs(2000);
  523 + returnCode = GduFlightController_CancelEmergencyBrakeAction();
  524 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  525 + USER_LOG_ERROR("Cancel emergency brake action failed, error code: 0x%08X", returnCode);
  526 + goto out;
  527 + }
  528 +
  529 + USER_LOG_INFO(
  530 + "--> Step 7: Move with north:3(m/s), earth:0(m/s), up:0(m/s), yaw:0(deg/s) from current point for 2.5s!");
  531 + GduTest_WidgetLogAppend(
  532 + "--> Step 7: Move with north:3(m/s), earth:0(m/s), up:0(m/s), yaw:0(deg/s) from current point for 2.5s!");
  533 + GduTest_FlightControlVelocityAndYawRateCtrl((T_GduTestFlightControlVector3f) {3, 0, 0}, 0, 2500);
  534 +
  535 + USER_LOG_INFO("--> Step 8: Emergency brake for 2s");
  536 + GduTest_WidgetLogAppend("--> Step 8: Emergency brake for 2s");
  537 + returnCode = GduFlightController_ExecuteEmergencyBrakeAction();
  538 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  539 + USER_LOG_ERROR("Emergency brake failed, error code: 0x%08X", returnCode);
  540 + goto out;
  541 + }
  542 + s_osalHandler->TaskSleepMs(2000);
  543 + returnCode = GduFlightController_CancelEmergencyBrakeAction();
  544 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  545 + USER_LOG_ERROR("Cancel emergency brake action failed, error code: 0x%08X", returnCode);
  546 + goto out;
  547 + }
  548 +
  549 + USER_LOG_INFO(
  550 + "--> Step 9: Move with north:-1.6(m/s), earth:-2(m/s), up:0(m/s), yaw:0(deg/s) from current point for 2.2s!");
  551 + GduTest_WidgetLogAppend(
  552 + "--> Step 9: Move with north:-1.6(m/s), earth:-2(m/s), up:0(m/s), yaw:0(deg/s) from current point for 2.2s!");
  553 + GduTest_FlightControlVelocityAndYawRateCtrl((T_GduTestFlightControlVector3f) {-1.6, -2, 0}, 0, 2200);
  554 +
  555 + USER_LOG_INFO("--> Step 10: Emergency brake for 2s");
  556 + GduTest_WidgetLogAppend("--> Step 10: Emergency brake for 2s");
  557 + returnCode = GduFlightController_ExecuteEmergencyBrakeAction();
  558 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  559 + USER_LOG_ERROR("Emergency brake failed, error code: 0x%08X", returnCode);
  560 + goto out;
  561 + }
  562 + s_osalHandler->TaskSleepMs(2000);
  563 + returnCode = GduFlightController_CancelEmergencyBrakeAction();
  564 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  565 + USER_LOG_ERROR("Cancel emergency brake action failed, error code: 0x%08X", returnCode);
  566 + goto out;
  567 + }
  568 +
  569 + USER_LOG_INFO("--> Step 11: Landing\r\n");
  570 + GduTest_WidgetLogAppend("--> Step 11: Landing\r\n");
  571 + if (!GduTest_FlightControlMonitoredLanding()) {
  572 + USER_LOG_ERROR("Landing failed");
  573 + goto out;
  574 + }
  575 + USER_LOG_INFO("Successful landing\r\n");
  576 + GduTest_WidgetLogAppend("Successful landing\r\n");
  577 +
  578 + USER_LOG_INFO("--> Step 12: Release joystick authority");
  579 + GduTest_WidgetLogAppend("--> Step 12: Release joystick authority");
  580 + returnCode = GduFlightController_ReleaseJoystickCtrlAuthority();
  581 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  582 + USER_LOG_ERROR("Release joystick authority failed, error code: 0x%08X", returnCode);
  583 + goto out;
  584 + }
  585 +
  586 +out:
  587 + USER_LOG_INFO("Flight control move-by-velocity sample end");
  588 + GduTest_WidgetLogAppend("Flight control move-by-velocity sample end");
  589 +}
  590 +
  591 +void GduTest_FlightControlArrestFlyingSample()
  592 +{
  593 + T_GduReturnCode returnCode;
  594 +
  595 + USER_LOG_INFO("Flight control arrest-flying sample start");
  596 + GduTest_WidgetLogAppend("Flight control arrest-flying sample start");
  597 +
  598 + USER_LOG_INFO("--> Step 1: Enable arrest-flying");
  599 + GduTest_WidgetLogAppend("--> Step 1: Enable arrest-flying");
  600 + returnCode = GduFlightController_ArrestFlying();
  601 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  602 + USER_LOG_ERROR("Enable arrest-flying failed, error code: 0x%08X", returnCode);
  603 + goto out;
  604 + }
  605 + s_osalHandler->TaskSleepMs(2000);
  606 +
  607 + //you can replace with takeoff to test in air.
  608 + USER_LOG_INFO("--> Step 2: Turn on motors\r\n");
  609 + GduTest_WidgetLogAppend("--> Step 2: Turn on motors\r\n");
  610 + returnCode = GduFlightController_TurnOnMotors();
  611 + if (returnCode == GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  612 + USER_LOG_ERROR("Turn on motors successfully, but arrest-flying failed");
  613 + s_osalHandler->TaskSleepMs(4000);
  614 + USER_LOG_INFO("--> Step 3: Turn off motors\r\n");
  615 + GduTest_WidgetLogAppend("--> Step 3: Turn off motors\r\n");
  616 + returnCode = GduFlightController_TurnOffMotors();
  617 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  618 + USER_LOG_ERROR("Turn off motors failed, error code: 0x%08X", returnCode);
  619 + }
  620 + goto out;
  621 + }
  622 +
  623 + USER_LOG_INFO("Turn on motors failed.Arrest-flying successfully\r\n");
  624 + GduTest_WidgetLogAppend("Turn on motors failed.Arrest-flying successfully\r\n");
  625 + s_osalHandler->TaskSleepMs(2000);
  626 +
  627 + USER_LOG_INFO("--> Step 3: Disable arrest-flying");
  628 + GduTest_WidgetLogAppend("--> Step 3: Disable arrest-flying");
  629 + returnCode = GduFlightController_CancelArrestFlying();
  630 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  631 + USER_LOG_ERROR("Disable arrest-flying failed, error code: 0x%08X", returnCode);
  632 + goto out;
  633 + }
  634 + s_osalHandler->TaskSleepMs(2000);
  635 +
  636 + USER_LOG_INFO("--> Step 4: Turn on motors\r\n");
  637 + GduTest_WidgetLogAppend("--> Step 4: Turn on motors\r\n");
  638 + returnCode = GduFlightController_TurnOnMotors();
  639 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  640 + USER_LOG_ERROR("Turn on motors failed and disable arrest-flying failed, error code: 0x%08X", returnCode);
  641 + goto out;
  642 + } else {
  643 + USER_LOG_INFO("Turn on motors successfully and disable arrest-flying successfully\r\n");
  644 + s_osalHandler->TaskSleepMs(4000);
  645 + USER_LOG_INFO("--> Step 5: Turn off motors");
  646 + GduTest_WidgetLogAppend("--> Step 5: Turn off motors");
  647 + returnCode = GduFlightController_TurnOffMotors();
  648 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  649 + USER_LOG_ERROR("Turn off motors failed, error code: 0x%08X", returnCode);
  650 + }
  651 + }
  652 +
  653 +out:
  654 + USER_LOG_INFO("Flight control arrest-flying sample end");
  655 + GduTest_WidgetLogAppend("Flight control arrest-flying sample end");
  656 +}
  657 +
  658 +void GduTest_FlightControlSetGetParamSample()
  659 +{
  660 + T_GduReturnCode returnCode;
  661 + E_GduFlightControllerObstacleAvoidanceEnableStatus horizontalVisualObstacleAvoidanceStatus;
  662 + E_GduFlightControllerObstacleAvoidanceEnableStatus horizontalRadarObstacleAvoidanceStatus;
  663 + E_GduFlightControllerObstacleAvoidanceEnableStatus upwardsVisualObstacleAvoidanceStatus;
  664 + E_GduFlightControllerObstacleAvoidanceEnableStatus upwardsRadarObstacleAvoidanceStatus;
  665 + E_GduFlightControllerObstacleAvoidanceEnableStatus downloadsVisualObstacleAvoidanceStatus;
  666 + E_GduFlightControllerGoHomeAltitude goHomeAltitude;
  667 + E_GduFlightControllerRtkPositionEnableStatus rtkEnableStatus;
  668 + E_GduFlightControllerRCLostAction rcLostAction;
  669 +
  670 + USER_LOG_INFO("Flight control set-get-param sample start");
  671 + GduTest_WidgetLogAppend("Flight control set-get-param sample start");
  672 +
  673 + /*! Turn on horizontal vision avoid enable */
  674 + USER_LOG_INFO("--> Step 1: Turn on horizontal visual obstacle avoidance");
  675 + GduTest_WidgetLogAppend("--> Step 1: Turn on horizontal visual obstacle avoidance");
  676 + returnCode = GduFlightController_SetHorizontalVisualObstacleAvoidanceEnableStatus(
  677 + GDU_FLIGHT_CONTROLLER_ENABLE_OBSTACLE_AVOIDANCE);
  678 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  679 + USER_LOG_ERROR("Turn on horizontal visual obstacle avoidance failed, error code: 0x%08X", returnCode);
  680 + goto out;
  681 + };
  682 + s_osalHandler->TaskSleepMs(1000);
  683 +
  684 + USER_LOG_INFO("--> Step 2: Get horizontal horizontal visual obstacle status\r\n");
  685 + GduTest_WidgetLogAppend("--> Step 2: Get horizontal horizontal visual obstacle status\r\n");
  686 + returnCode = GduFlightController_GetHorizontalVisualObstacleAvoidanceEnableStatus(
  687 + &horizontalVisualObstacleAvoidanceStatus);
  688 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  689 + USER_LOG_ERROR("Get horizontal visual obstacle avoidance failed, error code: 0x%08X", returnCode);
  690 + goto out;
  691 + }
  692 + USER_LOG_INFO("Current horizontal visual obstacle avoidance status is %d\r\n",
  693 + horizontalVisualObstacleAvoidanceStatus);
  694 + s_osalHandler->TaskSleepMs(1000);
  695 +
  696 + /*! Turn on horizontal radar avoid enable */
  697 + USER_LOG_INFO("--> Step 3: Turn on horizontal radar obstacle avoidance");
  698 + GduTest_WidgetLogAppend("--> Step 3: Turn on horizontal radar obstacle avoidance");
  699 + returnCode = GduFlightController_SetHorizontalRadarObstacleAvoidanceEnableStatus(
  700 + GDU_FLIGHT_CONTROLLER_ENABLE_OBSTACLE_AVOIDANCE);
  701 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  702 + USER_LOG_ERROR("Turn on horizontal radar obstacle avoidance failed, error code: 0x%08X", returnCode);
  703 + goto out;
  704 + };
  705 + s_osalHandler->TaskSleepMs(1000);
  706 +
  707 + USER_LOG_INFO("--> Step 4: Get horizontal radar obstacle avoidance status\r\n");
  708 + GduTest_WidgetLogAppend("--> Step 4: Get horizontal radar obstacle avoidance status\r\n");
  709 + returnCode = GduFlightController_GetHorizontalRadarObstacleAvoidanceEnableStatus(
  710 + &horizontalRadarObstacleAvoidanceStatus);
  711 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  712 + USER_LOG_ERROR("Get horizontal radar obstacle avoidance failed, error code: 0x%08X", returnCode);
  713 + goto out;
  714 + }
  715 + USER_LOG_INFO("Current horizontal radar obstacle avoidance status is %d\r\n",
  716 + horizontalRadarObstacleAvoidanceStatus);
  717 + s_osalHandler->TaskSleepMs(1000);
  718 +
  719 + /*! Turn on upwards vision avoid enable */
  720 + USER_LOG_INFO("--> Step 5: Turn on upwards visual obstacle avoidance.");
  721 + GduTest_WidgetLogAppend("--> Step 5: Turn on upwards visual obstacle avoidance.");
  722 + returnCode = GduFlightController_SetUpwardsVisualObstacleAvoidanceEnableStatus(
  723 + GDU_FLIGHT_CONTROLLER_ENABLE_OBSTACLE_AVOIDANCE);
  724 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  725 + USER_LOG_ERROR("Turn on upwards visual obstacle avoidance failed, error code: 0x%08X", returnCode);
  726 + goto out;
  727 + };
  728 + s_osalHandler->TaskSleepMs(1000);
  729 +
  730 + USER_LOG_INFO("--> Step 6: Get upwards visual obstacle avoidance status\r\n");
  731 + GduTest_WidgetLogAppend("--> Step 6: Get upwards visual obstacle avoidance status\r\n");
  732 + returnCode = GduFlightController_GetUpwardsVisualObstacleAvoidanceEnableStatus(
  733 + &upwardsVisualObstacleAvoidanceStatus);
  734 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  735 + USER_LOG_ERROR("Get upwards visual obstacle avoidance failed, error code: 0x%08X", returnCode);
  736 + goto out;
  737 + }
  738 + USER_LOG_INFO("Current upwards visual obstacle avoidance status is %d\r\n", upwardsVisualObstacleAvoidanceStatus);
  739 + s_osalHandler->TaskSleepMs(1000);
  740 +
  741 + /*! Turn on upwards radar avoid enable */
  742 + USER_LOG_INFO("--> Step 7: Turn on upwards radar obstacle avoidance.");
  743 + GduTest_WidgetLogAppend("--> Step 7: Turn on upwards radar obstacle avoidance.");
  744 + returnCode = GduFlightController_SetUpwardsRadarObstacleAvoidanceEnableStatus(
  745 + GDU_FLIGHT_CONTROLLER_ENABLE_OBSTACLE_AVOIDANCE);
  746 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  747 + USER_LOG_ERROR("Turn on upwards radar obstacle avoidance failed, error code: 0x%08X", returnCode);
  748 + goto out;
  749 + }
  750 + s_osalHandler->TaskSleepMs(1000);
  751 +
  752 + USER_LOG_INFO("--> Step 8: Get upwards radar obstacle avoidance status\r\n");
  753 + GduTest_WidgetLogAppend("--> Step 8: Get upwards radar obstacle avoidance status\r\n");
  754 + returnCode = GduFlightController_GetUpwardsRadarObstacleAvoidanceEnableStatus(&upwardsRadarObstacleAvoidanceStatus);
  755 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  756 + USER_LOG_ERROR("Get upwards radar obstacle avoidance failed, error code: 0x%08X", returnCode);
  757 + goto out;
  758 + }
  759 + USER_LOG_INFO("Current upwards radar obstacle avoidance status is %d\r\n", upwardsRadarObstacleAvoidanceStatus);
  760 + s_osalHandler->TaskSleepMs(1000);
  761 +
  762 + /*! Turn on downwards vision avoid enable */
  763 + USER_LOG_INFO("--> Step 9: Turn on downwards visual obstacle avoidance.");
  764 + GduTest_WidgetLogAppend("--> Step 9: Turn on downwards visual obstacle avoidance.");
  765 + returnCode = GduFlightController_SetDownwardsVisualObstacleAvoidanceEnableStatus(
  766 + GDU_FLIGHT_CONTROLLER_ENABLE_OBSTACLE_AVOIDANCE);
  767 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  768 + USER_LOG_ERROR("Turn on downwards visual obstacle avoidance failed, error code: 0x%08X", returnCode);
  769 + goto out;
  770 + }
  771 + s_osalHandler->TaskSleepMs(1000);
  772 +
  773 + USER_LOG_INFO("--> Step 10: Get downwards visual obstacle avoidance status\r\n");
  774 + GduTest_WidgetLogAppend("--> Step 10: Get downwards visual obstacle avoidance status\r\n");
  775 + returnCode = GduFlightController_GetDownwardsVisualObstacleAvoidanceEnableStatus(
  776 + &downloadsVisualObstacleAvoidanceStatus);
  777 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  778 + USER_LOG_ERROR("Get downwards visual obstacle avoidance failed, error code: 0x%08X", returnCode);
  779 + goto out;
  780 + }
  781 + USER_LOG_INFO("Current downwards visual obstacle avoidance status is %d\r\n",
  782 + downloadsVisualObstacleAvoidanceStatus);
  783 + s_osalHandler->TaskSleepMs(1000);
  784 +
  785 + /*! Set new go home altitude */
  786 + USER_LOG_INFO("--> Step 11: Set go home altitude to 50(m)");
  787 + GduTest_WidgetLogAppend("--> Step 11: Set go home altitude to 50(m)");
  788 + returnCode = GduFlightController_SetGoHomeAltitude(50);
  789 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  790 + USER_LOG_ERROR("Set go home altitude to 50(m) failed, error code: 0x%08X", returnCode);
  791 + goto out;
  792 + }
  793 + s_osalHandler->TaskSleepMs(1000);
  794 +
  795 + /*! get go home altitude */
  796 + USER_LOG_INFO("--> Step 12: Get go home altitude\r\n");
  797 + GduTest_WidgetLogAppend("--> Step 12: Get go home altitude\r\n");
  798 + returnCode = GduFlightController_GetGoHomeAltitude(&goHomeAltitude);
  799 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  800 + USER_LOG_ERROR("Get go home altitude failed, error code: 0x%08X", returnCode);
  801 + goto out;
  802 + }
  803 + USER_LOG_INFO("Current go home altitude is %d m\r\n", goHomeAltitude);
  804 + s_osalHandler->TaskSleepMs(2000);
  805 +
  806 + /*! Set rtk enable */
  807 + USER_LOG_INFO("--> Step 13: Set rtk enable status");
  808 + GduTest_WidgetLogAppend("--> Step 13: Set rtk enable status");
  809 + returnCode = GduFlightController_SetRtkPositionEnableStatus(GDU_FLIGHT_CONTROLLER_ENABLE_RTK_POSITION);
  810 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  811 + USER_LOG_ERROR("Set rtk enable failed, error code: 0x%08X", returnCode);
  812 + goto out;
  813 + }
  814 + s_osalHandler->TaskSleepMs(1000);
  815 +
  816 + USER_LOG_INFO("--> Step 14: Get rtk enable status\r\n");
  817 + GduTest_WidgetLogAppend("--> Step 14: Get rtk enable status\r\n");
  818 + returnCode = GduFlightController_GetRtkPositionEnableStatus(&rtkEnableStatus);
  819 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  820 + USER_LOG_ERROR("Get rtk enable failed, error code: 0x%08X", returnCode);
  821 + goto out;
  822 + }
  823 + USER_LOG_INFO("Current rtk enable status is %d\r\n", rtkEnableStatus);
  824 + s_osalHandler->TaskSleepMs(1000);
  825 +
  826 + /*! Set rc lost action */
  827 + USER_LOG_INFO("--> Step 15: Set rc lost action");
  828 + GduTest_WidgetLogAppend("--> Step 15: Set rc lost action");
  829 + returnCode = GduFlightController_SetRCLostAction(GDU_FLIGHT_CONTROLLER_RC_LOST_ACTION_GOHOME);
  830 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  831 + USER_LOG_ERROR("Set rc lost action failed, error code: 0x%08X", returnCode);
  832 + goto out;
  833 + }
  834 + s_osalHandler->TaskSleepMs(1000);
  835 +
  836 + USER_LOG_INFO("--> Step 16: Get rc lost action\r\n");
  837 + GduTest_WidgetLogAppend("--> Step 16: Get rc lost action\r\n");
  838 + returnCode = GduFlightController_GetRCLostAction(&rcLostAction);
  839 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  840 + USER_LOG_ERROR("Get rc lost action failed, error code: 0x%08X", returnCode);
  841 + goto out;
  842 + }
  843 + USER_LOG_INFO("Current rc lost action is %d\r\n", rcLostAction);
  844 + GduTest_WidgetLogAppend("Current rc lost action is %d\r\n", rcLostAction);
  845 + s_osalHandler->TaskSleepMs(1000);
  846 +
  847 +out:
  848 + USER_LOG_INFO("Flight control set-get-param sample end");
  849 + GduTest_WidgetLogAppend("Flight control set-get-param sample end");
  850 +}
  851 +
  852 +void GduTest_FlightControlSample(E_GduTestFlightCtrlSampleSelect flightCtrlSampleSelect)
  853 +{
  854 + switch (flightCtrlSampleSelect) {
  855 + case E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_TAKE_OFF_LANDING: {
  856 + GduTest_FlightControlTakeOffLandingSample();
  857 + break;
  858 + }
  859 + case E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_TAKE_OFF_POSITION_CTRL_LANDING: {
  860 + GduTest_FlightControlPositionControlSample();
  861 + break;
  862 + }
  863 + case E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_TAKE_OFF_GO_HOME_FORCE_LANDING: {
  864 + GduTest_FlightControlGoHomeForceLandingSample();
  865 + break;
  866 + }
  867 + case E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_TAKE_OFF_VELOCITY_CTRL_LANDING: {
  868 + GduTest_FlightControlVelocityControlSample();
  869 + break;
  870 + }
  871 + case E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_ARREST_FLYING: {
  872 + GduTest_FlightControlArrestFlyingSample();
  873 + break;
  874 + }
  875 + case E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_SET_GET_PARAM: {
  876 + GduTest_FlightControlSetGetParamSample();
  877 + break;
  878 + }
  879 + default:
  880 + break;
  881 + }
  882 +}
  883 +
  884 +uint8_t GduTest_FlightControlGetDisplayModeIndex(E_GduFcSubscriptionDisplayMode displayMode)
  885 +{
  886 + uint8_t i;
  887 +
  888 + for (i = 0; i < sizeof(s_flightControlDisplayModeStr) / sizeof(T_GduTestFlightControlDisplayModeStr); i++) {
  889 + if (s_flightControlDisplayModeStr[i].displayMode == displayMode) {
  890 + return i;
  891 + }
  892 + }
  893 +
  894 + return i;
  895 +}
  896 +
  897 +T_GduFcSubscriptionFlightStatus GduTest_FlightControlGetValueOfFlightStatus(void)
  898 +{
  899 + T_GduReturnCode gduStat;
  900 + T_GduFcSubscriptionFlightStatus flightStatus;
  901 + T_GduDataTimestamp flightStatusTimestamp = {0};
  902 +
  903 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_STATUS_FLIGHT,
  904 + (uint8_t *) &flightStatus,
  905 + sizeof(T_GduFcSubscriptionFlightStatus),
  906 + &flightStatusTimestamp);
  907 +
  908 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  909 + USER_LOG_ERROR("Get value of topic flight status error, error code: 0x%08X", gduStat);
  910 + flightStatus = 0;
  911 + } else {
  912 + USER_LOG_DEBUG("Timestamp: millisecond %u microsecond %u.", flightStatusTimestamp.millisecond,
  913 + flightStatusTimestamp.microsecond);
  914 + USER_LOG_DEBUG("Flight status: %d.", flightStatus);
  915 + }
  916 +
  917 + return flightStatus;
  918 +}
  919 +
  920 +T_GduFcSubscriptionDisplaymode GduTest_FlightControlGetValueOfDisplayMode(void)
  921 +{
  922 + T_GduReturnCode gduStat;
  923 + T_GduFcSubscriptionDisplaymode displayMode;
  924 + T_GduDataTimestamp displayModeTimestamp = {0};
  925 +
  926 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_STATUS_DISPLAYMODE,
  927 + (uint8_t *) &displayMode,
  928 + sizeof(T_GduFcSubscriptionDisplaymode),
  929 + &displayModeTimestamp);
  930 +
  931 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  932 + USER_LOG_ERROR("Get value of topic display mode error, error code: 0x%08X", gduStat);
  933 + displayMode = 0;
  934 + } else {
  935 + USER_LOG_DEBUG("Timestamp: millisecond %u microsecond %u.", displayModeTimestamp.millisecond,
  936 + displayModeTimestamp.microsecond);
  937 + USER_LOG_DEBUG("Display mode : %d.", displayMode);
  938 + }
  939 +
  940 + return displayMode;
  941 +}
  942 +
  943 +T_GduFcSubscriptionAvoidData GduTest_FlightControlGetValueOfAvoidData(void)
  944 +{
  945 + T_GduReturnCode gduStat;
  946 + T_GduFcSubscriptionAvoidData avoidData = {0};
  947 + T_GduDataTimestamp avoidDataTimestamp = {0};
  948 +
  949 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_AVOID_DATA,
  950 + (uint8_t *) &avoidData,
  951 + sizeof(T_GduFcSubscriptionAvoidData),
  952 + &avoidDataTimestamp);
  953 +
  954 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  955 + USER_LOG_ERROR("Get value of topic avoid data error, error code: 0x%08X", gduStat);
  956 + } else {
  957 + USER_LOG_DEBUG("Timestamp: millisecond %u microsecond %u.", avoidDataTimestamp.millisecond,
  958 + avoidDataTimestamp.microsecond);
  959 + USER_LOG_DEBUG("Avoid downwards distance is %f m", avoidData.down);
  960 + }
  961 +
  962 + return avoidData;
  963 +}
  964 +
  965 +T_GduFcSubscriptionQuaternion GduTest_FlightControlGetValueOfQuaternion(void)
  966 +{
  967 + T_GduReturnCode gduStat;
  968 + T_GduFcSubscriptionQuaternion quaternion = {0};
  969 + T_GduDataTimestamp quaternionTimestamp = {0};
  970 +
  971 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_QUATERNION,
  972 + (uint8_t *) &quaternion,
  973 + sizeof(T_GduFcSubscriptionQuaternion),
  974 + &quaternionTimestamp);
  975 +
  976 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  977 + USER_LOG_ERROR("Get value of topic quaternion error, error code: 0x%08X", gduStat);
  978 + } else {
  979 + USER_LOG_DEBUG("Timestamp: millisecond %u microsecond %u.", quaternionTimestamp.millisecond,
  980 + quaternionTimestamp.microsecond);
  981 + USER_LOG_DEBUG("Quaternion: %f %f %f %f.", quaternion.q0, quaternion.q1, quaternion.q2, quaternion.q3);
  982 + }
  983 +
  984 + return quaternion;
  985 +}
  986 +
  987 +T_GduFcSubscriptionPositionFused GduTest_FlightControlGetValueOfPositionFused(void)
  988 +{
  989 + T_GduReturnCode gduStat;
  990 + T_GduFcSubscriptionPositionFused positionFused = {0};
  991 + T_GduDataTimestamp positionFusedTimestamp = {0};
  992 +
  993 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_POSITION_FUSED,
  994 + (uint8_t *) &positionFused,
  995 + sizeof(T_GduFcSubscriptionPositionFused),
  996 + &positionFusedTimestamp);
  997 +
  998 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  999 + USER_LOG_ERROR("Get value of topic position fused error, error code: 0x%08X", gduStat);
  1000 + } else {
  1001 + USER_LOG_DEBUG("Timestamp: millisecond %u microsecond %u.", positionFusedTimestamp.millisecond,
  1002 + positionFusedTimestamp.microsecond);
  1003 + USER_LOG_DEBUG("PositionFused: %f, %f,%f,%d.", positionFused.latitude, positionFused.longitude,
  1004 + positionFused.altitude, positionFused.visibleSatelliteNumber);
  1005 + }
  1006 +
  1007 + return positionFused;
  1008 +}
  1009 +
  1010 +gdu_f32_t GduTest_FlightControlGetValueOfRelativeHeight(void)
  1011 +{
  1012 + T_GduReturnCode gduStat;
  1013 + T_GduFcSubscriptionAltitudeFused altitudeFused = 0;
  1014 + T_GduFcSubscriptionAltitudeOfHomePoint homePointAltitude = 0;
  1015 + gdu_f32_t relativeHeight = 0;
  1016 + T_GduDataTimestamp relativeHeightTimestamp = {0};
  1017 +
  1018 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_ALTITUDE_OF_HOMEPOINT,
  1019 + (uint8_t *) &homePointAltitude,
  1020 + sizeof(T_GduFcSubscriptionAltitudeOfHomePoint),
  1021 + &relativeHeightTimestamp);
  1022 +
  1023 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  1024 + USER_LOG_ERROR("Get value of topic altitude of home point error, error code: 0x%08X", gduStat);
  1025 + return -1;
  1026 + } else {
  1027 + USER_LOG_DEBUG("Timestamp: millisecond %u microsecond %u.", relativeHeightTimestamp.millisecond,
  1028 + relativeHeightTimestamp.microsecond);
  1029 + }
  1030 +
  1031 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_ALTITUDE_FUSED,
  1032 + (uint8_t *) &altitudeFused,
  1033 + sizeof(T_GduFcSubscriptionAltitudeFused),
  1034 + &relativeHeightTimestamp);
  1035 +
  1036 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  1037 + USER_LOG_ERROR("Get value of topic altitude fused error, error code: 0x%08X", gduStat);
  1038 + return -1;
  1039 + } else {
  1040 + USER_LOG_DEBUG("Timestamp: millisecond %u microsecond %u.", relativeHeightTimestamp.millisecond,
  1041 + relativeHeightTimestamp.microsecond);
  1042 + }
  1043 +
  1044 + relativeHeight = altitudeFused - homePointAltitude;
  1045 +
  1046 + return relativeHeight;
  1047 +}
  1048 +
  1049 +bool GduTest_FlightControlMotorStartedCheck(void)
  1050 +{
  1051 + int motorsNotStarted = 0;
  1052 + int timeoutCycles = 20;
  1053 +
  1054 + while (GduTest_FlightControlGetValueOfFlightStatus() != GDU_FC_SUBSCRIPTION_FLIGHT_STATUS_ON_GROUND &&
  1055 + GduTest_FlightControlGetValueOfDisplayMode() != GDU_FC_SUBSCRIPTION_DISPLAY_MODE_ENGINE_START &&
  1056 + motorsNotStarted < timeoutCycles) {
  1057 + motorsNotStarted++;
  1058 + s_osalHandler->TaskSleepMs(100);
  1059 + }
  1060 + return motorsNotStarted != timeoutCycles ? true : false;
  1061 +}
  1062 +
  1063 +bool GduTest_FlightControlTakeOffInAirCheck(void)
  1064 +{
  1065 + int stillOnGround = 0;
  1066 + int timeoutCycles = 110;
  1067 +
  1068 + while (GduTest_FlightControlGetValueOfFlightStatus() != GDU_FC_SUBSCRIPTION_FLIGHT_STATUS_IN_AIR &&
  1069 + (GduTest_FlightControlGetValueOfDisplayMode() != GDU_FC_SUBSCRIPTION_DISPLAY_MODE_ASSISTED_TAKEOFF ||
  1070 + GduTest_FlightControlGetValueOfDisplayMode() != GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_TAKEOFF) &&
  1071 + stillOnGround < timeoutCycles) {
  1072 + stillOnGround++;
  1073 + s_osalHandler->TaskSleepMs(100);
  1074 + }
  1075 +
  1076 + return stillOnGround != timeoutCycles ? true : false;
  1077 +}
  1078 +
  1079 +bool takeoffFinishedCheck(void)
  1080 +{
  1081 + while (GduTest_FlightControlGetValueOfDisplayMode() == GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_TAKEOFF ||
  1082 + GduTest_FlightControlGetValueOfDisplayMode() == GDU_FC_SUBSCRIPTION_DISPLAY_MODE_ASSISTED_TAKEOFF) {
  1083 + s_osalHandler->TaskSleepMs(1000);
  1084 + }
  1085 +
  1086 + return (GduTest_FlightControlGetValueOfDisplayMode() == GDU_FC_SUBSCRIPTION_DISPLAY_MODE_P_GPS ||
  1087 + GduTest_FlightControlGetValueOfDisplayMode() == GDU_FC_SUBSCRIPTION_DISPLAY_MODE_ATTITUDE) ? true : false;
  1088 +}
  1089 +
  1090 +bool GduTest_FlightControlLandFinishedCheck(void)
  1091 +{
  1092 + while (GduTest_FlightControlGetValueOfDisplayMode() == GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_LANDING ||
  1093 + GduTest_FlightControlGetValueOfFlightStatus() == GDU_FC_SUBSCRIPTION_FLIGHT_STATUS_IN_AIR) {
  1094 + s_osalHandler->TaskSleepMs(1000);
  1095 + }
  1096 +
  1097 + return (GduTest_FlightControlGetValueOfDisplayMode() != GDU_FC_SUBSCRIPTION_DISPLAY_MODE_P_GPS ||
  1098 + GduTest_FlightControlGetValueOfDisplayMode() != GDU_FC_SUBSCRIPTION_DISPLAY_MODE_ATTITUDE) ? true : false;
  1099 +}
  1100 +
  1101 +bool GduTest_FlightControlCheckActionStarted(E_GduFcSubscriptionDisplayMode mode)
  1102 +{
  1103 + int actionNotStarted = 0;
  1104 + int timeoutCycles = 20;
  1105 +
  1106 + while (GduTest_FlightControlGetValueOfDisplayMode() != mode && actionNotStarted < timeoutCycles) {
  1107 + actionNotStarted++;
  1108 + s_osalHandler->TaskSleepMs(100);
  1109 + }
  1110 +
  1111 + if (actionNotStarted == timeoutCycles) {
  1112 + USER_LOG_ERROR("%s start failed, now flight is in %s.",
  1113 + s_flightControlDisplayModeStr[GduTest_FlightControlGetDisplayModeIndex(mode)].displayModeStr,
  1114 + s_flightControlDisplayModeStr[GduTest_FlightControlGetDisplayModeIndex(
  1115 + GduTest_FlightControlGetValueOfDisplayMode())].displayModeStr);
  1116 + return false;
  1117 + } else {
  1118 + USER_LOG_INFO("Now flight is in %s.",
  1119 + s_flightControlDisplayModeStr[GduTest_FlightControlGetDisplayModeIndex(mode)].displayModeStr);
  1120 + return true;
  1121 + }
  1122 +}
  1123 +
  1124 +bool GduTest_FlightControlMonitoredTakeoff(void)
  1125 +{
  1126 + T_GduReturnCode gduStat;
  1127 +
  1128 + //! Start takeoff
  1129 + gduStat = GduFlightController_StartTakeoff();
  1130 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  1131 + USER_LOG_ERROR("Request to take off failed, error code: 0x%08X", gduStat);
  1132 + return false;
  1133 + }
  1134 +
  1135 + //! Motors start check
  1136 + if (!GduTest_FlightControlMotorStartedCheck()) {
  1137 + USER_LOG_ERROR("Takeoff failed. Motors are not spinning.");
  1138 + return false;
  1139 + } else {
  1140 + USER_LOG_INFO("Motors spinning...");
  1141 + }
  1142 + //! In air check
  1143 + if (!GduTest_FlightControlTakeOffInAirCheck()) {
  1144 + USER_LOG_ERROR("Takeoff failed. Aircraft is still on the ground, but the "
  1145 + "motors are spinning");
  1146 + return false;
  1147 + } else {
  1148 + USER_LOG_INFO("Ascending...");
  1149 + }
  1150 + //! Finished takeoff check
  1151 + if (!takeoffFinishedCheck()) {
  1152 + USER_LOG_ERROR("Takeoff finished, but the aircraft is in an unexpected mode. "
  1153 + "Please connect GDU GO.");
  1154 + return false;
  1155 + }
  1156 +
  1157 + return true;
  1158 +}
  1159 +
  1160 +bool GduTest_FlightControlMonitoredLanding(void)
  1161 +{
  1162 + T_GduReturnCode gduStat;
  1163 + /*! Step 1: Start landing */
  1164 + gduStat = GduFlightController_StartLanding();
  1165 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  1166 + USER_LOG_ERROR("Start landing failed, error code: 0x%08X", gduStat);
  1167 + return false;
  1168 + }
  1169 +
  1170 + /*! Step 2: check Landing start*/
  1171 + if (!GduTest_FlightControlCheckActionStarted(GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_LANDING)) {
  1172 + USER_LOG_ERROR("Fail to execute Landing action!");
  1173 + return false;
  1174 + } else {
  1175 + /*! Step 3: check Landing finished*/
  1176 + if (!GduTest_FlightControlLandFinishedCheck()) {
  1177 + USER_LOG_ERROR("Landing finished, but the aircraft is in an unexpected mode. "
  1178 + "Please connect GDU Assistant.");
  1179 + return false;
  1180 + }
  1181 + }
  1182 +
  1183 + return true;
  1184 +}
  1185 +
  1186 +bool GduTest_FlightControlGoHomeAndConfirmLanding(void)
  1187 +{
  1188 + T_GduReturnCode gduStat;
  1189 +
  1190 + /*! Step 1: Start go home */
  1191 + USER_LOG_INFO("Start go home action");
  1192 + gduStat = GduFlightController_StartGoHome();
  1193 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  1194 + USER_LOG_ERROR("Start to go home failed, error code: 0x%08X", gduStat);
  1195 + return false;;
  1196 + }
  1197 +
  1198 + if (!GduTest_FlightControlCheckActionStarted(GDU_FC_SUBSCRIPTION_DISPLAY_MODE_NAVI_GO_HOME)) {
  1199 + return false;
  1200 + } else {
  1201 + while (GduTest_FlightControlGetValueOfFlightStatus() == GDU_FC_SUBSCRIPTION_FLIGHT_STATUS_IN_AIR &&
  1202 + GduTest_FlightControlGetValueOfDisplayMode() == GDU_FC_SUBSCRIPTION_DISPLAY_MODE_NAVI_GO_HOME) {
  1203 + s_osalHandler->TaskSleepMs(1000);// waiting for this action finished
  1204 + }
  1205 + }
  1206 +
  1207 + /*! Step 2: Start landing */
  1208 + USER_LOG_INFO("Start landing action");
  1209 + if (!GduTest_FlightControlCheckActionStarted(GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_LANDING)) {
  1210 + USER_LOG_ERROR("Fail to execute Landing action");
  1211 + return false;
  1212 + } else {
  1213 + while (GduTest_FlightControlGetValueOfDisplayMode() == GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_LANDING &&
  1214 + GduTest_FlightControlGetValueOfFlightStatus() == GDU_FC_SUBSCRIPTION_FLIGHT_STATUS_IN_AIR) {
  1215 + T_GduFcSubscriptionAvoidData avoidData = GduTest_FlightControlGetValueOfAvoidData();
  1216 + s_osalHandler->TaskSleepMs(1000);
  1217 + if (((gdu_f64_t) 0.65 < avoidData.down && avoidData.down < (gdu_f64_t) 0.75) &&
  1218 + avoidData.downHealth == 1) {
  1219 + break;
  1220 + }
  1221 + }
  1222 + }
  1223 +
  1224 + /*! Step 4: Confirm Landing */
  1225 + USER_LOG_INFO("Start confirm Landing and avoid ground action");
  1226 + gduStat = GduFlightController_StartConfirmLanding();
  1227 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  1228 + USER_LOG_ERROR("Fail to execute confirm landing avoid ground action, error code: 0x%08X", gduStat);
  1229 + return false;
  1230 + }
  1231 +
  1232 + if (!GduTest_FlightControlCheckActionStarted(GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_LANDING)) {
  1233 + return false;
  1234 + } else {
  1235 + while (GduTest_FlightControlGetValueOfFlightStatus() == GDU_FC_SUBSCRIPTION_FLIGHT_STATUS_IN_AIR &&
  1236 + GduTest_FlightControlGetValueOfDisplayMode() == GDU_FC_SUBSCRIPTION_DISPLAY_MODE_AUTO_LANDING) {
  1237 + s_osalHandler->TaskSleepMs(1000);
  1238 + }
  1239 + }
  1240 +
  1241 + /*! Step 5: Landing finished check*/
  1242 + if (GduTest_FlightControlGetValueOfDisplayMode() != GDU_FC_SUBSCRIPTION_DISPLAY_MODE_P_GPS ||
  1243 + GduTest_FlightControlGetValueOfDisplayMode() != GDU_FC_SUBSCRIPTION_DISPLAY_MODE_ATTITUDE) {
  1244 + USER_LOG_INFO("Successful landing");
  1245 + } else {
  1246 + USER_LOG_ERROR("Landing finished, but the aircraft is in an unexpected mode. "
  1247 + "Please connect GDU Assistant.");
  1248 + return false;
  1249 + }
  1250 +
  1251 + return true;
  1252 +}
  1253 +
  1254 +T_GduTestFlightControlVector3f GduTest_FlightControlQuaternionToEulerAngle(const T_GduFcSubscriptionQuaternion quat)
  1255 +{
  1256 + T_GduTestFlightControlVector3f eulerAngle;
  1257 + double q2sqr = quat.q2 * quat.q2;
  1258 + double t0 = -2.0 * (q2sqr + quat.q3 * quat.q3) + 1.0;
  1259 + double t1 = (gdu_f64_t) 2.0 * (quat.q1 * quat.q2 + quat.q0 * quat.q3);
  1260 + double t2 = -2.0 * (quat.q1 * quat.q3 - quat.q0 * quat.q2);
  1261 + double t3 = (gdu_f64_t) 2.0 * (quat.q2 * quat.q3 + quat.q0 * quat.q1);
  1262 + double t4 = -2.0 * (quat.q1 * quat.q1 + q2sqr) + 1.0;
  1263 + t2 = (t2 > 1.0) ? 1.0 : t2;
  1264 + t2 = (t2 < -1.0) ? -1.0 : t2;
  1265 + eulerAngle.x = asin(t2);
  1266 + eulerAngle.y = atan2(t3, t4);
  1267 + eulerAngle.z = atan2(t1, t0);
  1268 + return eulerAngle;
  1269 +}
  1270 +
  1271 +T_GduTestFlightControlVector3f
  1272 +GduTest_FlightControlLocalOffsetFromGpsAndFusedHeightOffset(const T_GduFcSubscriptionPositionFused target,
  1273 + const T_GduFcSubscriptionPositionFused origin,
  1274 + const gdu_f32_t targetHeight,
  1275 + const gdu_f32_t originHeight)
  1276 +{
  1277 + T_GduTestFlightControlVector3f deltaNed;
  1278 + double deltaLon = target.longitude - origin.longitude;
  1279 + double deltaLat = target.latitude - origin.latitude;
  1280 + deltaNed.x = deltaLat * s_earthCenter;
  1281 + deltaNed.y = deltaLon * s_earthCenter * cos(target.latitude);
  1282 + deltaNed.z = targetHeight - originHeight;
  1283 +
  1284 + return deltaNed;
  1285 +}
  1286 +
  1287 +T_GduTestFlightControlVector3f
  1288 +GduTest_FlightControlVector3FSub(const T_GduTestFlightControlVector3f vectorA,
  1289 + const T_GduTestFlightControlVector3f vectorB)
  1290 +{
  1291 + T_GduTestFlightControlVector3f result;
  1292 + result.x = vectorA.x - vectorB.x;
  1293 + result.y = vectorA.y - vectorB.y;
  1294 + result.z = vectorA.z - vectorB.z;
  1295 + return result;
  1296 +}
  1297 +
  1298 +int GduTest_FlightControlSignOfData(gdu_f32_t data)
  1299 +{
  1300 + return data < 0 ? -1 : 1;
  1301 +}
  1302 +
  1303 +void GduTest_FlightControlHorizCommandLimit(gdu_f32_t speedFactor, gdu_f32_t *commandX, gdu_f32_t *commandY)
  1304 +{
  1305 + if (fabs(*commandX) > speedFactor)
  1306 + *commandX = speedFactor * GduTest_FlightControlSignOfData(*commandX);
  1307 + if (fabs(*commandY) > speedFactor)
  1308 + *commandY = speedFactor * GduTest_FlightControlSignOfData(*commandY);
  1309 +}
  1310 +
  1311 +gdu_f32_t GduTest_FlightControlVectorNorm(T_GduTestFlightControlVector3f v)
  1312 +{
  1313 + return sqrt(pow(v.x, 2) + pow(v.y, 2) + pow(v.z, 2));
  1314 +}
  1315 +
  1316 +bool
  1317 +GduTest_FlightControlMoveByPositionOffset(const T_GduTestFlightControlVector3f offsetDesired, float yawDesiredInDeg,
  1318 + float posThresholdInM, float yawThresholdInDeg)
  1319 +{
  1320 + int timeoutInMilSec = 20000;
  1321 + int controlFreqInHz = 50; // Hz
  1322 + int cycleTimeInMs = 1000 / controlFreqInHz;
  1323 + int outOfControlBoundsTimeLimit = 10 * cycleTimeInMs; // 10 cycles
  1324 + int withinControlBoundsTimeReqmt = 100 * cycleTimeInMs; // 100 cycles
  1325 + int elapsedTimeInMs = 0;
  1326 + int withinBoundsCounter = 0;
  1327 + int outOfBounds = 0;
  1328 + int brakeCounter = 0;
  1329 + int speedFactor = 2;
  1330 +
  1331 + //! get origin position and relative height(from home point)of aircraft.
  1332 + T_GduFcSubscriptionPositionFused originGPSPosition = GduTest_FlightControlGetValueOfPositionFused();
  1333 + gdu_f32_t originHeightBaseHomePoint = GduTest_FlightControlGetValueOfRelativeHeight();
  1334 + if (originHeightBaseHomePoint == -1) {
  1335 + USER_LOG_ERROR("Relative height is invalid!");
  1336 + return false;
  1337 + }
  1338 +
  1339 + T_GduFlightControllerJoystickMode joystickMode = {
  1340 + GDU_FLIGHT_CONTROLLER_HORIZONTAL_POSITION_CONTROL_MODE,
  1341 + GDU_FLIGHT_CONTROLLER_VERTICAL_POSITION_CONTROL_MODE,
  1342 + GDU_FLIGHT_CONTROLLER_YAW_ANGLE_CONTROL_MODE,
  1343 + GDU_FLIGHT_CONTROLLER_HORIZONTAL_GROUND_COORDINATE,
  1344 + GDU_FLIGHT_CONTROLLER_STABLE_CONTROL_MODE_ENABLE,
  1345 + };
  1346 + GduFlightController_SetJoystickMode(joystickMode);
  1347 +
  1348 + while (elapsedTimeInMs < timeoutInMilSec) {
  1349 + T_GduFcSubscriptionPositionFused currentGPSPosition = GduTest_FlightControlGetValueOfPositionFused();
  1350 + T_GduFcSubscriptionQuaternion currentQuaternion = GduTest_FlightControlGetValueOfQuaternion();
  1351 + gdu_f32_t currentHeight = GduTest_FlightControlGetValueOfRelativeHeight();
  1352 + if (originHeightBaseHomePoint == -1) {
  1353 + USER_LOG_ERROR("Relative height is invalid!");
  1354 + return false;
  1355 + }
  1356 +
  1357 + float yawInRad = GduTest_FlightControlQuaternionToEulerAngle(currentQuaternion).z;
  1358 + //! get the vector between aircraft and origin point.
  1359 +
  1360 + T_GduTestFlightControlVector3f localOffset = GduTest_FlightControlLocalOffsetFromGpsAndFusedHeightOffset(
  1361 + currentGPSPosition,
  1362 + originGPSPosition,
  1363 + currentHeight,
  1364 + originHeightBaseHomePoint);
  1365 + //! get the vector between aircraft and target point.
  1366 + T_GduTestFlightControlVector3f offsetRemaining = GduTest_FlightControlVector3FSub(offsetDesired, localOffset);
  1367 +
  1368 + T_GduTestFlightControlVector3f positionCommand = offsetRemaining;
  1369 + GduTest_FlightControlHorizCommandLimit(speedFactor, &positionCommand.x, &positionCommand.y);
  1370 +
  1371 + T_GduFlightControllerJoystickCommand joystickCommand = {positionCommand.x, positionCommand.y,
  1372 + offsetDesired.z + originHeightBaseHomePoint,
  1373 + yawDesiredInDeg};
  1374 + GduFlightController_ExecuteJoystickAction(joystickCommand);
  1375 +
  1376 + if (GduTest_FlightControlVectorNorm(offsetRemaining) < posThresholdInM &&
  1377 + fabs(yawInRad / s_degToRad - yawDesiredInDeg) < yawThresholdInDeg) {
  1378 + //! 1. We are within bounds; start incrementing our in-bound counter
  1379 + withinBoundsCounter += cycleTimeInMs;
  1380 + } else {
  1381 + if (withinBoundsCounter != 0) {
  1382 + //! 2. Start incrementing an out-of-bounds counter
  1383 + outOfBounds += cycleTimeInMs;
  1384 + }
  1385 + }
  1386 + //! 3. Reset withinBoundsCounter if necessary
  1387 + if (outOfBounds > outOfControlBoundsTimeLimit) {
  1388 + withinBoundsCounter = 0;
  1389 + outOfBounds = 0;
  1390 + }
  1391 + //! 4. If within bounds, set flag and break
  1392 + if (withinBoundsCounter >= withinControlBoundsTimeReqmt) {
  1393 + break;
  1394 + }
  1395 + s_osalHandler->TaskSleepMs(cycleTimeInMs);
  1396 + elapsedTimeInMs += cycleTimeInMs;
  1397 + }
  1398 +
  1399 + while (brakeCounter < withinControlBoundsTimeReqmt) {
  1400 + s_osalHandler->TaskSleepMs(cycleTimeInMs);
  1401 + brakeCounter += cycleTimeInMs;
  1402 + }
  1403 +
  1404 + if (elapsedTimeInMs >= timeoutInMilSec) {
  1405 + USER_LOG_ERROR("Task timeout!");
  1406 + return false;
  1407 + }
  1408 +
  1409 + return true;
  1410 +}
  1411 +
  1412 +void GduTest_FlightControlVelocityAndYawRateCtrl(const T_GduTestFlightControlVector3f offsetDesired, float yawRate,
  1413 + uint32_t timeMs)
  1414 +{
  1415 + uint32_t originTime = 0;
  1416 + uint32_t currentTime = 0;
  1417 + uint32_t elapsedTimeInMs = 0;
  1418 + s_osalHandler->GetTimeMs(&originTime);
  1419 + s_osalHandler->GetTimeMs(&currentTime);
  1420 + elapsedTimeInMs = currentTime - originTime;
  1421 + T_GduFlightControllerJoystickMode joystickMode = {
  1422 + GDU_FLIGHT_CONTROLLER_HORIZONTAL_VELOCITY_CONTROL_MODE,
  1423 + GDU_FLIGHT_CONTROLLER_VERTICAL_VELOCITY_CONTROL_MODE,
  1424 + GDU_FLIGHT_CONTROLLER_YAW_ANGLE_RATE_CONTROL_MODE,
  1425 + GDU_FLIGHT_CONTROLLER_HORIZONTAL_GROUND_COORDINATE,
  1426 + GDU_FLIGHT_CONTROLLER_STABLE_CONTROL_MODE_ENABLE,
  1427 + };
  1428 +
  1429 + GduFlightController_SetJoystickMode(joystickMode);
  1430 + T_GduFlightControllerJoystickCommand joystickCommand = {offsetDesired.x, offsetDesired.y, offsetDesired.z,
  1431 + yawRate};
  1432 +
  1433 + while (elapsedTimeInMs <= timeMs) {
  1434 + GduFlightController_ExecuteJoystickAction(joystickCommand);
  1435 + s_osalHandler->TaskSleepMs(2);
  1436 + s_osalHandler->GetTimeMs(&currentTime);
  1437 + elapsedTimeInMs = currentTime - originTime;
  1438 + }
  1439 +}
  1440 +
  1441 +T_GduReturnCode
  1442 +GduTest_FlightControlJoystickCtrlAuthSwitchEventCallback(T_GduFlightControllerJoystickCtrlAuthorityEventInfo eventData)
  1443 +{
  1444 + switch (eventData.joystickCtrlAuthoritySwitchEvent) {
  1445 + case GDU_FLIGHT_CONTROLLER_MSDK_GET_JOYSTICK_CTRL_AUTH_EVENT: {
  1446 + if (eventData.curJoystickCtrlAuthority == GDU_FLIGHT_CONTROLLER_JOYSTICK_CTRL_AUTHORITY_MSDK) {
  1447 + USER_LOG_INFO("[Event]Msdk request to obtain joystick ctrl authority\r\n");
  1448 + } else {
  1449 + USER_LOG_INFO("[Event]Msdk request to release joystick ctrl authority\r\n");
  1450 + }
  1451 + break;
  1452 + }
  1453 + case GDU_FLIGHT_CONTROLLER_INTERNAL_GET_JOYSTICK_CTRL_AUTH_EVENT: {
  1454 + if (eventData.curJoystickCtrlAuthority == GDU_FLIGHT_CONTROLLER_JOYSTICK_CTRL_AUTHORITY_INTERNAL) {
  1455 + USER_LOG_INFO("[Event]Internal request to obtain joystick ctrl authority\r\n");
  1456 + } else {
  1457 + USER_LOG_INFO("[Event]Internal request to release joystick ctrl authority\r\n");
  1458 + }
  1459 + break;
  1460 + }
  1461 + case GDU_FLIGHT_CONTROLLER_OSDK_GET_JOYSTICK_CTRL_AUTH_EVENT: {
  1462 + if (eventData.curJoystickCtrlAuthority == GDU_FLIGHT_CONTROLLER_JOYSTICK_CTRL_AUTHORITY_OSDK) {
  1463 + USER_LOG_INFO("[Event]Osdk request to obtain joystick ctrl authority\r\n");
  1464 + } else {
  1465 + USER_LOG_INFO("[Event]Osdk request to release joystick ctrl authority\r\n");
  1466 + }
  1467 + break;
  1468 + }
  1469 + case GDU_FLIGHT_CONTROLLER_RC_LOST_GET_JOYSTICK_CTRL_AUTH_EVENT :
  1470 + USER_LOG_INFO("[Event]Current joystick ctrl authority is reset to rc due to rc lost\r\n");
  1471 + break;
  1472 + case GDU_FLIGHT_CONTROLLER_RC_NOT_P_MODE_RESET_JOYSTICK_CTRL_AUTH_EVENT :
  1473 + USER_LOG_INFO("[Event]Current joystick ctrl authority is reset to rc for rc is not in P mode\r\n");
  1474 + break;
  1475 + case GDU_FLIGHT_CONTROLLER_RC_SWITCH_MODE_GET_JOYSTICK_CTRL_AUTH_EVENT :
  1476 + USER_LOG_INFO("[Event]Current joystick ctrl authority is reset to rc due to rc switching mode\r\n");
  1477 + break;
  1478 + case GDU_FLIGHT_CONTROLLER_RC_PAUSE_GET_JOYSTICK_CTRL_AUTH_EVENT :
  1479 + USER_LOG_INFO("[Event]Current joystick ctrl authority is reset to rc due to rc pausing\r\n");
  1480 + break;
  1481 + case GDU_FLIGHT_CONTROLLER_RC_REQUEST_GO_HOME_GET_JOYSTICK_CTRL_AUTH_EVENT :
  1482 + USER_LOG_INFO("[Event]Current joystick ctrl authority is reset to rc due to rc request for return\r\n");
  1483 + break;
  1484 + case GDU_FLIGHT_CONTROLLER_LOW_BATTERY_GO_HOME_RESET_JOYSTICK_CTRL_AUTH_EVENT :
  1485 + USER_LOG_INFO("[Event]Current joystick ctrl authority is reset to rc for low battery return\r\n");
  1486 + break;
  1487 + case GDU_FLIGHT_CONTROLLER_LOW_BATTERY_LANDING_RESET_JOYSTICK_CTRL_AUTH_EVENT :
  1488 + USER_LOG_INFO("[Event]Current joystick ctrl authority is reset to rc for low battery land\r\n");
  1489 + break;
  1490 + case GDU_FLIGHT_CONTROLLER_OSDK_LOST_GET_JOYSTICK_CTRL_AUTH_EVENT:
  1491 + USER_LOG_INFO("[Event]Current joystick ctrl authority is reset to rc due to osdk lost\r\n");
  1492 + break;
  1493 + case GDU_FLIGHT_CONTROLLER_NERA_FLIGHT_BOUNDARY_RESET_JOYSTICK_CTRL_AUTH_EVENT :
  1494 + USER_LOG_INFO("[Event]Current joystick ctrl authority is reset to rc due to near boundary\r\n");
  1495 + break;
  1496 + default:
  1497 + USER_LOG_INFO("[Event]Unknown joystick ctrl authority event\r\n");
  1498 + }
  1499 +
  1500 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  1501 +}
  1502 +
  1503 +/****************** (C) COPYRIGHT GDU Innovations *****END OF FILE****/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_flight_control.h
  4 + * @brief This is the header file for "test_flight_control.c", defining the structure and
  5 + * (exported) function prototypes.
  6 + *
  7 + * @copyright (c) 2021 GDU. All rights reserved.
  8 + *
  9 + * All information contained herein is, and remains, the property of GDU.
  10 + * The intellectual and technical concepts contained herein are proprietary
  11 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  12 + * and protected by trade secret or copyright law. Dissemination of this
  13 + * information, including but not limited to data and other proprietary
  14 + * material(s) incorporated within the information, in any form, is strictly
  15 + * prohibited without the express written consent of GDU.
  16 + *
  17 + * If you receive this source code without GDU’s authorization, you may not
  18 + * further disseminate the information, and you must immediately remove the
  19 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  20 + * legal actions against you for any loss(es) or damage(s) caused by your
  21 + * failure to do so.
  22 + *
  23 + *********************************************************************
  24 + */
  25 +
  26 +/* Define to prevent recursive inclusion -------------------------------------*/
  27 +#ifndef TEST_FLIGHT_CONTROL_H
  28 +#define TEST_FLIGHT_CONTROL_H
  29 +
  30 +/* Includes ------------------------------------------------------------------*/
  31 +#include "gdu_typedef.h"
  32 +
  33 +#ifdef __cplusplus
  34 +extern "C" {
  35 +#endif
  36 +
  37 +/* Exported constants --------------------------------------------------------*/
  38 +typedef enum {
  39 + E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_TAKE_OFF_LANDING,
  40 + E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_TAKE_OFF_POSITION_CTRL_LANDING,
  41 + E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_TAKE_OFF_GO_HOME_FORCE_LANDING,
  42 + E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_TAKE_OFF_VELOCITY_CTRL_LANDING,
  43 + E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_ARREST_FLYING,
  44 + E_GDU_TEST_FLIGHT_CTRL_SAMPLE_SELECT_SET_GET_PARAM,
  45 +} E_GduTestFlightCtrlSampleSelect;
  46 +
  47 +/* Exported types ------------------------------------------------------------*/
  48 +
  49 +/* Exported functions --------------------------------------------------------*/
  50 +T_GduReturnCode GduTest_FlightControlRunSample(E_GduTestFlightCtrlSampleSelect flightCtrlSampleSelect);
  51 +
  52 +#ifdef __cplusplus
  53 +}
  54 +#endif
  55 +
  56 +#endif // TEST_FLIGHT_CONTROL_H
  57 +/************************ (C) COPYRIGHT GDU Innovations *******END OF FILE******/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_payload_gimbal_emu.c
  4 + * @brief
  5 + *
  6 + * @copyright (c) 2021 GDU. All rights reserved.
  7 + *
  8 + * All information contained herein is, and remains, the property of GDU.
  9 + * The intellectual and technical concepts contained herein are proprietary
  10 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  11 + * and protected by trade secret or copyright law. Dissemination of this
  12 + * information, including but not limited to data and other proprietary
  13 + * material(s) incorporated within the information, in any form, is strictly
  14 + * prohibited without the express written consent of GDU.
  15 + *
  16 + * If you receive this source code without GDU’s authorization, you may not
  17 + * further disseminate the information, and you must immediately remove the
  18 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  19 + * legal actions against you for any loss(es) or damage(s) caused by your
  20 + * failure to do so.
  21 + *
  22 + *********************************************************************
  23 + */
  24 +
  25 +/* Includes ------------------------------------------------------------------*/
  26 +#include "math.h"
  27 +#include <gdu_gimbal.h>
  28 +#include "test_payload_gimbal_emu.h"
  29 +//#include "gdu_fc_subscription.h"
  30 +#include "gdu_logger.h"
  31 +#include "gdu_platform.h"
  32 +#include "utils/util_misc.h"
  33 +
  34 +/* Private constants ---------------------------------------------------------*/
  35 +#define PAYLOAD_GIMBAL_EMU_TASK_STACK_SIZE (2048)
  36 +#define PAYLOAD_GIMBAL_TASK_FREQ 1000
  37 +#define PAYLOAD_GIMBAL_CALIBRATION_TIME_MS 2000
  38 +
  39 +/* Private types -------------------------------------------------------------*/
  40 +typedef enum {
  41 + TEST_GIMBAL_CONTROL_TYPE_UNKNOWN = 0,
  42 + TEST_GIMBAL_CONTROL_TYPE_SPEED = 1,
  43 + TEST_GIMBAL_CONTROL_TYPE_ANGLE = 2,
  44 +} E_TestGimbalControlType;
  45 +
  46 +/* Private functions declaration ---------------------------------------------*/
  47 +static void *UserGimbal_Task(void *arg);
  48 +static T_GduReturnCode GetSystemState(T_GduGimbalSystemState *systemState);
  49 +static T_GduReturnCode GetAttitudeInformation(T_GduGimbalAttitudeInformation *attitudeInformation);
  50 +static T_GduReturnCode GetCalibrationState(T_GduGimbalCalibrationState *calibrationState);
  51 +static T_GduReturnCode GetRotationSpeed(T_GduAttitude3d *rotationSpeed);
  52 +static T_GduReturnCode GetJointAngle(T_GduAttitude3d *jointAngle);
  53 +static T_GduReturnCode StartCalibrate(void);
  54 +static T_GduReturnCode SetControllerSmoothFactor(uint8_t smoothingFactor, E_GduGimbalAxis axis);
  55 +static T_GduReturnCode SetPitchRangeExtensionEnabled(bool enabledFlag);
  56 +static T_GduReturnCode SetControllerMaxSpeedPercentage(uint8_t maxSpeedPercentage, E_GduGimbalAxis axis);
  57 +static T_GduReturnCode RestoreFactorySettings(void);
  58 +static T_GduReturnCode SetMode(E_GduGimbalMode mode);
  59 +static T_GduReturnCode Reset(E_GduGimbalResetMode mode);
  60 +static T_GduReturnCode FineTuneAngle(T_GduAttitude3d fineTuneAngle);
  61 +static T_GduReturnCode GduTest_GimbalAngleLegalization(T_GduAttitude3f *attitude, T_GduAttitude3d aircraftAttitude,
  62 + T_GduGimbalReachLimitFlag *reachLimitFlag);
  63 +static T_GduReturnCode
  64 +GduTest_GimbalCalculateSpeed(T_GduAttitude3d originalAttitude, T_GduAttitude3d targetAttitude, uint16_t actionTime,
  65 + T_GduAttitude3d *speed);
  66 +static void GduTest_GimbalSpeedLegalization(T_GduAttitude3d *speed);
  67 +//static T_GduReturnCode GduTest_GimbalCalculateGroundAttitudeBaseQuaternion(T_GduFcSubscriptionQuaternion quaternion,
  68 +// T_GduAttitude3d *attitude);
  69 +
  70 +/* Private variables ---------------------------------------------------------*/
  71 +static T_GduTaskHandle s_userGimbalThread;
  72 +static T_GduGimbalCommonHandler s_commonHandler = {0};
  73 +static T_GduGimbalSystemState s_systemState = {0};
  74 +static bool s_rotatingFlag = false;
  75 +static T_GduMutexHandle s_commonMutex = {0};
  76 +
  77 +static T_GduGimbalAttitudeInformation s_attitudeInformation = {0}; // unit: 0.1 degree, ground coordination
  78 +static T_GduAttitude3f s_attitudeHighPrecision = {0}; // unit: 0.1 degree, ground coordination
  79 +static T_GduGimbalCalibrationState s_calibrationState = {0};
  80 +static T_GduAttitude3d s_targetAttitude = {0}; // unit: 0.1 degree, ground coordination
  81 +static T_GduAttitude3d s_speed = {0}; // unit: 0.1 degree/s, ground coordination
  82 +static T_GduAttitude3d s_aircraftAttitude = {0}; // unit: 0.1 degree, ground coordination
  83 +static T_GduAttitude3d s_lastAircraftAttitude = {0}; // unit: 0.1 degree, ground coordination
  84 +static E_TestGimbalControlType s_controlType = TEST_GIMBAL_CONTROL_TYPE_UNKNOWN;
  85 +static const T_GduAttitude3d s_jointAngleLimitMin = {-1200, -100, -1800}; // unit: 0.1 degree
  86 +static const T_GduAttitude3d s_jointAngleLimitMax = {300, 100, 1800}; // unit: 0.1 degree
  87 +static const T_GduAttitude3d s_eulerAngleLimitMin = {-900, -100, -1800}; // unit: 0.1 degree
  88 +static const T_GduAttitude3d s_eulerAngleLimitMax = {100, 100, 1800}; // unit: 0.1 degree
  89 +static const int32_t s_pitchEulerAngleExtensionMin = -1200; // unit: 0.1 degree
  90 +static const int32_t s_pitchEulerAngleExtensionMax = 300; // unit: 0.1 degree
  91 +static const T_GduAttitude3d s_speedLimit = {1800, 1800, 1800}; // unit: 0.1 degree/s
  92 +static uint32_t s_calibrationStartTime = 0; // unit: ms
  93 +static T_GduMutexHandle s_attitudeMutex = NULL;
  94 +static T_GduMutexHandle s_calibrationMutex = NULL;
  95 +
  96 +/* Exported functions definition ---------------------------------------------*/
  97 +/**
  98 + * @brief
  99 + * @note Gimbal sample rely on aircraft quaternion.
  100 + * @return
  101 + */
  102 +T_GduReturnCode GduTest_GimbalStartService(void)
  103 +{
  104 + T_GduReturnCode gduStat;
  105 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  106 +
  107 + s_systemState.resettingFlag = false;
  108 + s_systemState.mountedUpward = false;
  109 + s_systemState.blockingFlag = false;
  110 + s_systemState.pitchRangeExtensionEnabledFlag = false;
  111 +
  112 + s_calibrationState.calibratingFlag = false;
  113 + s_calibrationState.lastCalibrationResult = true;
  114 +
  115 + s_commonHandler.GetSystemState = GetSystemState;//
  116 + s_commonHandler.GetAttitudeInformation = GetAttitudeInformation;//获取云台姿态信息
  117 + s_commonHandler.GetCalibrationState = GetCalibrationState;//获取校准状态
  118 + s_commonHandler.GetRotationSpeed = GetRotationSpeed;//获取云台转动速度
  119 + s_commonHandler.GetJointAngle = GetJointAngle;//获取云台关节角度
  120 + s_commonHandler.Rotate = GduTest_GimbalRotate;//控制云台转动
  121 + s_commonHandler.StartCalibrate = StartCalibrate;//启动校准
  122 + s_commonHandler.SetControllerSmoothFactor = SetControllerSmoothFactor;//设置控制器平滑因子
  123 + s_commonHandler.SetPitchRangeExtensionEnabled = SetPitchRangeExtensionEnabled;//范围扩展启动,设置俯仰范围***
  124 + s_commonHandler.SetControllerMaxSpeedPercentage = SetControllerMaxSpeedPercentage; //设置最大速度控制百分比
  125 + s_commonHandler.RestoreFactorySettings = RestoreFactorySettings;//恢复出厂设置
  126 + s_commonHandler.SetMode = SetMode;
  127 + s_commonHandler.Reset = Reset;
  128 + s_commonHandler.FineTuneAngle = FineTuneAngle;//姿态微调角度
  129 +
  130 + if (osalHandler->MutexCreate(&s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  131 + USER_LOG_ERROR("mutex create error");
  132 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  133 + }
  134 +
  135 + if (osalHandler->MutexCreate(&s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  136 + USER_LOG_ERROR("mutex create error");
  137 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  138 + }
  139 +
  140 + if (osalHandler->MutexCreate(&s_calibrationMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  141 + USER_LOG_ERROR("mutex create error");
  142 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  143 + }
  144 +
  145 + gduStat = GduGimbal_RegCommonHandler(&s_commonHandler);
  146 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  147 + USER_LOG_ERROR("gimbal register common handler error: 0x%08llX", gduStat);
  148 + }
  149 +
  150 + gduStat = GduGimbal_Init();
  151 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  152 + USER_LOG_ERROR("init gimbal module error: 0x%08llX", gduStat);
  153 + }
  154 +
  155 + if (osalHandler->TaskCreate("user_gimbal_task", UserGimbal_Task,
  156 + PAYLOAD_GIMBAL_EMU_TASK_STACK_SIZE, NULL, &s_userGimbalThread) !=
  157 + GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  158 + USER_LOG_ERROR("user gimbal task create error");
  159 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  160 + }
  161 +
  162 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  163 +}
  164 +
  165 +T_GduReturnCode GduTest_GimbalDeInit(void)
  166 +{
  167 + T_GduReturnCode gduStat;
  168 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  169 +
  170 + gduStat = osalHandler->TaskDestroy(s_userGimbalThread);
  171 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  172 + USER_LOG_ERROR("Destroy test gimbal thread error: 0x%08llX.", gduStat);
  173 + return gduStat;
  174 + }
  175 +
  176 + gduStat = GduGimbal_DeInit();
  177 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  178 + USER_LOG_ERROR("Deinit gimbal module error: 0x%08llX.", gduStat);
  179 + return gduStat;
  180 + }
  181 +
  182 + if (osalHandler->MutexDestroy(s_calibrationMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  183 + USER_LOG_ERROR("mutex destroy error");
  184 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  185 + }
  186 +
  187 + if (osalHandler->MutexDestroy(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  188 + USER_LOG_ERROR("mutex destroy error");
  189 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  190 + }
  191 +
  192 + if (osalHandler->MutexDestroy(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  193 + USER_LOG_ERROR("mutex destroy error");
  194 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  195 + }
  196 +
  197 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  198 +}
  199 +
  200 +T_GduReturnCode GduTest_GimbalRotate(E_GduGimbalRotationMode rotationMode,
  201 + T_GduGimbalRotationProperty rotationProperty,
  202 + T_GduAttitude3d rotationValue)
  203 +{
  204 + T_GduReturnCode gduStat;
  205 + T_GduReturnCode returnCode = GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  206 + T_GduAttitude3d targetAttitudeDTemp = {0};
  207 + T_GduAttitude3f targetAttitudeFTemp = {0};
  208 + T_GduAttitude3d speedTemp = {0};
  209 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  210 +
  211 +// USER_LOG_DEBUG("gimbal rotation value invalid flag: pitch %d, roll %d, yaw %d.",
  212 +// rotationProperty.rotationValueInvalidFlag.pitch,
  213 +// rotationProperty.rotationValueInvalidFlag.roll,
  214 +// rotationProperty.rotationValueInvalidFlag.yaw);
  215 +
  216 + if (osalHandler->MutexLock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  217 + USER_LOG_ERROR("mutex lock error");
  218 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  219 + }
  220 +
  221 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  222 + USER_LOG_ERROR("mutex lock error");
  223 + returnCode = GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  224 + goto out2;
  225 + }
  226 +
  227 + switch (rotationMode) {
  228 + case GDU_GIMBAL_ROTATION_MODE_RELATIVE_ANGLE:
  229 + USER_LOG_INFO("gimbal relative rotate angle: pitch %d, roll %d, yaw %d.", rotationValue.pitch,
  230 + rotationValue.roll, rotationValue.yaw);
  231 + USER_LOG_DEBUG("gimbal relative rotate action time: %d.",
  232 + rotationProperty.relativeAngleRotation.actionTime);
  233 +
  234 + if (s_rotatingFlag == true) {
  235 + USER_LOG_WARN("gimbal is rotating.");
  236 + goto out1;
  237 + }
  238 +
  239 + targetAttitudeDTemp.pitch =
  240 + rotationProperty.rotationValueInvalidFlag.pitch == true ? s_attitudeInformation.attitude.pitch : (
  241 + s_attitudeInformation.attitude.pitch + rotationValue.pitch);
  242 + targetAttitudeDTemp.roll =
  243 + rotationProperty.rotationValueInvalidFlag.roll == true ? s_attitudeInformation.attitude.roll : (
  244 + s_attitudeInformation.attitude.roll + rotationValue.roll);
  245 + targetAttitudeDTemp.yaw =
  246 + rotationProperty.rotationValueInvalidFlag.yaw == true ? s_attitudeInformation.attitude.yaw : (
  247 + s_attitudeInformation.attitude.yaw + rotationValue.yaw);
  248 +
  249 + targetAttitudeFTemp.pitch = targetAttitudeDTemp.pitch;
  250 + targetAttitudeFTemp.roll = targetAttitudeDTemp.roll;
  251 + targetAttitudeFTemp.yaw = targetAttitudeDTemp.yaw;
  252 + GduTest_GimbalAngleLegalization(&targetAttitudeFTemp, s_aircraftAttitude, NULL);
  253 + targetAttitudeDTemp.pitch = targetAttitudeFTemp.pitch;
  254 + targetAttitudeDTemp.roll = targetAttitudeFTemp.roll;
  255 + targetAttitudeDTemp.yaw = targetAttitudeFTemp.yaw;
  256 +
  257 + s_targetAttitude = targetAttitudeDTemp;
  258 + s_rotatingFlag = true;
  259 + s_controlType = TEST_GIMBAL_CONTROL_TYPE_ANGLE;
  260 +
  261 + gduStat = GduTest_GimbalCalculateSpeed(s_attitudeInformation.attitude, s_targetAttitude,
  262 + rotationProperty.relativeAngleRotation.actionTime, &s_speed);
  263 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  264 + USER_LOG_ERROR("calculate gimbal rotation speed error: 0x%08llX.", gduStat);
  265 + returnCode = gduStat;
  266 + goto out1;
  267 + }
  268 +
  269 + break;
  270 + case GDU_GIMBAL_ROTATION_MODE_ABSOLUTE_ANGLE:
  271 + USER_LOG_INFO("gimbal absolute rotate angle: pitch %d, roll %d, yaw %d.", rotationValue.pitch,
  272 + rotationValue.roll, rotationValue.yaw);
  273 + USER_LOG_DEBUG("gimbal absolute rotate action time: %d.",
  274 + rotationProperty.absoluteAngleRotation.actionTime);
  275 + if (rotationProperty.absoluteAngleRotation.jointAngleValid) {
  276 + USER_LOG_DEBUG("gimbal joint angles: pitch %d, roll %d, yaw %d.",
  277 + rotationProperty.absoluteAngleRotation.jointAngle.pitch,
  278 + rotationProperty.absoluteAngleRotation.jointAngle.roll,
  279 + rotationProperty.absoluteAngleRotation.jointAngle.yaw);
  280 + }
  281 +
  282 + if (s_rotatingFlag == true) {
  283 + USER_LOG_WARN("gimbal is rotating.");
  284 + goto out1;
  285 + }
  286 +
  287 + targetAttitudeDTemp.pitch =
  288 + rotationProperty.rotationValueInvalidFlag.pitch == true ? s_attitudeInformation.attitude.pitch
  289 + : rotationValue.pitch;
  290 + targetAttitudeDTemp.roll =
  291 + rotationProperty.rotationValueInvalidFlag.roll == true ? s_attitudeInformation.attitude.roll
  292 + : rotationValue.roll;
  293 + targetAttitudeDTemp.yaw =
  294 + rotationProperty.rotationValueInvalidFlag.yaw == true ? s_attitudeInformation.attitude.yaw
  295 + : rotationValue.yaw;
  296 +
  297 + targetAttitudeFTemp.pitch = targetAttitudeDTemp.pitch;
  298 + targetAttitudeFTemp.roll = targetAttitudeDTemp.roll;
  299 + targetAttitudeFTemp.yaw = targetAttitudeDTemp.yaw;
  300 + GduTest_GimbalAngleLegalization(&targetAttitudeFTemp, s_aircraftAttitude, NULL);
  301 + targetAttitudeDTemp.pitch = targetAttitudeFTemp.pitch;
  302 + targetAttitudeDTemp.roll = targetAttitudeFTemp.roll;
  303 + targetAttitudeDTemp.yaw = targetAttitudeFTemp.yaw;
  304 +
  305 + s_targetAttitude = targetAttitudeDTemp;
  306 + s_rotatingFlag = true;
  307 + s_controlType = TEST_GIMBAL_CONTROL_TYPE_ANGLE;
  308 +
  309 + gduStat = GduTest_GimbalCalculateSpeed(s_attitudeInformation.attitude, s_targetAttitude,
  310 + rotationProperty.absoluteAngleRotation.actionTime, &s_speed);
  311 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  312 + USER_LOG_ERROR("calculate gimbal rotation speed error: 0x%08llX.", gduStat);
  313 + returnCode = gduStat;
  314 + goto out1;
  315 + }
  316 +
  317 + break;
  318 + case GDU_GIMBAL_ROTATION_MODE_SPEED:
  319 +// USER_LOG_INFO("gimbal rotate speed: pitch %d, roll %d, yaw %d.", rotationValue.pitch,
  320 +// rotationValue.roll, rotationValue.yaw);
  321 +
  322 + if (s_rotatingFlag == true && s_controlType == TEST_GIMBAL_CONTROL_TYPE_ANGLE) {
  323 + USER_LOG_WARN("gimbal is rotating.");
  324 + goto out1;
  325 + }
  326 +
  327 + memcpy(&speedTemp, &rotationValue, sizeof(T_GduAttitude3d));
  328 + GduTest_GimbalSpeedLegalization(&speedTemp);
  329 + s_speed = speedTemp;
  330 +
  331 + if (rotationValue.pitch != 0 || rotationValue.roll != 0 || rotationValue.yaw != 0) {
  332 + s_rotatingFlag = true;
  333 + s_controlType = TEST_GIMBAL_CONTROL_TYPE_SPEED;
  334 + } else {
  335 + s_rotatingFlag = false;
  336 + }
  337 +
  338 + break;
  339 + default:
  340 + USER_LOG_ERROR("gimbal rotation mode invalid: %d.", rotationMode);
  341 + returnCode = GDU_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT;
  342 + goto out1;
  343 + }
  344 +
  345 +out1:
  346 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  347 + USER_LOG_ERROR("mutex unlock error");
  348 + returnCode = GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  349 + goto out2;
  350 + }
  351 +
  352 +out2:
  353 + if (osalHandler->MutexUnlock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  354 + USER_LOG_ERROR("mutex unlock error");
  355 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  356 + }
  357 +
  358 + return returnCode;
  359 +}
  360 +
  361 +/* Private functions definition-----------------------------------------------*/
  362 +#ifndef __CC_ARM
  363 +#pragma GCC diagnostic push
  364 +#pragma GCC diagnostic ignored "-Wmissing-noreturn"
  365 +#pragma GCC diagnostic ignored "-Wreturn-type"
  366 +#endif
  367 +
  368 +static void *UserGimbal_Task(void *arg)
  369 +{
  370 + T_GduReturnCode gduStat;
  371 + static uint32_t step = 0;
  372 + //T_GduFcSubscriptionQuaternion quaternion = {0};
  373 + T_GduDataTimestamp timestamp = {0};
  374 + T_GduAttitude3f nextAttitude = {0};
  375 + T_GduAttitude3f attitudeFTemp = {0};
  376 + uint32_t currentTime = 0;
  377 + uint32_t progressTemp = 0;
  378 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  379 +
  380 + USER_UTIL_UNUSED(arg);
  381 +
  382 + while (1) {
  383 + osalHandler->TaskSleepMs(1000 / PAYLOAD_GIMBAL_TASK_FREQ);
  384 + step++;
  385 +
  386 + if (osalHandler->MutexLock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  387 + USER_LOG_ERROR("mutex lock error");
  388 + continue;
  389 + }
  390 +
  391 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  392 + USER_LOG_ERROR("mutex lock error");
  393 + goto out2;
  394 + }
  395 +
  396 + if (USER_UTIL_IS_WORK_TURN(step, 1, PAYLOAD_GIMBAL_TASK_FREQ)) {
  397 + USER_LOG_DEBUG("gimbal attitude: pitch %d, roll %d, yaw %d.", s_attitudeInformation.attitude.pitch,
  398 + s_attitudeInformation.attitude.roll, s_attitudeInformation.attitude.yaw);
  399 +
  400 + USER_LOG_DEBUG("gimbal fine tune: pitch %d, roll %d, yaw %d.", s_systemState.fineTuneAngle.pitch,
  401 + s_systemState.fineTuneAngle.roll, s_systemState.fineTuneAngle.yaw);
  402 + }
  403 +
  404 +#if 0
  405 + // update aircraft attitude
  406 + if (USER_UTIL_IS_WORK_TURN(step, 50, PAYLOAD_GIMBAL_TASK_FREQ)) {
  407 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_QUATERNION,
  408 + (uint8_t *) &quaternion,
  409 + sizeof(T_GduFcSubscriptionQuaternion),
  410 + &timestamp);
  411 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  412 + USER_LOG_ERROR("get topic quaternion value error.");
  413 + }
  414 +
  415 + gduStat = GduTest_GimbalCalculateGroundAttitudeBaseQuaternion(quaternion, &s_aircraftAttitude);
  416 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  417 + USER_LOG_ERROR("calculate and update aircraft attitude error.");
  418 + }
  419 + }
  420 +#endif
  421 +
  422 + // stable control
  423 + switch (s_systemState.gimbalMode) {
  424 + case GDU_GIMBAL_MODE_FREE:
  425 + break;
  426 + case GDU_GIMBAL_MODE_FPV:
  427 + s_attitudeInformation.attitude.roll += (s_aircraftAttitude.roll - s_lastAircraftAttitude.roll);
  428 + s_attitudeInformation.attitude.yaw += (s_aircraftAttitude.yaw - s_lastAircraftAttitude.yaw);
  429 +
  430 + s_attitudeHighPrecision.roll += (float) (s_aircraftAttitude.roll - s_lastAircraftAttitude.roll);
  431 + s_attitudeHighPrecision.yaw += (float) (s_aircraftAttitude.yaw - s_lastAircraftAttitude.yaw);
  432 +
  433 + if (s_rotatingFlag == true && s_controlType == TEST_GIMBAL_CONTROL_TYPE_ANGLE) {
  434 + s_targetAttitude.roll += (s_aircraftAttitude.roll - s_lastAircraftAttitude.roll);
  435 + s_targetAttitude.yaw += (s_aircraftAttitude.yaw - s_lastAircraftAttitude.yaw);
  436 + }
  437 + break;
  438 + case GDU_GIMBAL_MODE_YAW_FOLLOW:
  439 + s_attitudeInformation.attitude.yaw += (s_aircraftAttitude.yaw - s_lastAircraftAttitude.yaw);
  440 +
  441 + s_attitudeHighPrecision.yaw += (float) (s_aircraftAttitude.yaw - s_lastAircraftAttitude.yaw);
  442 +
  443 + if (s_rotatingFlag == true && s_controlType == TEST_GIMBAL_CONTROL_TYPE_ANGLE) {
  444 + s_targetAttitude.yaw += (s_aircraftAttitude.yaw - s_lastAircraftAttitude.yaw);
  445 + }
  446 + break;
  447 + default:
  448 + USER_LOG_ERROR("gimbal mode invalid: %d.", s_systemState.gimbalMode);
  449 + }
  450 + s_lastAircraftAttitude = s_aircraftAttitude;
  451 +
  452 + attitudeFTemp.pitch = s_attitudeInformation.attitude.pitch;
  453 + attitudeFTemp.roll = s_attitudeInformation.attitude.roll;
  454 + attitudeFTemp.yaw = s_attitudeInformation.attitude.yaw;
  455 + GduTest_GimbalAngleLegalization(&attitudeFTemp, s_aircraftAttitude, &s_attitudeInformation.reachLimitFlag);
  456 + s_attitudeInformation.attitude.pitch = attitudeFTemp.pitch;
  457 + s_attitudeInformation.attitude.roll = attitudeFTemp.roll;
  458 + s_attitudeInformation.attitude.yaw = attitudeFTemp.yaw;
  459 +
  460 + GduTest_GimbalAngleLegalization(&s_attitudeHighPrecision, s_aircraftAttitude, NULL);
  461 +
  462 + attitudeFTemp.pitch = s_targetAttitude.pitch;
  463 + attitudeFTemp.roll = s_targetAttitude.roll;
  464 + attitudeFTemp.yaw = s_targetAttitude.yaw;
  465 + GduTest_GimbalAngleLegalization(&attitudeFTemp, s_aircraftAttitude, NULL);
  466 + s_targetAttitude.pitch = attitudeFTemp.pitch;
  467 + s_targetAttitude.roll = attitudeFTemp.roll;
  468 + s_targetAttitude.yaw = attitudeFTemp.yaw;
  469 +
  470 + // rotation
  471 + if (s_rotatingFlag != true)
  472 + goto out1;
  473 +
  474 + nextAttitude.pitch =
  475 + (float) s_attitudeHighPrecision.pitch + (float) s_speed.pitch / (float) PAYLOAD_GIMBAL_TASK_FREQ;
  476 + nextAttitude.roll =
  477 + (float) s_attitudeHighPrecision.roll + (float) s_speed.roll / (float) PAYLOAD_GIMBAL_TASK_FREQ;
  478 + nextAttitude.yaw = (float) s_attitudeHighPrecision.yaw + (float) s_speed.yaw / (float) PAYLOAD_GIMBAL_TASK_FREQ;
  479 +
  480 + if (s_controlType == TEST_GIMBAL_CONTROL_TYPE_ANGLE) {
  481 + nextAttitude.pitch =
  482 + (nextAttitude.pitch - s_targetAttitude.pitch) * s_speed.pitch >= 0 ? s_targetAttitude.pitch
  483 + : nextAttitude.pitch;
  484 + nextAttitude.roll = (nextAttitude.roll - s_targetAttitude.roll) * s_speed.roll >= 0 ? s_targetAttitude.roll
  485 + : nextAttitude.roll;
  486 + nextAttitude.yaw =
  487 + (nextAttitude.yaw - s_targetAttitude.yaw) * s_speed.yaw >= 0 ? s_targetAttitude.yaw : nextAttitude.yaw;
  488 + }
  489 +
  490 + GduTest_GimbalAngleLegalization(&nextAttitude, s_aircraftAttitude, &s_attitudeInformation.reachLimitFlag);
  491 + s_attitudeInformation.attitude.pitch = nextAttitude.pitch;
  492 + s_attitudeInformation.attitude.roll = nextAttitude.roll;
  493 + s_attitudeInformation.attitude.yaw = nextAttitude.yaw;
  494 +
  495 + s_attitudeHighPrecision.pitch = nextAttitude.pitch;
  496 + s_attitudeHighPrecision.roll = nextAttitude.roll;
  497 + s_attitudeHighPrecision.yaw = nextAttitude.yaw;
  498 +
  499 + if (s_controlType == TEST_GIMBAL_CONTROL_TYPE_ANGLE) {
  500 + if (memcmp(&s_attitudeInformation.attitude, &s_targetAttitude, sizeof(T_GduAttitude3d)) == 0) {
  501 + s_rotatingFlag = false;
  502 + }
  503 + } else if (s_controlType == TEST_GIMBAL_CONTROL_TYPE_SPEED) {
  504 + if ((s_attitudeInformation.reachLimitFlag.pitch == true || s_speed.pitch == 0) &&
  505 + (s_attitudeInformation.reachLimitFlag.roll == true || s_speed.roll == 0) &&
  506 + (s_attitudeInformation.reachLimitFlag.yaw == true || s_speed.yaw == 0)) {
  507 + s_rotatingFlag = false;
  508 + }
  509 + }
  510 +
  511 +out1:
  512 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  513 + USER_LOG_ERROR("mutex unlock error");
  514 + goto out2;
  515 + }
  516 +
  517 +out2:
  518 + if (osalHandler->MutexUnlock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  519 + USER_LOG_ERROR("mutex unlock error");
  520 + continue;
  521 + }
  522 +
  523 + gduStat = osalHandler->GetTimeMs(&currentTime);
  524 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  525 + USER_LOG_ERROR("get current time error: 0x%08llX.", gduStat);
  526 + continue;
  527 + }
  528 +
  529 + if (osalHandler->MutexLock(s_calibrationMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  530 + USER_LOG_ERROR("mutex lock error");
  531 + continue;
  532 + }
  533 +
  534 + // calibration
  535 + if (s_calibrationState.calibratingFlag != true)
  536 + goto unlockCalibrationMutex;
  537 +
  538 + progressTemp = (currentTime - s_calibrationStartTime) * 100 / PAYLOAD_GIMBAL_CALIBRATION_TIME_MS;
  539 + if (progressTemp >= 100) {
  540 + s_calibrationState.calibratingFlag = false;
  541 + s_calibrationState.currentCalibrationProgress = 100;
  542 + s_calibrationState.currentCalibrationStage = GDU_GIMBAL_CALIBRATION_STAGE_COMPLETE;
  543 + }
  544 +
  545 +unlockCalibrationMutex:
  546 + if (osalHandler->MutexUnlock(s_calibrationMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  547 + USER_LOG_ERROR("mutex unlock error");
  548 + continue;
  549 + }
  550 + }
  551 +}
  552 +
  553 +#ifndef __CC_ARM
  554 +#pragma GCC diagnostic pop
  555 +#endif
  556 +
  557 +static T_GduReturnCode GetSystemState(T_GduGimbalSystemState *systemState)
  558 +{
  559 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  560 +
  561 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  562 + USER_LOG_ERROR("mutex lock error");
  563 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  564 + }
  565 +
  566 + *systemState = s_systemState;
  567 +
  568 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  569 + USER_LOG_ERROR("mutex unlock error");
  570 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  571 + }
  572 +
  573 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  574 +}
  575 +
  576 +static T_GduReturnCode GetAttitudeInformation(T_GduGimbalAttitudeInformation *attitudeInformation)
  577 +{
  578 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  579 +
  580 + if (osalHandler->MutexLock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  581 + USER_LOG_ERROR("mutex lock error");
  582 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  583 + }
  584 +
  585 + *attitudeInformation = s_attitudeInformation;
  586 +
  587 + if (osalHandler->MutexUnlock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  588 + USER_LOG_ERROR("mutex unlock error");
  589 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  590 + }
  591 +
  592 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  593 +}
  594 +
  595 +static T_GduReturnCode GetCalibrationState(T_GduGimbalCalibrationState *calibrationState)
  596 +{
  597 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  598 +
  599 + if (osalHandler->MutexLock(s_calibrationMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  600 + USER_LOG_ERROR("mutex lock error");
  601 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  602 + }
  603 +
  604 + *calibrationState = s_calibrationState;
  605 +
  606 + if (osalHandler->MutexUnlock(s_calibrationMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  607 + USER_LOG_ERROR("mutex unlock error");
  608 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  609 + }
  610 +
  611 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  612 +}
  613 +
  614 +static T_GduReturnCode GetRotationSpeed(T_GduAttitude3d *rotationSpeed)
  615 +{
  616 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  617 +
  618 + if (osalHandler->MutexLock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  619 + USER_LOG_ERROR("mutex lock error");
  620 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  621 + }
  622 +
  623 + *rotationSpeed = s_speed;
  624 +
  625 + if (osalHandler->MutexUnlock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  626 + USER_LOG_ERROR("mutex unlock error");
  627 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  628 + }
  629 +
  630 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  631 +}
  632 +
  633 +static T_GduReturnCode GetJointAngle(T_GduAttitude3d *jointAngle)
  634 +{
  635 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  636 +
  637 + if (osalHandler->MutexLock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  638 + USER_LOG_ERROR("mutex lock error");
  639 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  640 + }
  641 +
  642 + jointAngle->pitch = s_attitudeInformation.attitude.pitch - s_aircraftAttitude.pitch;
  643 + jointAngle->roll = s_attitudeInformation.attitude.roll - s_aircraftAttitude.roll;
  644 + jointAngle->yaw = s_attitudeInformation.attitude.yaw - s_aircraftAttitude.yaw;
  645 +
  646 + printf("云台角度:%d ,%d ,%d\n",jointAngle->pitch,jointAngle->roll,jointAngle->yaw);
  647 +
  648 + if (osalHandler->MutexUnlock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  649 + USER_LOG_ERROR("mutex unlock error");
  650 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  651 + }
  652 +
  653 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  654 +}
  655 +
  656 +static T_GduReturnCode StartCalibrate(void)
  657 +{
  658 + T_GduReturnCode gduStat;
  659 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  660 +
  661 + USER_LOG_INFO("start calibrate gimbal.");
  662 +
  663 + gduStat = osalHandler->GetTimeMs(&s_calibrationStartTime);
  664 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  665 + USER_LOG_ERROR("get start time error: 0x%08llX.", gduStat);
  666 + }
  667 +
  668 + if (osalHandler->MutexLock(s_calibrationMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  669 + USER_LOG_ERROR("mutex lock error");
  670 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  671 + }
  672 +
  673 + s_calibrationState.calibratingFlag = true;
  674 + s_calibrationState.currentCalibrationProgress = 0;
  675 + s_calibrationState.currentCalibrationStage = GDU_GIMBAL_CALIBRATION_STAGE_PROCRESSING;
  676 +
  677 + if (osalHandler->MutexUnlock(s_calibrationMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  678 + USER_LOG_ERROR("mutex unlock error");
  679 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  680 + }
  681 +
  682 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  683 +}
  684 +
  685 +static T_GduReturnCode SetControllerSmoothFactor(uint8_t smoothingFactor, E_GduGimbalAxis axis)
  686 +{
  687 + USER_LOG_INFO("set gimbal controller smooth factor: factor %d, axis %d.", smoothingFactor, axis);
  688 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  689 +
  690 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  691 + USER_LOG_ERROR("mutex lock error");
  692 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  693 + }
  694 +
  695 + if (axis == GDU_GIMBAL_AXIS_PITCH)
  696 + s_systemState.smoothFactor.pitch = smoothingFactor;
  697 + else if (axis == GDU_GIMBAL_AXIS_YAW)
  698 + s_systemState.smoothFactor.yaw = smoothingFactor;
  699 + else
  700 + USER_LOG_ERROR("axis is not supported.");
  701 +
  702 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  703 + USER_LOG_ERROR("mutex unlock error");
  704 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  705 + }
  706 +
  707 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  708 +}
  709 +
  710 +static T_GduReturnCode SetPitchRangeExtensionEnabled(bool enabledFlag)
  711 +{
  712 + USER_LOG_INFO("set gimbal pitch range extension enable flag: %d.", enabledFlag);
  713 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  714 +
  715 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  716 + USER_LOG_ERROR("mutex lock error");
  717 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  718 + }
  719 +
  720 + s_systemState.pitchRangeExtensionEnabledFlag = enabledFlag;
  721 +
  722 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  723 + USER_LOG_ERROR("mutex unlock error");
  724 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  725 + }
  726 +
  727 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  728 +}
  729 +
  730 +static T_GduReturnCode SetControllerMaxSpeedPercentage(uint8_t maxSpeedPercentage, E_GduGimbalAxis axis)
  731 +{
  732 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  733 +
  734 + USER_LOG_INFO("set gimbal controller max speed: max speed %d, axis %d.", maxSpeedPercentage, axis);
  735 +
  736 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  737 + USER_LOG_ERROR("mutex lock error");
  738 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  739 + }
  740 +
  741 + if (axis == GDU_GIMBAL_AXIS_PITCH)
  742 + s_systemState.maxSpeedPercentage.pitch = maxSpeedPercentage;
  743 + else if (axis == GDU_GIMBAL_AXIS_YAW)
  744 + s_systemState.maxSpeedPercentage.yaw = maxSpeedPercentage;
  745 + else
  746 + USER_LOG_ERROR("axis is not supported.");
  747 +
  748 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  749 + USER_LOG_ERROR("mutex unlock error");
  750 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  751 + }
  752 +
  753 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  754 +}
  755 +
  756 +static T_GduReturnCode RestoreFactorySettings(void)
  757 +{
  758 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  759 +
  760 + USER_LOG_INFO("restore gimbal factory settings.");
  761 +
  762 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  763 + USER_LOG_ERROR("mutex lock error");
  764 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  765 + }
  766 +
  767 + s_systemState.pitchRangeExtensionEnabledFlag = false;
  768 + s_systemState.gimbalMode = GDU_GIMBAL_MODE_FREE;
  769 + memset(&s_systemState.fineTuneAngle, 0, sizeof(s_systemState.fineTuneAngle));
  770 + memset(&s_systemState.smoothFactor, 0, sizeof(s_systemState.smoothFactor));
  771 + s_systemState.maxSpeedPercentage.pitch = 1;
  772 + s_systemState.maxSpeedPercentage.yaw = 1;
  773 +
  774 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  775 + USER_LOG_ERROR("mutex unlock error");
  776 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  777 + }
  778 +
  779 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  780 +}
  781 +
  782 +static T_GduReturnCode SetMode(E_GduGimbalMode mode)
  783 +{
  784 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  785 +
  786 + USER_LOG_INFO("set gimbal mode: %d.", mode);
  787 +
  788 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  789 + USER_LOG_ERROR("mutex lock error");
  790 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  791 + }
  792 +
  793 + s_systemState.gimbalMode = mode;
  794 +
  795 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  796 + USER_LOG_ERROR("mutex unlock error");
  797 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  798 + }
  799 +
  800 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  801 +}
  802 +
  803 +static T_GduReturnCode Reset(E_GduGimbalResetMode mode)
  804 +{
  805 + T_GduReturnCode gduReturnCode = GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  806 + T_GduAttitude3f attitudeFTemp = {0};
  807 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  808 +
  809 + USER_LOG_INFO("reset gimbal: %d.", mode);
  810 +
  811 + if (osalHandler->MutexLock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  812 + USER_LOG_ERROR("mutex lock error");
  813 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  814 + }
  815 +
  816 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  817 + USER_LOG_ERROR("mutex lock error");
  818 + gduReturnCode = GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  819 + goto unlock2;
  820 + }
  821 +
  822 + switch (mode) {
  823 + case GDU_GIMBAL_RESET_MODE_YAW:
  824 + s_attitudeInformation.attitude.yaw = s_aircraftAttitude.yaw + s_systemState.fineTuneAngle.yaw;
  825 +
  826 + s_attitudeHighPrecision.yaw = s_aircraftAttitude.yaw + s_systemState.fineTuneAngle.yaw;
  827 + break;
  828 + case GDU_GIMBAL_RESET_MODE_PITCH_AND_YAW:
  829 + s_attitudeInformation.attitude.pitch = s_systemState.fineTuneAngle.pitch;
  830 + s_attitudeInformation.attitude.yaw = s_aircraftAttitude.yaw + s_systemState.fineTuneAngle.yaw;
  831 +
  832 + s_attitudeHighPrecision.pitch = s_systemState.fineTuneAngle.pitch;
  833 + s_attitudeHighPrecision.yaw = s_aircraftAttitude.yaw + s_systemState.fineTuneAngle.yaw;
  834 + break;
  835 + case GDU_GIMBAL_RESET_MODE_PITCH_DOWNWARD_UPWARD_AND_YAW:
  836 + s_attitudeInformation.attitude.pitch =
  837 + s_systemState.fineTuneAngle.pitch + (s_systemState.mountedUpward ? 900 : -900);
  838 + s_attitudeInformation.attitude.yaw = s_aircraftAttitude.yaw + s_systemState.fineTuneAngle.yaw;
  839 +
  840 + s_attitudeHighPrecision.pitch =
  841 + s_systemState.fineTuneAngle.pitch + (s_systemState.mountedUpward ? 900 : -900);
  842 + s_attitudeHighPrecision.yaw = s_aircraftAttitude.yaw + s_systemState.fineTuneAngle.yaw;
  843 + break;
  844 + case GDU_GIMBAL_RESET_MODE_PITCH_DOWNWARD_UPWARD:
  845 + s_attitudeInformation.attitude.pitch =
  846 + s_systemState.fineTuneAngle.pitch + (s_systemState.mountedUpward ? 900 : -900);
  847 +
  848 + s_attitudeHighPrecision.pitch =
  849 + s_systemState.fineTuneAngle.pitch + (s_systemState.mountedUpward ? 900 : -900);
  850 + break;
  851 + default:
  852 + USER_LOG_ERROR("reset mode is invalid: %d.", mode);
  853 + gduReturnCode = GDU_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
  854 + goto unlock1;
  855 + }
  856 +
  857 + attitudeFTemp.pitch = s_attitudeInformation.attitude.pitch;
  858 + attitudeFTemp.roll = s_attitudeInformation.attitude.roll;
  859 + attitudeFTemp.yaw = s_attitudeInformation.attitude.yaw;
  860 + GduTest_GimbalAngleLegalization(&attitudeFTemp, s_aircraftAttitude, &s_attitudeInformation.reachLimitFlag);
  861 + s_attitudeInformation.attitude.pitch = attitudeFTemp.pitch;
  862 + s_attitudeInformation.attitude.roll = attitudeFTemp.roll;
  863 + s_attitudeInformation.attitude.yaw = attitudeFTemp.yaw;
  864 + GduTest_GimbalAngleLegalization(&s_attitudeHighPrecision, s_aircraftAttitude, NULL);
  865 +
  866 + s_rotatingFlag = false;
  867 +
  868 +unlock1:
  869 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  870 + USER_LOG_ERROR("mutex unlock error");
  871 + gduReturnCode = GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  872 + goto unlock2;
  873 + }
  874 +
  875 +unlock2:
  876 + if (osalHandler->MutexUnlock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  877 + USER_LOG_ERROR("mutex unlock error");
  878 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  879 + }
  880 +
  881 + return gduReturnCode;
  882 +}
  883 +
  884 +static T_GduReturnCode FineTuneAngle(T_GduAttitude3d fineTuneAngle)
  885 +{
  886 + T_GduReturnCode gduReturnCode = GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  887 + T_GduGimbalReachLimitFlag attitudeReachLimitFlag = {0};
  888 + T_GduGimbalReachLimitFlag fineTuneAngleReachLimitFlag = {0};
  889 + T_GduAttitude3d aircraftAttitudeResetted = {0};
  890 + T_GduAttitude3f attitudeFTemp = {0};
  891 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  892 +
  893 + USER_LOG_INFO("gimbal fine tune angle: pitch %d, roll %d, yaw %d.", fineTuneAngle.pitch,
  894 + fineTuneAngle.roll, fineTuneAngle.yaw);
  895 +
  896 + if (osalHandler->MutexLock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  897 + USER_LOG_ERROR("mutex lock error");
  898 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  899 + }
  900 +
  901 + s_attitudeInformation.attitude.pitch += fineTuneAngle.pitch;
  902 + s_attitudeInformation.attitude.roll += fineTuneAngle.roll;
  903 + s_attitudeInformation.attitude.yaw += fineTuneAngle.yaw;
  904 + attitudeFTemp.pitch = s_attitudeInformation.attitude.pitch;
  905 + attitudeFTemp.roll = s_attitudeInformation.attitude.roll;
  906 + attitudeFTemp.yaw = s_attitudeInformation.attitude.yaw;
  907 + GduTest_GimbalAngleLegalization(&attitudeFTemp, s_aircraftAttitude, &attitudeReachLimitFlag);
  908 + s_attitudeInformation.attitude.pitch = attitudeFTemp.pitch;
  909 + s_attitudeInformation.attitude.roll = attitudeFTemp.roll;
  910 + s_attitudeInformation.attitude.yaw = attitudeFTemp.yaw;
  911 +
  912 + s_attitudeHighPrecision.pitch += fineTuneAngle.pitch;
  913 + s_attitudeHighPrecision.roll += fineTuneAngle.roll;
  914 + s_attitudeHighPrecision.yaw += fineTuneAngle.yaw;
  915 + GduTest_GimbalAngleLegalization(&s_attitudeHighPrecision, s_aircraftAttitude, NULL);
  916 +
  917 + if (osalHandler->MutexLock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  918 + USER_LOG_ERROR("mutex lock error");
  919 + gduReturnCode = GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  920 + goto unlock;
  921 + }
  922 +
  923 + s_systemState.fineTuneAngle.pitch += fineTuneAngle.pitch;
  924 + s_systemState.fineTuneAngle.roll += fineTuneAngle.roll;
  925 + s_systemState.fineTuneAngle.yaw += fineTuneAngle.yaw;
  926 + attitudeFTemp.pitch = s_systemState.fineTuneAngle.pitch;
  927 + attitudeFTemp.roll = s_systemState.fineTuneAngle.roll;
  928 + attitudeFTemp.yaw = s_systemState.fineTuneAngle.yaw;
  929 + GduTest_GimbalAngleLegalization(&attitudeFTemp, aircraftAttitudeResetted, &fineTuneAngleReachLimitFlag);
  930 + s_systemState.fineTuneAngle.pitch = attitudeFTemp.pitch;
  931 + s_systemState.fineTuneAngle.roll = attitudeFTemp.roll;
  932 + s_systemState.fineTuneAngle.yaw = attitudeFTemp.yaw;
  933 +
  934 + if (osalHandler->MutexUnlock(s_commonMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  935 + USER_LOG_ERROR("mutex unlock error");
  936 + gduReturnCode = GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  937 + goto unlock;
  938 + }
  939 +
  940 +unlock:
  941 + if (osalHandler->MutexUnlock(s_attitudeMutex) != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  942 + USER_LOG_ERROR("mutex unlock error");
  943 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  944 + }
  945 +
  946 + if (((attitudeReachLimitFlag.pitch == true || fineTuneAngleReachLimitFlag.pitch == true) &&
  947 + fineTuneAngle.pitch != 0) ||
  948 + ((attitudeReachLimitFlag.roll == true || fineTuneAngleReachLimitFlag.roll == true) &&
  949 + fineTuneAngle.roll != 0) ||
  950 + ((attitudeReachLimitFlag.yaw == true || fineTuneAngleReachLimitFlag.yaw == true) && fineTuneAngle.yaw != 0)) {
  951 + return GDU_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE;
  952 + }
  953 +
  954 + return gduReturnCode;
  955 +}
  956 +
  957 +/**
  958 + * @brief
  959 + * @param attitude: in ground coordinate
  960 + * @param aircraftAttitude: in ground coordinate
  961 + * @param reachLimitFlag
  962 + * @return
  963 + */
  964 +static T_GduReturnCode GduTest_GimbalAngleLegalization(T_GduAttitude3f *attitude, T_GduAttitude3d aircraftAttitude,
  965 + T_GduGimbalReachLimitFlag *reachLimitFlag)
  966 +{
  967 + T_GduAttitude3d eulerAngleLimitMin;
  968 + T_GduAttitude3d eulerAngleLimitMax;
  969 + T_GduAttitude3d angleLimitInBodyCoordinateFromEulerLimitMin = {0};
  970 + T_GduAttitude3d angleLimitInBodyCoordinateFromEulerLimitMax = {0};
  971 + T_GduAttitude3d finalAngleLimitInBodyCoordinateMin = {0};
  972 + T_GduAttitude3d finalAngleLimitInBodyCoordinateMax = {0};
  973 + T_GduAttitude3f attitudeInBodyCoordinate = {0};
  974 +
  975 + if (attitude == NULL) {
  976 + USER_LOG_ERROR("input pointer is null.");
  977 + return GDU_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
  978 + }
  979 +
  980 + // calculate euler angle limit
  981 + eulerAngleLimitMin = s_eulerAngleLimitMin;
  982 + eulerAngleLimitMax = s_eulerAngleLimitMax;
  983 + if (s_systemState.pitchRangeExtensionEnabledFlag == true) {
  984 + eulerAngleLimitMin.pitch = s_pitchEulerAngleExtensionMin;
  985 + eulerAngleLimitMax.pitch = s_pitchEulerAngleExtensionMax;
  986 + }
  987 +
  988 + // transfer euler angle limit to angle limit in body coordinate
  989 + angleLimitInBodyCoordinateFromEulerLimitMin.pitch = eulerAngleLimitMin.pitch - aircraftAttitude.pitch;
  990 + angleLimitInBodyCoordinateFromEulerLimitMin.roll = eulerAngleLimitMin.roll - aircraftAttitude.roll;
  991 + angleLimitInBodyCoordinateFromEulerLimitMin.yaw = eulerAngleLimitMin.yaw - aircraftAttitude.yaw;
  992 + angleLimitInBodyCoordinateFromEulerLimitMax.pitch = eulerAngleLimitMax.pitch - aircraftAttitude.pitch;
  993 + angleLimitInBodyCoordinateFromEulerLimitMax.roll = eulerAngleLimitMax.roll - aircraftAttitude.roll;
  994 + angleLimitInBodyCoordinateFromEulerLimitMax.yaw = eulerAngleLimitMax.yaw - aircraftAttitude.yaw;
  995 +
  996 + // calculate final angle limit in body coordinate based on euler angle limit and joint angle limit
  997 + finalAngleLimitInBodyCoordinateMin.pitch = USER_UTIL_MAX(angleLimitInBodyCoordinateFromEulerLimitMin.pitch,
  998 + s_jointAngleLimitMin.pitch);
  999 + finalAngleLimitInBodyCoordinateMin.roll = USER_UTIL_MAX(angleLimitInBodyCoordinateFromEulerLimitMin.roll,
  1000 + s_jointAngleLimitMin.roll);
  1001 + finalAngleLimitInBodyCoordinateMin.yaw = USER_UTIL_MAX(angleLimitInBodyCoordinateFromEulerLimitMin.yaw,
  1002 + s_jointAngleLimitMin.yaw);
  1003 + finalAngleLimitInBodyCoordinateMax.pitch = USER_UTIL_MIN(angleLimitInBodyCoordinateFromEulerLimitMax.pitch,
  1004 + s_jointAngleLimitMax.pitch);
  1005 + finalAngleLimitInBodyCoordinateMax.roll = USER_UTIL_MIN(angleLimitInBodyCoordinateFromEulerLimitMax.roll,
  1006 + s_jointAngleLimitMax.roll);
  1007 + finalAngleLimitInBodyCoordinateMax.yaw = USER_UTIL_MIN(angleLimitInBodyCoordinateFromEulerLimitMax.yaw,
  1008 + s_jointAngleLimitMax.yaw);
  1009 +
  1010 + // calculate gimbal attitude in body coordinate
  1011 + attitudeInBodyCoordinate.pitch = attitude->pitch - (float) aircraftAttitude.pitch;
  1012 + attitudeInBodyCoordinate.roll = attitude->roll - (float) aircraftAttitude.roll;
  1013 + attitudeInBodyCoordinate.yaw = attitude->yaw - (float) aircraftAttitude.yaw;
  1014 +
  1015 + // modify attitude based on final angle limit
  1016 + attitudeInBodyCoordinate.pitch = USER_UTIL_MIN(attitudeInBodyCoordinate.pitch,
  1017 + (float) finalAngleLimitInBodyCoordinateMax.pitch);
  1018 + attitudeInBodyCoordinate.pitch = USER_UTIL_MAX(attitudeInBodyCoordinate.pitch,
  1019 + (float) finalAngleLimitInBodyCoordinateMin.pitch);
  1020 + attitudeInBodyCoordinate.roll = USER_UTIL_MIN(attitudeInBodyCoordinate.roll,
  1021 + (float) finalAngleLimitInBodyCoordinateMax.roll);
  1022 + attitudeInBodyCoordinate.roll = USER_UTIL_MAX(attitudeInBodyCoordinate.roll,
  1023 + (float) finalAngleLimitInBodyCoordinateMin.roll);
  1024 + attitudeInBodyCoordinate.yaw = USER_UTIL_MIN(attitudeInBodyCoordinate.yaw,
  1025 + (float) finalAngleLimitInBodyCoordinateMax.yaw);
  1026 + attitudeInBodyCoordinate.yaw = USER_UTIL_MAX(attitudeInBodyCoordinate.yaw,
  1027 + (float) finalAngleLimitInBodyCoordinateMin.yaw);
  1028 +
  1029 + // calculate gimbal attitude in ground coordinate
  1030 + attitude->pitch = attitudeInBodyCoordinate.pitch + (float) aircraftAttitude.pitch;
  1031 + attitude->roll = attitudeInBodyCoordinate.roll + (float) aircraftAttitude.roll;
  1032 + attitude->yaw = attitudeInBodyCoordinate.yaw + (float) aircraftAttitude.yaw;
  1033 +
  1034 + // calculate reach limit flag, please note reach limit flag only specifies whether gimbal attitude reach joint angle limit
  1035 + if (reachLimitFlag != NULL) {
  1036 + reachLimitFlag->pitch = (attitudeInBodyCoordinate.pitch >= s_jointAngleLimitMax.pitch ||
  1037 + attitudeInBodyCoordinate.pitch <= s_jointAngleLimitMin.pitch) ? true : false;
  1038 + reachLimitFlag->roll = (attitudeInBodyCoordinate.roll >= s_jointAngleLimitMax.roll ||
  1039 + attitudeInBodyCoordinate.roll <= s_jointAngleLimitMin.roll) ? true : false;
  1040 + reachLimitFlag->yaw = (attitudeInBodyCoordinate.yaw >= s_jointAngleLimitMax.yaw ||
  1041 + attitudeInBodyCoordinate.yaw <= s_jointAngleLimitMin.yaw) ? true : false;
  1042 + }
  1043 +
  1044 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  1045 +}
  1046 +
  1047 +/**
  1048 + * @brief
  1049 + * @param originalAttitude: unit: 0.1degree.
  1050 + * @param targetAttitude: unit: 0.1degree.
  1051 + * @param actionTime: unit: 0.01s.
  1052 + * @param speed: unit: 0.1degree/s.
  1053 + * @return
  1054 + */
  1055 +static T_GduReturnCode
  1056 +GduTest_GimbalCalculateSpeed(T_GduAttitude3d originalAttitude, T_GduAttitude3d targetAttitude, uint16_t actionTime,
  1057 + T_GduAttitude3d *speed)
  1058 +{
  1059 + float pitchSpeedTemp = 0;
  1060 + float rollSpeedTemp = 0;
  1061 + float yawSpeedTemp = 0;
  1062 +
  1063 + if (speed == NULL) {
  1064 + USER_LOG_ERROR("input pointer is null.");
  1065 + return GDU_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
  1066 + }
  1067 +
  1068 + pitchSpeedTemp = (float) (targetAttitude.pitch - originalAttitude.pitch) / (float) actionTime * 100;
  1069 + rollSpeedTemp = (float) (targetAttitude.roll - originalAttitude.roll) / (float) actionTime * 100;
  1070 + yawSpeedTemp = (float) (targetAttitude.yaw - originalAttitude.yaw) / (float) actionTime * 100;
  1071 +
  1072 + speed->pitch = pitchSpeedTemp >= 0.0f ? (int32_t) (pitchSpeedTemp + 1) : (int32_t) (pitchSpeedTemp - 1);
  1073 + speed->roll = rollSpeedTemp >= 0.0f ? (int32_t) (rollSpeedTemp + 1) : (int32_t) (rollSpeedTemp - 1);
  1074 + speed->yaw = yawSpeedTemp >= 0.0f ? (int32_t) (yawSpeedTemp + 1) : (int32_t) (yawSpeedTemp - 1);
  1075 +
  1076 + GduTest_GimbalSpeedLegalization(speed);
  1077 +
  1078 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  1079 +}
  1080 +
  1081 +static void GduTest_GimbalSpeedLegalization(T_GduAttitude3d *speed)
  1082 +{
  1083 + speed->pitch = speed->pitch > s_speedLimit.pitch ? s_speedLimit.pitch : speed->pitch;
  1084 + speed->roll = speed->roll > s_speedLimit.roll ? s_speedLimit.roll : speed->roll;
  1085 + speed->yaw = speed->yaw > s_speedLimit.yaw ? s_speedLimit.yaw : speed->yaw;
  1086 +
  1087 + speed->pitch = speed->pitch < (0 - s_speedLimit.pitch) ? (0 - s_speedLimit.pitch) : speed->pitch;
  1088 + speed->roll = speed->roll < (0 - s_speedLimit.roll) ? (0 - s_speedLimit.roll) : speed->roll;
  1089 + speed->yaw = speed->yaw < (0 - s_speedLimit.yaw) ? (0 - s_speedLimit.yaw) : speed->yaw;
  1090 +}
  1091 +
  1092 +#if 0
  1093 +/**
  1094 + * @brief
  1095 + * @param quaternion
  1096 + * @param attitude Unit: 0.1 degree.
  1097 + * @return
  1098 + */
  1099 +static T_GduReturnCode GduTest_GimbalCalculateGroundAttitudeBaseQuaternion(T_GduFcSubscriptionQuaternion quaternion,
  1100 + T_GduAttitude3d *attitude)
  1101 +{
  1102 + double aircraftPitchInRad;
  1103 + double aircraftRollInRad;
  1104 + double aircraftYawInRad;
  1105 +
  1106 + if (attitude == NULL) {
  1107 + USER_LOG_ERROR("Input argument is null.");
  1108 + return GDU_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
  1109 + }
  1110 +
  1111 + aircraftPitchInRad = asin(2 * ((double) quaternion.q0 * quaternion.q2 - (double) quaternion.q3 * quaternion.q1));
  1112 + attitude->pitch = aircraftPitchInRad * 180 / GDU_PI * 10;
  1113 +
  1114 + aircraftRollInRad = atan2(2 * ((double) quaternion.q0 * quaternion.q1 + (double) quaternion.q2 * quaternion.q3),
  1115 + (double) 1 -
  1116 + 2 * ((double) quaternion.q1 * quaternion.q1 + (double) quaternion.q2 * quaternion.q2));
  1117 + attitude->roll = aircraftRollInRad * 180 / GDU_PI * 10;
  1118 +
  1119 + aircraftYawInRad = atan2(2 * ((double) quaternion.q0 * quaternion.q3 + (double) quaternion.q1 * quaternion.q2),
  1120 + (double) 1 -
  1121 + 2 * ((double) quaternion.q2 * quaternion.q2 + (double) quaternion.q3 * quaternion.q3));
  1122 + attitude->yaw = aircraftYawInRad * 180 / GDU_PI * 10;
  1123 +
  1124 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  1125 +}
  1126 +#endif
  1127 +
  1128 +/****************** (C) COPYRIGHT GDU Innovations *****END OF FILE****/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_payload_gimbal_emu.h
  4 + * @brief This is the header file for "test_payload_gimbal_emu.c", defining the structure and
  5 + * (exported) function prototypes.
  6 + *
  7 + * @copyright (c) 2021 GDU. All rights reserved.
  8 + *
  9 + * All information contained herein is, and remains, the property of GDU.
  10 + * The intellectual and technical concepts contained herein are proprietary
  11 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  12 + * and protected by trade secret or copyright law. Dissemination of this
  13 + * information, including but not limited to data and other proprietary
  14 + * material(s) incorporated within the information, in any form, is strictly
  15 + * prohibited without the express written consent of GDU.
  16 + *
  17 + * If you receive this source code without GDU’s authorization, you may not
  18 + * further disseminate the information, and you must immediately remove the
  19 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  20 + * legal actions against you for any loss(es) or damage(s) caused by your
  21 + * failure to do so.
  22 + *
  23 + *********************************************************************
  24 + */
  25 +
  26 +/* Define to prevent recursive inclusion -------------------------------------*/
  27 +#ifndef TEST_PAYLOAD_GIMBAL_EMU_H
  28 +#define TEST_PAYLOAD_GIMBAL_EMU_H
  29 +
  30 +/* Includes ------------------------------------------------------------------*/
  31 +#include "gdu_typedef.h"
  32 +#include "gdu_gimbal.h"
  33 +
  34 +#ifdef __cplusplus
  35 +extern "C" {
  36 +#endif
  37 +
  38 +/* Exported constants --------------------------------------------------------*/
  39 +
  40 +
  41 +/* Exported types ------------------------------------------------------------*/
  42 +
  43 +
  44 +/* Exported functions --------------------------------------------------------*/
  45 +T_GduReturnCode GduTest_GimbalStartService(void);
  46 +
  47 +T_GduReturnCode GduTest_GimbalDeInit(void);
  48 +T_GduReturnCode GduTest_GimbalRotate(E_GduGimbalRotationMode rotationMode,
  49 + T_GduGimbalRotationProperty rotationProperty,
  50 + T_GduAttitude3d rotationValue); // unit if angle control: 0.1 degree, unit if speed control: 0.1 degree/s
  51 +
  52 +#ifdef __cplusplus
  53 +}
  54 +#endif
  55 +
  56 +#endif // TEST_PAYLOAD_GIMBAL_EMU_H
  57 +
  58 +/************************ (C) COPYRIGHT GDU Innovations *******END OF FILE******/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_hms.c
  4 + * @brief
  5 + *
  6 + * @copyright (c) 2021 GDU. All rights reserved.
  7 + *
  8 + * All information contained herein is, and remains, the property of GDU.
  9 + * The intellectual and technical concepts contained herein are proprietary
  10 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  11 + * and protected by trade secret or copyright law. Dissemination of this
  12 + * information, including but not limited to data and other proprietary
  13 + * material(s) incorporated within the information, in any form, is strictly
  14 + * prohibited without the express written consent of GDU.
  15 + *
  16 + * If you receive this source code without GDU’s authorization, you may not
  17 + * further disseminate the information, and you must immediately remove the
  18 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  19 + * legal actions against you for any loss(es) or damage(s) caused by your
  20 + * failure to do so.
  21 + *
  22 + *********************************************************************
  23 + */
  24 +
  25 +/* Includes ------------------------------------------------------------------*/
  26 +#include "test_hms.h"
  27 +#include "gdu_hms.h"
  28 +#include "gdu_hms_info_table.h"
  29 +#include "gdu_logger.h"
  30 +#include "gdu_platform.h"
  31 +#include "gdu_fc_subscription.h"
  32 +
  33 +/* Private constants ---------------------------------------------------------*/
  34 +#define MAX_HMS_PRINT_COUNT 150
  35 +#define MAX_BUFFER_LEN 256
  36 +#define MIN_HMS_ERROR_LEVEL 0
  37 +#define MID_HMS_ERROR_LEVEL 3
  38 +#define MAX_HMS_ERROR_LEVEL 6
  39 +/* Private types -------------------------------------------------------------*/
  40 +
  41 +/* Private values -------------------------------------------------------------*/
  42 +static const char *oldReplaceAlarmIdStr = "%alarmid";
  43 +static const char *oldReplaceIndexStr = "%index";
  44 +static const char *oldReplaceComponentIndexStr = "%component_index";
  45 +
  46 +/* Private functions declaration ---------------------------------------------*/
  47 +static T_GduReturnCode GduTest_HmsInit(void);
  48 +static T_GduReturnCode GduTest_HmsDeInit(void);
  49 +static T_GduFcSubscriptionFlightStatus GduTest_GetValueOfFlightStatus(void);
  50 +static bool GduTest_ReplaceStr(char *buffer, uint32_t bufferMaxLen, const char *target, const char *dest);
  51 +static bool GduTest_MarchErrCodeInfoTable(T_GduHmsInfoTable hmsInfoTable);
  52 +static T_GduReturnCode GduTest_HmsInfoCallback(T_GduHmsInfoTable hmsInfoTable);
  53 +
  54 +/* Exported functions definition ---------------------------------------------*/
  55 +T_GduReturnCode GduTest_HmsRunSample(void)
  56 +{
  57 + T_GduReturnCode returnCode;
  58 + T_GduOsalHandler *osalHandler;
  59 +
  60 + USER_LOG_INFO("Hms Sample Start");
  61 + GduTest_WidgetLogAppend("Hms Sample Start");
  62 +
  63 + USER_LOG_INFO("--> Step 1: Init hms sample");
  64 + GduTest_WidgetLogAppend("--> Step 1: Init hms sample");
  65 + returnCode = GduTest_HmsInit();
  66 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  67 + USER_LOG_ERROR("Hms sample init error, error code:0x%08llX", returnCode);
  68 + goto out;
  69 + }
  70 +
  71 + osalHandler = GduPlatform_GetOsalHandler();
  72 + USER_LOG_INFO("--> Step 2: Register callback function of push HMS information");
  73 + GduTest_WidgetLogAppend("--> Step 2: Register callback function of push HMS information");
  74 + returnCode = GduHms_RegHmsInfoCallback(GduTest_HmsInfoCallback);
  75 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  76 + USER_LOG_ERROR("Register callback function of push HMS information failed, error code:0x%08llX", returnCode);
  77 + goto out;
  78 + }
  79 + else
  80 + {
  81 + return returnCode;
  82 + }
  83 +
  84 + //osalHandler->TaskSleepMs(10000);
  85 +
  86 +out:
  87 + USER_LOG_INFO("--> Step 3: Deinit hms sample");
  88 + GduTest_WidgetLogAppend("--> Step 3: Deinit hms sample");
  89 + returnCode = GduTest_HmsDeInit();
  90 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  91 + USER_LOG_ERROR("Hms sample deinit error, error code:0x%08llX", returnCode);
  92 + }
  93 +
  94 + USER_LOG_INFO("Hms Sample End");
  95 + GduTest_WidgetLogAppend("Hms Sample End");
  96 +
  97 + return returnCode;
  98 +}
  99 +
  100 +/* Private functions definition-----------------------------------------------*/
  101 +static T_GduReturnCode GduTest_HmsInit(void)
  102 +{
  103 + T_GduReturnCode returnCode;
  104 +
  105 + returnCode = GduFcSubscription_Init();
  106 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  107 + USER_LOG_ERROR("Hms sample init data subscription module failed, error code:0x%08llX", returnCode);
  108 + return returnCode;
  109 + }
  110 +
  111 + /*! subscribe fc data */
  112 + returnCode = GduFcSubscription_SubscribeTopic(GDU_FC_SUBSCRIPTION_TOPIC_STATUS_FLIGHT,
  113 + GDU_DATA_SUBSCRIPTION_TOPIC_10_HZ,
  114 + NULL);
  115 +
  116 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  117 + USER_LOG_ERROR("HMS sample subscribe topic flight status error, error code:0x%08llX", returnCode);
  118 + return returnCode;
  119 + }
  120 +
  121 + return GduHms_Init();
  122 +}
  123 +
  124 +static T_GduReturnCode GduTest_HmsDeInit(void)
  125 +{
  126 + T_GduReturnCode returnCode;
  127 +
  128 + returnCode = GduFcSubscription_DeInit();
  129 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  130 + USER_LOG_ERROR("Deinit data subscription module failed, error code:0x%08llX",
  131 + returnCode);
  132 + return returnCode;
  133 + }
  134 +
  135 + return GduHms_DeInit();
  136 +}
  137 +
  138 +static T_GduFcSubscriptionFlightStatus GduTest_GetValueOfFlightStatus(void)
  139 +{
  140 + T_GduReturnCode gduStat;
  141 + T_GduFcSubscriptionFlightStatus flightStatus;
  142 + T_GduDataTimestamp flightStatusTimestamp = {0};
  143 +
  144 + gduStat = GduFcSubscription_GetLatestValueOfTopic(GDU_FC_SUBSCRIPTION_TOPIC_STATUS_FLIGHT,
  145 + (uint8_t *) &flightStatus,
  146 + sizeof(T_GduFcSubscriptionFlightStatus),
  147 + &flightStatusTimestamp);
  148 +
  149 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  150 + USER_LOG_ERROR("Get value of topic flight status failed, error code:0x%08llX", gduStat);
  151 + flightStatus = 0;
  152 + } else {
  153 + USER_LOG_DEBUG("Timestamp: millisecond %u microsecond %u.", flightStatusTimestamp.millisecond,
  154 + flightStatusTimestamp.microsecond);
  155 + USER_LOG_DEBUG("Flight status: %d.", flightStatus);
  156 + }
  157 +
  158 + return flightStatus;
  159 +}
  160 +
  161 +static bool GduTest_ReplaceStr(char *buffer, uint32_t bufferMaxLen, const char *target, const char *dest)
  162 +{
  163 + char printBuffHeader[MAX_BUFFER_LEN] = {0};
  164 + uint32_t printBuffHeaderCpyCnt = 0;
  165 + char printBuffTail[MAX_BUFFER_LEN] = {0};
  166 + uint32_t printBuffTailCpyCnt = 0;
  167 + char *targetOffset = NULL;
  168 +
  169 + targetOffset = strstr(buffer, target);
  170 + if (!targetOffset) {
  171 + return false;
  172 + }
  173 +
  174 + printBuffHeaderCpyCnt = targetOffset - buffer;
  175 + if (printBuffHeaderCpyCnt > sizeof(printBuffHeader)) {
  176 + printBuffHeaderCpyCnt = sizeof(printBuffHeader);
  177 + }
  178 + memcpy(printBuffHeader, buffer, printBuffHeaderCpyCnt);
  179 +
  180 + printBuffTailCpyCnt = strlen(targetOffset + strlen(target));
  181 + if (printBuffTailCpyCnt > sizeof(printBuffTail)) {
  182 + printBuffTailCpyCnt = sizeof(printBuffTail);
  183 + }
  184 + memcpy(printBuffTail, targetOffset + strlen(target), printBuffTailCpyCnt);
  185 +
  186 + snprintf(buffer, bufferMaxLen, "%s%s%s", printBuffHeader, dest, printBuffTail);
  187 + return true;
  188 +}
  189 +
  190 +
  191 +static bool GduTest_MarchErrCodeInfoTable(T_GduHmsInfoTable hmsInfoTable)
  192 +{
  193 + char alarmIdStr[20] = {0};
  194 + char sensorIdStr[20] = {0};
  195 + char componentIdStr[20] = {0};
  196 + char printBuff[256] = {0};
  197 + const char *originalAlarmInfo = NULL;
  198 + uint8_t hmsCodeMatchFlag = 0;
  199 +
  200 + if (!hmsInfoTable.hmsInfo) {
  201 + USER_LOG_ERROR("Hms info table is null");
  202 + return false;
  203 + }
  204 +
  205 + for (int i = 0; i < hmsInfoTable.hmsInfoNum; i++) {
  206 + hmsCodeMatchFlag = 0;
  207 + for (int j = 0; j < sizeof(hmsErrCodeInfoTbl) / sizeof(T_GduHmsErrCodeInfo); j++) {
  208 + if (hmsInfoTable.hmsInfo[i].errorCode == hmsErrCodeInfoTbl[j].alarmId) {
  209 + hmsCodeMatchFlag = 1;
  210 + snprintf(alarmIdStr, sizeof(alarmIdStr), "%u", hmsInfoTable.hmsInfo[i].errorCode);
  211 + //note:sensor_idx:[0,5].In order to be consistent with the display of pilot, add one.
  212 + snprintf(sensorIdStr, sizeof(sensorIdStr), "%d", hmsInfoTable.hmsInfo[i].componentIndex + 1);
  213 + snprintf(componentIdStr, sizeof(componentIdStr), "0x%02X", hmsInfoTable.hmsInfo[i].componentIndex + 1);
  214 + if (GduTest_GetValueOfFlightStatus() == GDU_FC_SUBSCRIPTION_FLIGHT_STATUS_IN_AIR) {
  215 + originalAlarmInfo = hmsErrCodeInfoTbl[j].flyAlarmInfo;
  216 + } else {
  217 + originalAlarmInfo = hmsErrCodeInfoTbl[j].groundAlarmInfo;
  218 + }
  219 + originalAlarmInfo = hmsErrCodeInfoTbl[j].groundAlarmInfo;
  220 + if (strlen(originalAlarmInfo)) {
  221 + snprintf(printBuff, sizeof(printBuff), "%s", originalAlarmInfo);
  222 + GduTest_ReplaceStr(printBuff, sizeof(printBuff), oldReplaceAlarmIdStr, alarmIdStr);
  223 + GduTest_ReplaceStr(printBuff, sizeof(printBuff), oldReplaceIndexStr, sensorIdStr);
  224 + GduTest_ReplaceStr(printBuff, sizeof(printBuff), oldReplaceComponentIndexStr, componentIdStr);
  225 + if (hmsInfoTable.hmsInfo[i].errorLevel > MIN_HMS_ERROR_LEVEL &&
  226 + hmsInfoTable.hmsInfo[i].errorLevel < MID_HMS_ERROR_LEVEL) {
  227 + USER_LOG_WARN("[ErrorCode:0x%2x] %s", hmsInfoTable.hmsInfo[i].errorCode, printBuff);
  228 + } else if (hmsInfoTable.hmsInfo[i].errorLevel >= MID_HMS_ERROR_LEVEL &&
  229 + hmsInfoTable.hmsInfo[i].errorLevel < MAX_HMS_ERROR_LEVEL) {
  230 + USER_LOG_ERROR("[ErrorCode:0x%2x] %s", hmsInfoTable.hmsInfo[i].errorCode, printBuff);
  231 + }
  232 + }
  233 + }
  234 + }
  235 + if (!hmsCodeMatchFlag) {
  236 + USER_LOG_WARN("[ErrorCode:0x%2x] There are no matching documents in the current hmsErrCodeInfoTbl for now.",
  237 + hmsInfoTable.hmsInfo[i].errorCode);
  238 + }
  239 + }
  240 +
  241 + return true;
  242 +}
  243 +
  244 +static T_GduReturnCode GduTest_HmsInfoCallback(T_GduHmsInfoTable hmsInfoTable)
  245 +{
  246 + if (!GduTest_MarchErrCodeInfoTable(hmsInfoTable)) {
  247 + USER_LOG_ERROR("March HMS Information failed.");
  248 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  249 + }
  250 +
  251 + if (hmsInfoTable.hmsInfoNum == 0) {
  252 + USER_LOG_INFO("All systems of drone are running well now.");
  253 + }
  254 +
  255 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  256 +}
  257 +
  258 +/****************** (C) COPYRIGHT GDU Innovations *****END OF FILE****/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_hms.h
  4 + * @brief This is the header file for "test_hms.c", defining the structure and
  5 + * (exported) function prototypes.
  6 + *
  7 + * @copyright (c) 2021 GDU. All rights reserved.
  8 + *
  9 + * All information contained herein is, and remains, the property of GDU.
  10 + * The intellectual and technical concepts contained herein are proprietary
  11 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  12 + * and protected by trade secret or copyright law. Dissemination of this
  13 + * information, including but not limited to data and other proprietary
  14 + * material(s) incorporated within the information, in any form, is strictly
  15 + * prohibited without the express written consent of GDU.
  16 + *
  17 + * If you receive this source code without GDU’s authorization, you may not
  18 + * further disseminate the information, and you must immediately remove the
  19 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  20 + * legal actions against you for any loss(es) or damage(s) caused by your
  21 + * failure to do so.
  22 + *
  23 + *********************************************************************
  24 + */
  25 +
  26 +/* Define to prevent recursive inclusion -------------------------------------*/
  27 +#ifndef TEST_HMS_H
  28 +#define TEST_HMS_H
  29 +
  30 +/* Includes ------------------------------------------------------------------*/
  31 +#include "gdu_typedef.h"
  32 +
  33 +#ifdef __cplusplus
  34 +extern "C" {
  35 +#endif
  36 +
  37 +/* Exported constants --------------------------------------------------------*/
  38 +
  39 +/* Exported types ------------------------------------------------------------*/
  40 +
  41 +/* Exported functions --------------------------------------------------------*/
  42 +T_GduReturnCode GduTest_HmsRunSample(void);
  43 +
  44 +#ifdef __cplusplus
  45 +}
  46 +#endif
  47 +
  48 +#endif // TEST_HMS_H
  49 +/************************ (C) COPYRIGHT GDU Innovations *******END OF FILE******/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_positioning.c
  4 + * @brief
  5 + *
  6 + * @copyright (c) 2021 GDU. All rights reserved.
  7 + *
  8 + * All information contained herein is, and remains, the property of GDU.
  9 + * The intellectual and technical concepts contained herein are proprietary
  10 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  11 + * and protected by trade secret or copyright law. Dissemination of this
  12 + * information, including but not limited to data and other proprietary
  13 + * material(s) incorporated within the information, in any form, is strictly
  14 + * prohibited without the express written consent of GDU.
  15 + *
  16 + * If you receive this source code without GDU’s authorization, you may not
  17 + * further disseminate the information, and you must immediately remove the
  18 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  19 + * legal actions against you for any loss(es) or damage(s) caused by your
  20 + * failure to do so.
  21 + *
  22 + *********************************************************************
  23 + */
  24 +
  25 +
  26 +/* Includes ------------------------------------------------------------------*/
  27 +#include <fc_subscription/test_fc_subscription.h>
  28 +#include "test_positioning.h"
  29 +#include "gdu_positioning.h"
  30 +#include "gdu_logger.h"
  31 +#include "utils/util_misc.h"
  32 +#include "gdu_platform.h"
  33 +#include "time_sync/test_time_sync.h"
  34 +
  35 +/* Private constants ---------------------------------------------------------*/
  36 +#define POSITIONING_TASK_FREQ (1)
  37 +#define POSITIONING_TASK_STACK_SIZE (2048)
  38 +
  39 +#define GDU_TEST_POSITIONING_EVENT_COUNT (5)
  40 +#define GDU_TEST_TIME_INTERVAL_AMONG_EVENTS_US (1000)
  41 +
  42 +/* Private types -------------------------------------------------------------*/
  43 +
  44 +
  45 +/* Private functions declaration ---------------------------------------------*/
  46 +static void *GduTest_PositioningTask(void *arg);
  47 +
  48 +/* Private variables ---------------------------------------------------------*/
  49 +static T_GduTaskHandle s_userPositioningThread;
  50 +static int32_t s_eventIndex = 0;
  51 +
  52 +/* Exported functions definition ---------------------------------------------*/
  53 +T_GduReturnCode GduTest_PositioningStartService(void)
  54 +{
  55 + T_GduReturnCode gduStat;
  56 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  57 +
  58 + gduStat = GduPositioning_Init();
  59 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  60 + USER_LOG_ERROR("positioning module init error.");
  61 + return gduStat;
  62 + }
  63 +
  64 + USER_LOG_DEBUG("positioning start service");
  65 + GduPositioning_SetTaskIndex(0);
  66 +
  67 + if (osalHandler->TaskCreate("user_positioning_task", GduTest_PositioningTask,
  68 + POSITIONING_TASK_STACK_SIZE, NULL, &s_userPositioningThread) !=
  69 + GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  70 + USER_LOG_ERROR("user positioning task create error.");
  71 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  72 + }
  73 +
  74 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  75 +}
  76 +
  77 +/* Private functions definition-----------------------------------------------*/
  78 +#ifndef __CC_ARM
  79 +#pragma GCC diagnostic push
  80 +#pragma GCC diagnostic ignored "-Wmissing-noreturn"
  81 +#pragma GCC diagnostic ignored "-Wreturn-type"
  82 +#endif
  83 +
  84 +static void *GduTest_PositioningTask(void *arg)
  85 +{
  86 + int32_t i = 0;
  87 + T_GduReturnCode gduStat;
  88 + uint64_t ppsNewestTriggerTimeUs = 0;
  89 + uint64_t posTime = 0;
  90 + uint32_t currentTimeMs = 0;
  91 + uint64_t currentTimeUs = 0;
  92 + T_GduPositioningEventInfo eventInfo[GDU_TEST_POSITIONING_EVENT_COUNT] = {0};
  93 + T_GduPositioningPositionInfo positionInfo[GDU_TEST_POSITIONING_EVENT_COUNT] = {0};
  94 + T_GduTimeSyncAircraftTime aircraftTime = {0};
  95 + T_GduOsalHandler *osalHandler = GduPlatform_GetOsalHandler();
  96 + uint8_t totalSatelliteNumber = 0;
  97 + uint32_t beforeTime = 0, afterTime = 0;
  98 +
  99 + USER_UTIL_UNUSED(arg);
  100 +
  101 + while (1) {
  102 + osalHandler->TaskSleepMs(1000 / POSITIONING_TASK_FREQ);
  103 +
  104 + gduStat = GduTest_FcSubscriptionGetTotalSatelliteNumber(&totalSatelliteNumber);
  105 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  106 + USER_LOG_ERROR("get total satellite number error: 0x%08llX.", gduStat);
  107 + continue;
  108 + }
  109 +
  110 + gduStat = GduTest_TimeSyncGetNewestPpsTriggerLocalTimeUs(&ppsNewestTriggerTimeUs);
  111 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  112 + USER_LOG_ERROR("get newest pps trigger time error: 0x%08llX.", gduStat);
  113 + continue;
  114 + }
  115 +
  116 + gduStat = osalHandler->GetTimeMs(&currentTimeMs);
  117 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  118 + USER_LOG_ERROR("get current time error: 0x%08llX.", gduStat);
  119 + continue;
  120 + }
  121 +
  122 + for (i = 0; i < GDU_TEST_POSITIONING_EVENT_COUNT; ++i) {
  123 + eventInfo[i].eventSetIndex = s_eventIndex;
  124 + eventInfo[i].targetPointIndex = i;
  125 +
  126 + currentTimeUs = ((uint64_t)currentTimeMs - (i+1) * 300) * 1000;
  127 + gduStat = GduTimeSync_TransferToAircraftTime(currentTimeUs, &aircraftTime);
  128 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  129 + USER_LOG_ERROR("transfer to aircraft time error: 0x%08llX.", gduStat);
  130 + continue;
  131 + }
  132 +
  133 + eventInfo[i].eventTime = aircraftTime;
  134 + }
  135 +
  136 + gduStat = GduPositioning_GetPositionInformationSync(GDU_TEST_POSITIONING_EVENT_COUNT, eventInfo, positionInfo);
  137 + if (gduStat != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  138 + USER_LOG_ERROR("get position information error. error code is 0x%08llX", gduStat);
  139 + continue;
  140 + }
  141 +
  142 + USER_LOG_DEBUG("request position of target points success.");
  143 + USER_LOG_DEBUG("detail position information:*************");
  144 + for (i = 0; i < GDU_TEST_POSITIONING_EVENT_COUNT; ++i) {
  145 + USER_LOG_DEBUG("position solution property: %d. eventTime:(%d-%d-%d %d:%d:%d:%d)", positionInfo[i].positionSolutionProperty, eventInfo[i].eventTime.year, eventInfo[i].eventTime.month, eventInfo[i].eventTime.day, \
  146 + eventInfo[i].eventTime.hour, eventInfo[i].eventTime.minute , eventInfo[i].eventTime.second, eventInfo[i].eventTime.microsecond);
  147 +// USER_LOG_DEBUG("pitchAttitudeAngle: %d\trollAttitudeAngle: %d\tyawAttitudeAngle: %d",
  148 +// positionInfo[i].uavAttitude.pitch, positionInfo[i].uavAttitude.roll,
  149 +// positionInfo[i].uavAttitude.yaw);
  150 +// USER_LOG_DEBUG("northPositionOffset: %d\tearthPositionOffset: %d\tdownPositionOffset: %d",
  151 +// positionInfo[i].offsetBetweenMainAntennaAndTargetPoint.x,
  152 +// positionInfo[i].offsetBetweenMainAntennaAndTargetPoint.y,
  153 +// positionInfo[i].offsetBetweenMainAntennaAndTargetPoint.z);
  154 + USER_LOG_DEBUG("longitude: %.8f\tlatitude: %.8f\theight: %.8f",
  155 + positionInfo[i].targetPointPosition.longitude,
  156 + positionInfo[i].targetPointPosition.latitude,
  157 + positionInfo[i].targetPointPosition.height);
  158 +// USER_LOG_DEBUG(
  159 +// "longStandardDeviation: %.8f\tlatStandardDeviation: %.8f\thgtStandardDeviation: %.8f",
  160 +// positionInfo[i].targetPointPositionStandardDeviation.longitude,
  161 +// positionInfo[i].targetPointPositionStandardDeviation.latitude,
  162 +// positionInfo[i].targetPointPositionStandardDeviation.height);
  163 + }
  164 +
  165 + s_eventIndex++;
  166 + }
  167 +}
  168 +
  169 +#ifndef __CC_ARM
  170 +#pragma GCC diagnostic pop
  171 +#endif
  172 +
  173 +/****************** (C) COPYRIGHT GDU Innovations *****END OF FILE****/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_positioning.h
  4 + * @brief This is the header file for "test_positioning.c", defining the structure and
  5 + * (exported) function prototypes.
  6 + *
  7 + * @copyright (c) 2021 GDU. All rights reserved.
  8 + *
  9 + * All information contained herein is, and remains, the property of GDU.
  10 + * The intellectual and technical concepts contained herein are proprietary
  11 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  12 + * and protected by trade secret or copyright law. Dissemination of this
  13 + * information, including but not limited to data and other proprietary
  14 + * material(s) incorporated within the information, in any form, is strictly
  15 + * prohibited without the express written consent of GDU.
  16 + *
  17 + * If you receive this source code without GDU’s authorization, you may not
  18 + * further disseminate the information, and you must immediately remove the
  19 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  20 + * legal actions against you for any loss(es) or damage(s) caused by your
  21 + * failure to do so.
  22 + *
  23 + *********************************************************************
  24 + */
  25 +
  26 +/* Define to prevent recursive inclusion -------------------------------------*/
  27 +#ifndef TEST_POSITIONING_H
  28 +#define TEST_POSITIONING_H
  29 +
  30 +/* Includes ------------------------------------------------------------------*/
  31 +#include "gdu_typedef.h"
  32 +
  33 +#ifdef __cplusplus
  34 +extern "C" {
  35 +#endif
  36 +
  37 +/* Exported constants --------------------------------------------------------*/
  38 +
  39 +
  40 +/* Exported types ------------------------------------------------------------*/
  41 +
  42 +
  43 +/* Exported functions --------------------------------------------------------*/
  44 +T_GduReturnCode GduTest_PositioningStartService(void);
  45 +
  46 +#ifdef __cplusplus
  47 +}
  48 +#endif
  49 +
  50 +#endif // TEST_POSITIONING_H
  51 +
  52 +/************************ (C) COPYRIGHT GDU Innovations *******END OF FILE******/
  1 +/**
  2 + ********************************************************************
  3 + * @file test_power_management.c
  4 + * @brief
  5 + *
  6 + * @copyright (c) 2021 GDU. All rights reserved.
  7 + *
  8 + * All information contained herein is, and remains, the property of GDU.
  9 + * The intellectual and technical concepts contained herein are proprietary
  10 + * to GDU and may be covered by U.S. and foreign patents, patents in process,
  11 + * and protected by trade secret or copyright law. Dissemination of this
  12 + * information, including but not limited to data and other proprietary
  13 + * material(s) incorporated within the information, in any form, is strictly
  14 + * prohibited without the express written consent of GDU.
  15 + *
  16 + * If you receive this source code without GDU’s authorization, you may not
  17 + * further disseminate the information, and you must immediately remove the
  18 + * source code and notify GDU of its removal. GDU reserves the right to pursue
  19 + * legal actions against you for any loss(es) or damage(s) caused by your
  20 + * failure to do so.
  21 + *
  22 + *********************************************************************
  23 + */
  24 +
  25 +
  26 +/* Includes ------------------------------------------------------------------*/
  27 +#include "test_power_management.h"
  28 +#include "gdu_logger.h"
  29 +#include "gdu_aircraft_info.h"
  30 +
  31 +/* Private constants ---------------------------------------------------------*/
  32 +
  33 +/* Private types -------------------------------------------------------------*/
  34 +
  35 +/* Private functions declaration ---------------------------------------------*/
  36 +static T_GduReturnCode GduTest_PowerOffNotificationCallback(bool *powerOffPreparationFlag);
  37 +
  38 +/* Private variables ---------------------------------------------------------*/
  39 +static T_GduTestApplyHighPowerHandler s_applyHighPowerHandler;
  40 +
  41 +/* Exported functions definition ---------------------------------------------*/
  42 +/**
  43 + * @brief Register handler function for applying high power. This function have to be called before calling
  44 + * GduTest_PowerManagementInit(), except for in Linux, because GduTest_PowerManagementInit() do not apply high power
  45 + * in Linux OS.
  46 + * @param applyHighPowerHandler: pointer to handler function for applying high power.
  47 + * @return Execution result.
  48 + */
  49 +T_GduReturnCode GduTest_RegApplyHighPowerHandler(T_GduTestApplyHighPowerHandler *applyHighPowerHandler)
  50 +{
  51 + if (applyHighPowerHandler->pinInit == NULL) {
  52 + USER_LOG_ERROR("reg apply high power handler pinInit error");
  53 + return GDU_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
  54 + }
  55 +
  56 + if (applyHighPowerHandler->pinWrite == NULL) {
  57 + USER_LOG_ERROR("reg apply high power handler pinWrite error");
  58 + return GDU_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
  59 + }
  60 +
  61 + memcpy(&s_applyHighPowerHandler, applyHighPowerHandler, sizeof(T_GduTestApplyHighPowerHandler));
  62 +
  63 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  64 +}
  65 +
  66 +/**
  67 + * @brief Initialise power management module, including apply high power (only RTOS) and register power off notification
  68 + * callback function.
  69 + * @note GDU development board 1.0 can not accept high power, so do not call this function in GDU development board
  70 + * 1.0 project.
  71 + * @return Execution result.
  72 + */
  73 +T_GduReturnCode GduTest_PowerManagementStartService(void)
  74 +{
  75 + T_GduReturnCode returnCode;
  76 + T_GduAircraftInfoBaseInfo baseInfo = {0};
  77 +
  78 + returnCode = GduPowerManagement_Init();
  79 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  80 + USER_LOG_ERROR("power management init error: 0x%08llX.", returnCode);
  81 + return returnCode;
  82 + }
  83 +
  84 + returnCode = GduAircraftInfo_GetBaseInfo(&baseInfo);
  85 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  86 + USER_LOG_ERROR("Get aircraft base info error: 0x%08llX.", returnCode);
  87 + return returnCode;
  88 + }
  89 +
  90 + // register power off notification callback function
  91 + returnCode = GduPowerManagement_RegPowerOffNotificationCallback(GduTest_PowerOffNotificationCallback);
  92 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  93 + USER_LOG_ERROR("register power off notification callback function error");
  94 + return returnCode;
  95 + }
  96 +
  97 + // apply high power
  98 + if (s_applyHighPowerHandler.pinInit == NULL) {
  99 + USER_LOG_ERROR("apply high power pin init interface is NULL error");
  100 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  101 + }
  102 +
  103 + if (s_applyHighPowerHandler.pinWrite == NULL) {
  104 + USER_LOG_ERROR("apply high power pin write interface is NULL error");
  105 + return GDU_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
  106 + }
  107 +
  108 + returnCode = s_applyHighPowerHandler.pinInit();
  109 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  110 + USER_LOG_ERROR("apply high power pin init error");
  111 + return returnCode;
  112 + }
  113 +
  114 + returnCode = GduPowerManagement_RegWriteHighPowerApplyPinCallback(s_applyHighPowerHandler.pinWrite);
  115 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  116 + USER_LOG_ERROR("register WriteHighPowerApplyPinCallback error.");
  117 + return returnCode;
  118 + }
  119 +
  120 + returnCode = GduPowerManagement_ApplyHighPowerSync();
  121 + if (returnCode != GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
  122 + USER_LOG_ERROR("apply high power error");
  123 + return returnCode;
  124 + }
  125 + else
  126 + {
  127 + USER_LOG_DEBUG("apply high power success");
  128 + }
  129 +
  130 +
  131 +
  132 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  133 +}
  134 +
  135 +/* Private functions definition-----------------------------------------------*/
  136 +static T_GduReturnCode GduTest_PowerOffNotificationCallback(bool *powerOffPreparationFlag)
  137 +{
  138 + T_GduReturnCode gduStat;
  139 + USER_LOG_INFO("----------------------------------------aircraft will power off soon.");
  140 +
  141 + usleep(4500*1000);
  142 + *powerOffPreparationFlag = true;
  143 +
  144 +
  145 + return GDU_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
  146 +}
  147 +
  148 +/****************** (C) COPYRIGHT GDU Innovations *****END OF FILE****/