Compare commits

...

235 Commits

Author SHA1 Message Date
Lorenz Meier 50bd148f53 Aero: Update maintainer 2018-01-06 12:19:31 +01:00
Lorenz Meier ea545f2813 ROMFS: Exclude FMUv2 in Stampede 2018-01-06 11:35:53 +01:00
Lorenz Meier 6213b2266b ROMFS: Exclude FMUv2 in Axial Racing 2018-01-06 11:35:53 +01:00
Lorenz Meier f79c3bb5ea ROMFS: Exclude FMUv2 in ground vehicle 2018-01-06 11:35:53 +01:00
Lorenz Meier 25141ce184 ROMFS: Exclude FMUv2 in obscure airframe 2018-01-06 11:35:53 +01:00
Lorenz Meier 1930cc2fbe ROMFS: Exclude FMUv2 in VTOL 2018-01-06 11:35:53 +01:00
Lorenz Meier 90e7ce1b96 ROMFS: Remove reference to non-existent board 2018-01-06 11:35:53 +01:00
Lorenz Meier 1cfb441527 ROMFS: Reduce verbosity level 2018-01-06 11:35:53 +01:00
Lorenz Meier 59f56f4a5b Add support for Pixhack detection
This allows to boot a Pixhack 3.0 which is the same as Pixhawk 2.0 / 2.1
2018-01-06 11:35:53 +01:00
Lorenz Meier 01e1bac365 FMUv2: Fix Pixhawk Mini boards while hopefully retaining HK Pixhawk units. 2018-01-06 11:35:53 +01:00
Lorenz Meier 0cd24874f3 MPU6K: Provide more clear output which buses are being probed 2018-01-06 11:35:53 +01:00
Lorenz Meier 8c647f11d0 Revert "Revert "Fix for HobbyKing boards.""
This reverts commit b7189012dc.
2018-01-06 11:35:53 +01:00
Daniel Agar 37e3234e49 Jenkins uorb graphs set docker arguments 2018-01-05 23:20:04 -05:00
Daniel Agar 1f63d85869 NuttX generate Make.defs per config from PX4 cmake (#8573) 2018-01-05 22:47:10 -05:00
Daniel Agar f86d4b18f8 Jenkins generate uorb graphs (#8571) 2018-01-05 17:20:39 -05:00
Lorenz Meier 31ab496f31 ROMFS: Free additional space 2018-01-05 23:03:02 +01:00
Lorenz Meier dd5524da3d Make boot slightly less verbose 2018-01-05 22:45:12 +01:00
Matthias Grob c0c0666d5c Cygwin: use absolute path with cygpath conversion to the linker script again
because the relative path is interpreted differently on linux, mac and windows
2018-01-05 14:47:33 -05:00
Daniel Agar 275f462136 cmake determine relative path for firmware linking 2018-01-05 14:47:33 -05:00
Daniel Agar bf84cf0dcf Cygwin: use relative paths where needed 2018-01-05 14:47:33 -05:00
Matthias Grob be8adbfdf3 Cygwin: refactored & simplified some of the OS define logic 2018-01-05 14:47:33 -05:00
Matthias Grob 2186f7b1b1 Cygwin: Enable ARM build of px4fmu-vX_default under Windows Cygwin Environment 2018-01-05 14:47:33 -05:00
Matthias Grob 70de169f15 Cygwin: Enable build of SITL jMAVsim under Windows using the Cygwin Unix-like environment
Most of the incompatitbilities are luckily similar to the darwin build.
- New target OS __PX4_CYGWIN added because in other build environments on Windows defines will very likely be completely different
- added all necessary exeptions to the defines
- disabled priorities completely because on Windows they are defined 1-32 and with all the arbitrary +40 -40 priority settings there were a lot of problems
  not only did some threads/"virtual tasks" not start because of out of bound priorities but also the resulting scheduling was totally random and inadequate
  with default priorities it ran toally fine during my first tests, should be rethought when windows is used onboard in the future
2018-01-05 14:47:33 -05:00
Daniel Agar 02c4ec9b2a move nuttx-configs to platforms/nuttx 2018-01-05 14:21:31 -05:00
Daniel Agar 62c2fbb443 move Images to platforms/nuttx 2018-01-05 14:21:31 -05:00
Daniel Agar 2dcd617a8f move Debug to platforms/nuttx 2018-01-05 14:21:31 -05:00
Daniel Agar 7178f8416d delete obsolete Vagrantfile 2018-01-05 14:21:31 -05:00
Daniel Agar f2cd5e3e9f move src/firmware/ to platforms 2018-01-05 14:21:31 -05:00
Daniel Agar e5b784736f delete unused cmake/test 2018-01-05 14:21:31 -05:00
Daniel Agar 678e2c415d move cmake/${OS} to platforms 2018-01-05 14:21:31 -05:00
Nuno Marques 3fcffe1f3b Tools: update sitl_gazebo (#8597) 2018-01-05 14:09:31 -05:00
Amir Melzer 51437a89e1 remove coning compensation for the accelerometers (#8594) 2018-01-05 14:08:33 -05:00
Julian Oes 14cc9e9919 mavlink_messages: fix length of NAV_CONTROLLER msg
This was caught in an unrelated review.
2018-01-05 19:53:41 +01:00
ChristophTobler 3ffc1fd25b Stream scaled IMU for Snapdragon Flight using VISLAM
This is temporary (and for Snapdragon Flight + VISLAM only) until there is a proper solution to get unfiltered IMU data for VIOs etc.
2018-01-05 18:45:50 +01:00
Daniel Agar 545f8c4452 RTL optionally use planned mission landing (#8487)
- adds new RTL_LAND_TYPE parameter
2018-01-04 23:42:01 -05:00
Julian Oes f3bd241dbe jMAVSim: update to latest master
This brings some support for mavlink 2, and various other bugfixes.
2018-01-04 21:27:16 +01:00
Daniel Agar 430cdada60 param_export use bson encoder buffer 2018-01-04 09:21:17 +01:00
Daniel Agar 08443c0bfc params add param_find perf counter 2018-01-04 09:21:17 +01:00
Daniel Agar ec65ff7c5e sensors remove unnecessary param set notification 2018-01-04 09:21:17 +01:00
Daniel Agar 627788c93c mavlink remove unnecessary param set notification 2018-01-04 09:21:17 +01:00
Daniel Agar 2bb4644180 camera_trigger remove unnecessary param set notification 2018-01-04 09:21:17 +01:00
Daniel Agar 45441d62b1 sensors thermal calibration only get params if enabled 2018-01-04 09:21:17 +01:00
Daniel Agar 7af3cb9df8 param group "Sensors Thermal Calibration" shorten 2018-01-04 09:21:17 +01:00
Daniel Agar f87402b16c navigator remove redundant param updates 2018-01-04 09:21:17 +01:00
Daniel Agar 49180de27c commander remove continuous param_get in arm_auth_update 2018-01-04 09:21:17 +01:00
Daniel Agar 641129ad4e param add perf counters 2018-01-04 09:21:17 +01:00
keenanjohnson c8590e0fb1 Main Readme: Spelling correction
Signed-off-by: keenanjohnson <keenan.johnson@gmail.com>
2018-01-03 12:06:35 -05:00
Daniel Agar c7b5a6f463 FW delete unused yaw coordination parameters 2018-01-03 16:28:50 +01:00
Daniel Agar 757d905089 FW improve FW_ARSP_MODE metadata options
- fixes #8563
2018-01-03 08:18:22 +01:00
CarlOlsson 1cd0ca9c6c updated ecl 2018-01-02 22:36:42 +01:00
Paul Riseborough 96d04af6e8 ecl: adds sideslip to innovation test status reporting 2018-01-02 22:36:42 +01:00
CarlOlsson 84d7eb2900 ekf2: added beta test ratio to estimator_status
Signed-off-by: CarlOlsson <carlolsson.co@gmail.com>
2018-01-02 22:36:42 +01:00
Daniel Agar 573fbeda04 Jenkins add flight review email for failures 2018-01-02 16:00:35 -05:00
Daniel Agar 14e8ee75e7 Jenkins ROS tests fetch all git tags for correct version reporting 2018-01-02 16:00:35 -05:00
Daniel Agar 5af4704aac Jenkins ROS tests set CI=true and set CCACHE_BASEDIR 2018-01-02 12:25:10 -05:00
Lorenz Meier 1f4bad0624 MAVLink: Harden home position usage
This should ensure that the home position / altitude is only being used when valid.
2018-01-02 16:52:10 +01:00
Daniel Agar d67cbfba3a Jenkins add descriptions to flight review post 2018-01-02 10:38:12 -05:00
Daniel Agar 5db534849a Jenkins ROS tests archive all failure logs 2018-01-02 10:38:12 -05:00
Daniel Agar 4d08f56fae cmake add missing generate_px4muorb_stubs dependency (#8559) 2018-01-02 10:18:00 -05:00
Lorenz Meier 92540fc6d8 IO: Remove hint that parameter change requires reboot
The change is effective immediately so no reboot is required. This makes the whole configuration a lot easier.
2018-01-02 10:48:09 +01:00
Lorenz Meier f4362c5ae5 FMU: Remove hint that parameter change requires reboot
The change is effective immediately so no reboot is required. This makes the whole configuration a lot easier.
2018-01-02 10:47:38 +01:00
Daniel Agar b8e6fc2730 Makefile tests_coverage run ROS tests 2018-01-02 01:35:57 +01:00
Daniel Agar 6bdc18df6d sitl launch default ekf2 everywhere 2018-01-02 01:35:57 +01:00
Daniel Agar 734a6c8a42 Jenkins update mission test naming 2018-01-02 01:35:57 +01:00
Daniel Agar cd60fb6102 ledsim remove debug print 2018-01-02 01:35:57 +01:00
Daniel Agar e9960b5532 Jenkins add title and url for flight review upload 2018-01-02 01:35:57 +01:00
Daniel Agar 202c29154a simulator optimize GPS and battery
- GPS and battery were publishing at > 800Hz
2018-01-02 01:35:57 +01:00
Daniel Agar 66f614435f vtol_att avoid unnecessary work and delete unused 2018-01-02 01:35:57 +01:00
Daniel Agar d3a220f807 vtol_att only set fw_permanent_stab on param change 2018-01-02 01:35:57 +01:00
Daniel Agar 75e4a856a5 Jenkins post mission test logs to flight review 2018-01-02 01:35:57 +01:00
Daniel Agar 3f67ddbdba ROS mission_test.py send mission before starting
- update to latest sitl_gazebo
2018-01-02 01:35:57 +01:00
Daniel Agar 63deb40a76 ROS tests move to test/ and new Jenkins 2018-01-02 01:35:57 +01:00
Anthony Lamping f46db40b10 make sure FCU is connected to mavros before state topic is marked ready 2018-01-02 01:35:57 +01:00
Anthony Lamping ab5a268ca5 simplify vtol transition check, more log msgs 2018-01-02 01:35:57 +01:00
Anthony Lamping f9e7c66718 thread for offboard publishers, add asserts for topics to come up (simulation ready) and set mode and arming, use home_position topic as better indicator of when the simulation is ready, add more feedback to rosinfo, make timeouts meaningful (in seconds), add land and extended state values 2018-01-02 01:35:57 +01:00
Anthony Lamping 5ce381dfc7 update sitl tests 2018-01-02 01:35:57 +01:00
TSC21 fefed35dfe Tools: update sitl_gazebo 2018-01-01 21:06:00 +01:00
Daniel Agar 9d61febd39 tfmini remove obsolete IOCTLs 2018-01-01 17:38:41 +01:00
Lorenz Meier 49bed47924 Add TFMini to autostart 2018-01-01 17:38:41 +01:00
Ayush 91cedcaba3 Added tfmini driver to build configs 2018-01-01 17:38:41 +01:00
Ayush 9f2bb6c7f9 Added support for TFmini-LiDAR 2018-01-01 17:38:41 +01:00
Daniel Agar ad532d0510 docker_run.sh update container versions to match Jenkins 2018-01-01 10:27:43 -05:00
Daniel Agar 386c34a563 Jenkins update all containers to latest (except NuttX) 2018-01-01 10:19:00 -05:00
Daniel Agar 33266ef2c8 cmake use ccache if found and not disabled 2018-01-01 10:19:00 -05:00
Daniel Agar 1468d4ed39 muorb add generation dependency 2018-01-01 10:19:00 -05:00
Lorenz Meier 3b71c70583 Commander: Do not switch land detection state when not armed
This is important to have the probation times set up correctly and to silence land detected messages for systems that are not actually flying and just on the bench.
2018-01-01 15:32:37 +01:00
Lorenz Meier e7fe8f7268 Uploader: Enforce matching maximum flash sizes
The goal is to force developers to use the correct target with the correct flash size. This prevents criticial functionality missing and is in particular important for FMUv2/FMUv3 boards. It is unmaintainable otherwise for the Pixhawk series.
2018-01-01 09:29:55 -05:00
Lorenz Meier 3041438132 Zubax GNSS: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier e2b2f97d0d TAPv1: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 9a7f99f3cd S2740VC: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 0bfd2925bf Nucleo: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier d1d367011e IOv2: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier d26e037df4 FMUv5: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 3bfa194933 FMUv4PRO: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 18715ebd80 FMUv4: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier c0efaa4ca9 FMUv3: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 6fbfde9ec3 FMUv2: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier d22398f733 PX4 FLOW: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier cd0fbb3cd2 PX4 ESC: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 03c5e9172d PX4 CAN Node: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier bb3746e710 STM32 Disco: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier c3f630ca14 SAMe70: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 18d13498de NXPPHlite: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier ca472ebfaf MindPX: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 7277d72db5 ESC35: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 5d186f374b Crazyflie: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier f7b4f13e81 AUAV x2.1: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 2ba7b41f5c Aero: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 5072c0b5ae Aerocore: Store maximum flash size 2018-01-01 09:29:55 -05:00
Lorenz Meier 32aa8d4f51 FMUv3: Use its own proper prototype for the image 2018-01-01 09:29:55 -05:00
Lorenz Meier 40702b36ee NuttX: Allow different board prototype names from main build config 2018-01-01 09:29:55 -05:00
acfloria 1aebc69fed commander: Allow manual override in stabilized mode for a fixed-wing. 2018-01-01 14:28:36 +01:00
Lorenz Meier 715b571dac Commander: Add hint about ongoing rewrite
It's important that any reader of the file knows about the ongoing refactoring.
2018-01-01 13:11:52 +01:00
Anass Al dc6e47f777 Update SITL Gazebo for magnetic declination fix 2018-01-01 11:52:35 +01:00
Dennis Mannhart a649bbebb7 commander: switch to hold or mission once takeoff is finished (#8020)
* add COM_TAKEOFF_ACT to optionally switch to mission after takeoff
2017-12-31 13:58:20 -05:00
Lorenz Meier cf55901ac9 Calibration timeout: Triple to 90 seconds as the user can now cancel the routine
We timed out earlier to allow users to abort, but now that we can cancel we do not need to enforce such a time limit.
2017-12-31 16:37:02 +01:00
Lorenz Meier 2167457e2e VTOL status: Do not force a commander status change
Before the VTOL status would automatically force a commander state update all the time. This saves effort and makes sure the system only updates when it should.
2017-12-31 16:37:02 +01:00
Lorenz Meier 90b4afebb5 Commander: properly separate preflight check and prearm checks
We were running pre-arm checks before when not arming, which led to annoying error messages on vehicles that were on the bench or serviced on the ground. Now we really only run them when trying to arm.
2017-12-31 16:37:02 +01:00
Lorenz Meier ddf0ecfc38 Airspeed calibration: Ensure that the calibration state is stored correctly
This is necessary due to sensors that are so accurate that they have no offset at all.
2017-12-31 16:37:02 +01:00
Lorenz Meier 074636a8ae Commander: Check for preflight errors in order 2017-12-31 16:37:02 +01:00
Lorenz Meier c06251f3be IO serial: Code style 2017-12-31 16:36:34 +01:00
Lorenz Meier 1f21256f6a IO safety switch: Code style 2017-12-31 16:36:34 +01:00
Lorenz Meier 0013f641aa IO comms: Code style 2017-12-31 16:36:34 +01:00
Lorenz Meier ac113d71af IO main loop: Code style 2017-12-31 16:36:34 +01:00
Lorenz Meier 7d44567fab IO Proto: Code style 2017-12-31 16:36:34 +01:00
Lorenz Meier 2c148236ae IO Mixer: Code style 2017-12-31 16:36:34 +01:00
Lorenz Meier 0ef245aee1 IO ADC: Code style 2017-12-31 16:36:34 +01:00
Lorenz Meier 168e070f94 IO CMake file: Formatting 2017-12-31 16:36:34 +01:00
Lorenz Meier 51111fc6e3 IO Firmware: Document override behavior for manual override. 2017-12-31 16:36:34 +01:00
Daniel Agar d7aaab07fc delete unused SENSORIOCGQUEUEDEPTH 2017-12-31 09:47:51 -05:00
Daniel Agar 6ad9e59a7a delete unused GPIO_SET_INPUT 2017-12-31 09:47:51 -05:00
Daniel Agar b8b9f15a34 delete unused GPIO_PERIPHERAL_RAIL_RESET 2017-12-31 09:47:51 -05:00
Daniel Agar d61e0651ab delete unused GPIO_SET_OUTPUT_HIGH 2017-12-31 09:47:51 -05:00
Daniel Agar 4c041f12ea delete unused GPIO_SET_OUTPUT_LOW 2017-12-31 09:47:51 -05:00
Daniel Agar f550c8735a delete unused GPIO_SENSOR_RAIL_RESET 2017-12-31 09:47:51 -05:00
Daniel Agar c65db00914 delete unused GPIO_SET_ALT_4 2017-12-31 09:47:51 -05:00
Daniel Agar db5e932f48 delete unused GPIO_SET_ALT_3 2017-12-31 09:47:51 -05:00
Daniel Agar 17e58dc08b delete unused GPIO_SET_ALT_2 2017-12-31 09:47:51 -05:00
Daniel Agar c6760cc6fb delete unused GPIO_SET_ALT_1 2017-12-31 09:47:51 -05:00
Daniel Agar d91b2347dd mpu6000 delete dummy 2017-12-31 09:47:51 -05:00
Daniel Agar badcddc29a delete unused GYROIOCGEXTERNAL 2017-12-31 09:47:51 -05:00
Daniel Agar 98ca693298 delete unused GYROIOCGLOWPASS 2017-12-31 09:47:51 -05:00
Daniel Agar 85e879a574 delete unused GYROIOCSLOWPASS 2017-12-31 09:47:51 -05:00
Daniel Agar 1b4a224223 delete unused GYROIOCGHWLOWPASS 2017-12-31 09:47:51 -05:00
Daniel Agar cc2cf40e6e delete unused GYROIOCSHWLOWPASS 2017-12-31 09:47:51 -05:00
Daniel Agar 8b591aa13a delete unused ACCELIOCGHWLOWPASS 2017-12-31 09:47:51 -05:00
Daniel Agar 0f8f319411 delete unused ACCELIOCSHWLOWPASS 2017-12-31 09:47:51 -05:00
Daniel Agar 63d24a9e1e delete unused ACCELIOCGLOWPASS 2017-12-31 09:47:51 -05:00
Daniel Agar 417351390f delete unused ACCELIOCSLOWPASS 2017-12-31 09:47:51 -05:00
Daniel Agar be930d4372 delete unused PWM_SERVO_CLEAR_OVERRIDE_OK 2017-12-31 09:47:51 -05:00
Daniel Agar dacc45c3d1 delete unused PWM_SERVO_SET_OVERRIDE_OK 2017-12-31 09:47:51 -05:00
Daniel Agar ca6f6b27a5 delete unused PWM_SERVO_SET_RC_CONFIG 2017-12-31 09:47:51 -05:00
Daniel Agar ff6928fb63 delete unused GPIO_GET 2017-12-31 09:47:51 -05:00
Daniel Agar 65f9005bc6 delete unused RC_INPUT_GET 2017-12-31 09:47:51 -05:00
Daniel Agar 32a450f5dd detect_orientation make constants constexpr 2017-12-31 09:47:51 -05:00
Daniel Agar 344cf83549 delete unused SENSORIOCCALTEST 2017-12-31 09:47:51 -05:00
Daniel Agar 4980b93830 delete unused SENSORIOCGROTATION 2017-12-31 09:47:51 -05:00
Daniel Agar 9c378a7ca1 delete unused SENSORIOCSROTATION 2017-12-31 09:47:51 -05:00
Daniel Agar 3ead5c2afd delete unused MAGIOCSLOWPASS/MAGIOCGLOWPASS 2017-12-31 09:47:51 -05:00
Daniel Agar 301be5ed8a delete unused range finder IOCTLs 2017-12-31 09:47:51 -05:00
Daniel Agar 859b19db9a uORB.h reduce orb_metadata field sizes 2017-12-31 09:47:51 -05:00
Lorenz Meier 34ea229a78 Update Gazebo with GUI fix 2017-12-30 20:14:33 +01:00
Lorenz Meier ab30532f52 Update SITL Gazebo with build system fixes 2017-12-30 20:10:00 +01:00
Lorenz Meier 3cc356a703 Gazebo: Update repository to enable video streaming support 2017-12-30 18:17:25 +01:00
Lorenz Meier ab2f85d4ff SITL: Search MAVLink locally 2017-12-30 14:47:37 +01:00
Lorenz Meier 5d4086309f Gazebo: Fix build for Gazebo 8 and tune down GPS noise 2017-12-30 13:05:51 +01:00
Lorenz Meier e3f5f8e475 Update Gazebo submodule to include gimbal fixes 2017-12-30 11:46:55 +01:00
Daniel Agar cbc8b50aa1 sensors don't store diff_pres in class 2017-12-30 11:30:34 +01:00
Daniel Agar 4445ffc70e sensors don't store airspeed in class 2017-12-30 11:30:34 +01:00
Daniel Agar 6623fd0212 sensors don't keep battery_status messages 2017-12-30 11:30:34 +01:00
Ramón Hernán Roche Quintana d57ed6d17f Changelog generator default params 2017-12-30 11:27:57 +01:00
Lorenz Meier 6a701adf3c HITL: Remove hard requirement for airframes 2017-12-30 11:24:22 +01:00
Lorenz Meier 2eb3392c39 PWM out sim: Increase stack as needed 2017-12-30 11:24:22 +01:00
Lorenz Meier bb516be61e Commander: Enforce correct system configuration for HITL
This is important to ensure that users are not trying to use HITL with airframes that will not work.
2017-12-30 11:24:22 +01:00
Lorenz Meier 0ae1737e85 Commander: Fix HITL state initialization that prevented pre-flight checks to pass in HITL mode on v1.7.2
This is a minor change that fixes the ordering of the initialization.
2017-12-30 11:24:22 +01:00
Lorenz Meier 644db1b03f State machine helper: Fix typo 2017-12-30 11:24:22 +01:00
Lorenz Meier c31e31bf5e Voted sensors: Better error messages 2017-12-30 11:24:22 +01:00
Lorenz Meier f69a6af989 Commander: increase stack to ensure enough margin remains 2017-12-30 11:24:03 +01:00
Lorenz Meier fa8222e188 Logger: Free some RAM to leave space for mag calibration 2017-12-30 11:24:03 +01:00
Daniel Agar 370da89573 fw_pos_control fix parameter sanity check (#8521)
- the sanity check result wasn't being sent to the user and prevents landing slope, runway takeoff, and launch detector parameter updates.
2017-12-26 16:02:31 -05:00
Lorenz Meier 1cab556ddb Topic listener: Depend on messages, not just on headers
This ensures that the listener is re-built when the message spec changes.
2017-12-26 16:01:11 -05:00
Lorenz Meier 23d15c1365 Platform: Depend on messages, not just on headers
This ensures that platform is re-built if messages change.
2017-12-26 16:01:11 -05:00
Lorenz Meier 72823e6eb4 MicroRTPS bridge: Depend on messages, not just on headers
This ensures that an update of the message spec re-generates the bridge.
;
2017-12-26 16:01:11 -05:00
Daniel Agar fc7c8b4b89 vehicle_status delete engine_failure_cmd 2017-12-27 02:41:10 +08:00
Daniel Agar 17e17d79dd commander delete unused vtol_transition_failure_cmd 2017-12-27 02:41:10 +08:00
Daniel Agar d0fba8bf8b commander delete unused data_link_lost_cmd 2017-12-27 02:41:10 +08:00
Daniel Agar c0be801b5c commander delete unused rc_signal_lost_cmd 2017-12-27 02:41:10 +08:00
Daniel Agar 5a6cde41d5 commander delete unused gps_failure_cmd 2017-12-27 02:41:10 +08:00
Daniel Agar ca804a2308 commander delete unused sensors check 2017-12-27 02:41:10 +08:00
Daniel Agar 294fbc46a9 commander initial class structure 2017-12-27 02:41:10 +08:00
Amir Melzer 55be098e3b adis16448 bmlz fixes (#8519)
* small bit mask fix

* Restore factory calibration values in drivers start-up sequence

* Restore factory calibration values in drivers start-up sequence (reverted from commit 09ba45501f87f77e53d670fcf880b3cfc419fe38)

* Restore factory calibration values in drivers start-up sequence

* Initialization of the Adis16448 report struct

* Add stall time after write and read cycle

* Increasing the stall time for being compatible with the B sensor version

* small clean up

* Add settling time after initialization
2017-12-22 13:17:54 -05:00
Daniel Agar 5d6edcc15d commander consolidate periodic state publishing 2017-12-22 10:42:14 -05:00
Daniel Agar 1ea5de43cf logger add vehicle_status_flags 2017-12-22 10:42:14 -05:00
Daniel Agar 043ad3c33e commander vehicle_status_flags only publish if changed 2017-12-22 10:42:14 -05:00
Paul Riseborough 176738c688 commander: add missing px4_close (#8513) 2017-12-22 08:57:06 +11:00
Daniel Agar ec57832a8f FW land detector increase trigger time and cleanup (#8486) 2017-12-21 12:17:32 -05:00
Daniel Agar 7dab5d4380 mission feasibility full home position isn't always needed 2017-12-21 15:28:45 +08:00
Daniel Agar b7189012dc Revert "Fix for HobbyKing boards."
This reverts commit 75b93b0728.
2017-12-21 15:25:25 +08:00
Hamish Willee 2f50a07afb Delete redundant documentation files (#8505) 2017-12-21 02:06:41 -05:00
CarlOlsson 925c65b4d5 ekf2: add beta innovation gate to parameters
Signed-off-by: CarlOlsson <carlolsson.co@gmail.com>
2017-12-21 04:02:10 +08:00
Daniel Agar 58d1cdc733 Allow MAV_CMD_DO_SET_HOME as a mission command 2017-12-20 10:19:07 +01:00
sanderux a8c26265b5 Check manual home set when setting during arming 2017-12-20 10:19:07 +01:00
Daniel Agar 964cb486a9 home_position delete unused direction_{x, y, z} 2017-12-20 10:19:07 +01:00
Daniel Agar 375ae991bc commander DO_SET_HOME populate local coordinates
- unify commander home update
2017-12-20 10:19:07 +01:00
sanderux cf7ad67678 Check home reset in local frame 2017-12-20 10:19:07 +01:00
sanderux 4e175d13c4 Set manual_home when home set manually 2017-12-20 10:19:07 +01:00
sanderux 74868f8c2b Reset home position when landed and disarmed 2017-12-20 10:19:07 +01:00
Daniel Agar 6172315cf7 navigator mission_result fix increment sign 2017-12-20 17:05:25 +08:00
Daniel Agar a4be7ae7d0 commander mission_result check time and instance 2017-12-20 17:05:25 +08:00
Hamish Willee 7a9f7eb424 Updates to README
- Link supported airframes to the Airframe reference rather than portfolio pages (they may look pretty, but nowhere near as useful for developers. Add portfolio link up top.
- Change the somewhat empty "Project Milestones" to "Project Roadmap" and link to the high level roadmap. I removed the only milestone about Lorenz creating the software. If we end up adding a more detailed milestone section that could go in. 
- Added clear guidelines for users vs developers.
2017-12-20 05:22:43 +08:00
ChristophTobler 4bd7d62b5c ekf2: update AID_MASK bitmask comment for QGC 2017-12-20 05:22:11 +08:00
Pietro De Nicolao aea8985c8d Fix links to supported hardware in README.md (#8476) 2017-12-18 11:23:32 -05:00
Beat Küng 3da8031e8e uorb graph: improve error output 2017-12-18 10:19:15 +01:00
Beat Küng eeff52cda7 uorb_graph: add .gitignore, change graph file for sitl runtime config 2017-12-18 10:19:15 +01:00
Beat Küng ec50193d6c Makefile: add uorb_graphs target 2017-12-18 10:19:15 +01:00
Beat Küng 5195210893 CMakeLists.txt: add custom target uorb_graph to generate the graph JSON files
Use like this:
	  make px4fmu-v2_default uorb_graph
2017-12-18 10:19:15 +01:00
Beat Küng 57f92250b3 uorb graph create.py: sort modules & topics by name length for JSON output 2017-12-18 10:19:15 +01:00
Beat Küng 9bff0c8c04 uorb graphs: add script to create graph from a posix startup script 2017-12-18 10:19:15 +01:00
Beat Küng e2d6c0a8f9 uorb_graph: add script to generate uORB pub/sub graphs
2 possible output formats:
- JSON (can be used with D3.js)
- Graphviz

Not covered yet: Publication & Subscription classes
2017-12-18 10:19:15 +01:00
Daniel Agar d5bb948cbb README fix LICENSE link 2017-12-17 11:33:19 -05:00
Daniel Agar a4b127960b README switch travis-ci build status to Jenkins 2017-12-17 11:33:19 -05:00
Daniel Agar e8624f8afe navigator takeoff alt check use altitude acceptance (#8480) 2017-12-17 01:39:53 -05:00
Daniel Agar 28d1ec8afe VTOL defaults set MIS_TAKEOFF_ALT 20 and remove tuning (#8481) 2017-12-17 00:58:23 -05:00
Daniel Agar 642aeccd1e logger add home_position to the default set 2017-12-17 00:57:17 -05:00
James Goppert 75b93b0728 Fix for HobbyKing boards. 2017-12-16 21:05:18 +00:00
Daniel Agar a15ca72288 Jenkins add posix_sitl_default and posix_sitl_rtps 2017-12-15 14:31:25 -05:00
Daniel Agar 4beeb7f560 delete obsolete s3 upload helpers 2017-12-15 14:31:25 -05:00
Daniel Agar baff0832bc Jenkins clang scan-build output publisher 2017-12-15 14:31:25 -05:00
Daniel Agar c398c95fd5 Jenkins px4io-v2 build in same directory 2017-12-15 14:31:25 -05:00
Daniel Agar b1315a71ec Jenkins add cppcheck build 2017-12-15 14:31:25 -05:00
Daniel Agar 670111875e Jenkins add clang static analyzer (scan-build) 2017-12-15 14:31:25 -05:00
Daniel Agar e4180f6a72 Jenkins split GCC 7 posix & nuttx tests
- this groups the builds together properly
2017-12-15 14:31:25 -05:00
Daniel Agar 868ff42f47 check_submodules.sh handle CI forced update only if directory exists 2017-12-15 14:31:25 -05:00
Daniel Agar cebe7add8b Jenkins move style check to tests 2017-12-15 14:31:25 -05:00
Daniel Agar d7aa5df3cd Jenkins enable clang-tidy build 2017-12-15 14:31:25 -05:00
490 changed files with 5239 additions and 34587 deletions
+33
View File
@@ -0,0 +1,33 @@
# How to install:
# gem install github_changelog_generator
# How to run:
# github_changelog_generator -u PX4 -p Firmware
# Description:
# The following params are sensible defaults for the PX4 project,
# if you want to do a changelog before a release you need to update since-tag and future-releases,
# Params:
# github_changelog_generator --help for all options
# max-issues
# max threshold for github api queries
# make sure you set your CHANGELOG_GITHUB_TOKEN before
# running
max-issues=1500
# exclude-tags-regex
# excludes release candidates
exclude-tags-regex=rc[0-9]{1,}|beta[0-9]{1,}
# since-tag
# version of last stable release
# you need to change this depending on what you need
# if you want a changelog between versions this is the lowest version
since-tag=1.6.5
# future-release
# version you are about to release
# if you want a changelog between a version and all unreleased changes grouped as a release
# eg: v1.6.5 to v1.7.0
future-release=v1.7.0
+29 -5
View File
@@ -110,7 +110,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PX4_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PX4_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PX4_BINARY_DIR})
list(APPEND CMAKE_MODULE_PATH "${PX4_SOURCE_DIR}/cmake")
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/cmake)
#=============================================================================
# git
@@ -155,6 +155,9 @@ if (NOT EXTERNAL_MODULES_LOCATION STREQUAL "")
get_filename_component(EXTERNAL_MODULES_LOCATION "${EXTERNAL_MODULES_LOCATION}" ABSOLUTE)
endif()
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/platforms/${OS}/cmake)
include(platforms/${OS}/cmake/px4_impl_os.cmake)
set(config_module "configs/${CONFIG}")
include(${config_module})
@@ -243,11 +246,11 @@ set(BUILD_SHARED_LIBS OFF)
#=============================================================================
# ccache
#
option(CCACHE "Use ccache if available" OFF)
option(CCACHE "Use ccache if available" ON)
find_program(CCACHE_PROGRAM ccache)
if (CCACHE AND CCACHE_PROGRAM)
message(STATUS "Enabled ccache: ${CCACHE_PROGRAM}")
if (CCACHE AND CCACHE_PROGRAM AND NOT DEFINED ENV{CCACHE_DISABLE})
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
else()
endif()
#=============================================================================
@@ -398,7 +401,7 @@ foreach(module ${config_module_list})
add_subdirectory(src/${module})
endforeach()
add_subdirectory(src/firmware/${OS})
add_subdirectory(platforms/${OS})
#=============================================================================
# generate custom target to print for all executable and module cmake targets
@@ -413,6 +416,27 @@ if (all_posix_cmake_targets)
)
endif()
#=============================================================================
# uORB graph generation: add a custom target 'uorb_graph'
#
set(uorb_graph_config ${BOARD})
set(graph_module_list "")
foreach(module ${config_module_list})
set(graph_module_list "${graph_module_list}" "--src-path" "src/${module}")
endforeach()
add_custom_command(OUTPUT ${uorb_graph_config}
COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/uorb_graph/create.py
${module_list}
--exclude-path src/examples
--file ${PX4_SOURCE_DIR}/Tools/uorb_graph/graph_${uorb_graph_config}
WORKING_DIRECTORY ${PX4_SOURCE_DIR}
COMMENT "Generating uORB graph"
)
add_custom_target(uorb_graph DEPENDS ${uorb_graph_config})
#=============================================================================
# packaging
#
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

-98
View File
@@ -1,98 +0,0 @@
[TOC]
# Introduction
The HIL architecture allows you to test the flight stack replacing the real physical vehicle and sensors with a simulator of vehicle dynamics and sensor outputs. The flight stack "is not aware" that it is not on a real vehicle. This is a powerful tool for develping and testing code rapidly in a benchtop environment.
The flight stack can be run anywhere that supports a network connection to the simulator (with sufficient bandwidth and latency to transport the sensor and actuator messages). This can be on a standard linux workstation, an on-target linux image, or the on-target DSP image. These modes can be selected based on the goals of the testing. Workstation is useful for rapid testing in a tool-rich environment. DSP image testing is the closest to the final implementation, so is useful for testing actual HW operation, other than the physical sensing and actuation.
## Px4 High-level HIL Architecture
A diagram of the setup described is shown here. Note that UDP port numbers are only displayed on the socket server and are left blank on the socket client.
(???NOTES: This diagram needs to be updated to use control inputs over UDP, either from QGC or from other)
![SITL Diagram](./SITL_Diagram_QGC.png "SITL Diagram")
## Requirements
The simulator that is currently supported is jMAVSim. The setup described here requires PX4 and jMAVSim installed and running. qGroundControl (QGC) is also required because it is the supported method of providing manual control commands.
## Assumptions
# Compiling Code
## JMAVSim
### Platform Requirements
Linux with java-1.7.x or greater
### Build Instructions
In a clean directory
```
> git clone https://github.com/PX4/jMAVSim.git
> cd jMAVSim
> git submodule init
> git submodule update
> ant
```
## qGroundControl
### Platform Requirements
Windows 7
Logitech Gamepad F310 joystick controller
### Download/Install Instructions
Download QGC from http://qgroundcontrol.org/downloads and install using the windows executable.
## PX4
### Platform Requirements
Linux or Eagle with a working IP interface (?? does this need further instructions?)
### Build Host Requirements
(???Notes: Windows?)
### Download & Build Instructions
### Installing binaries on the Qualcomm Target
# Running PX4 in HIL Mode
## Starting PX4 on Qualcomm Eagle
```
> adb shell
# bash
root@linaro-developer:/# cd ???
root@linaro-developer:/# ./px4
App name: px4
Enter a command and its args:
uorb start
muorb start
mavlink start -u 14556
simulator start -p
```
## Starting jMAVSim
In the directory where jMAVSim is installed
```
java -cp lib/*:out/production/jmavsim.jar me.drton.jmavsim.Simulator -udp <IPADDR>:14560 -n 100
```
replacing <IPADDR> with the IP address of the machine running PX4 (Eagle). This can be found by running "ifconfig" on that machine.
## Starting qGroundControl
Launch the qGroundControl application
1. Set up the communication to the flight stack. In the menu File:Settings:CommLinks, select Add. Enter a Link Name of your choice. Select Link Type: UDP. Set the listening port to an unused port (example: 14561). Select Add. Enter the IP address and port of the PX4 Mavlink app, which is <IPADDR>:14556 with <IPADDR> being the IP address of the Eagle board. Select OK.
1. Set up the joystick. Plug in the joystick to your Windows machine. In the menu File:Settings:CommLinks, check Enable Controllers. Select "Gamepad F310". Select "Manual". Set the axes/channel mapping to 0:Yaw, 1:Throttle, 2:unset, 3:Pitch, 4:Roll. Seletct "Inverted" for the throttle axis. Click "Calibrate range". Move the right joystick through its full range of motion. Move the left joystick full left then full right. Move the left joystick full forward (but not full backward). Click "end calibration."
1. Connect to the flight stack. Click Analyze. Click the "Connect" button in the upper right, and select the connection that you created in the first step.
You should now be connected to the flight stack. You can see incoming Mavlink packets using the MAVLink Instpector (from Advanced:Tool Widgets)
## Controlling PX4 flight in HIL Mode
The joystick can now be used to fly the simulated vehicle. The jMAVSim world visualization gives a FPV view, and QGC can be used to display instruments such as artificial horizon and maps (if GPS simulation is enabled).
# Debugging/FAQ
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
-2
View File
@@ -1,2 +0,0 @@
#!/bin/sh
git log --pretty=format:"Last change: commit %h - %aN, %ar : %s" -1 $1 || echo no git
Vendored
+369 -37
View File
@@ -1,17 +1,6 @@
pipeline {
agent none
stages {
stage('Quality Checks') {
agent {
docker {
image 'px4io/px4-dev-base:2017-10-23'
args '-e CI=true'
}
}
steps {
sh 'make check_format'
}
}
stage('Build') {
steps {
@@ -55,7 +44,7 @@ pipeline {
sh "make clean"
sh "ccache -z"
sh "git fetch --tags"
sh "make nuttx_px4io-v2_default"
sh "make px4io-v2_default"
sh "make nuttx_px4fmu-v2_default"
sh "make nuttx_px4fmu-v2_lpe"
sh "make nuttx_px4fmu-v3_default"
@@ -118,6 +107,28 @@ pipeline {
}
// posix_sitl
for (def option in ["sitl_default", "sitl_rtps"]) {
def node_name = "${option}"
builds["${node_name}"] = {
node {
stage("Build Test ${node_name}") {
docker.image('px4io/px4-dev-base:2017-12-30').inside('-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw') {
stage("${node_name}") {
checkout scm
sh "make clean"
sh "ccache -z"
sh "make posix_${node_name}"
sh "ccache -s"
}
}
}
}
}
}
// raspberry pi and bebop (armhf)
for (def option in ["rpi_cross", "bebop_default"]) {
def node_name = "${option}"
@@ -125,7 +136,7 @@ pipeline {
builds["${node_name}"] = {
node {
stage("Build Test ${node_name}") {
docker.image('px4io/px4-dev-raspi:2017-10-23').inside('-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw') {
docker.image('px4io/px4-dev-raspi:2017-12-30').inside('-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw') {
stage("${node_name}") {
checkout scm
sh "make clean"
@@ -147,7 +158,7 @@ pipeline {
builds["${node_name}"] = {
node {
stage("Build Test ${node_name}") {
docker.image('px4io/px4-dev-armhf:2017-10-23').inside('-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw') {
docker.image('px4io/px4-dev-armhf:2017-12-30').inside('-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw') {
stage("${node_name}") {
checkout scm
sh "make clean"
@@ -170,7 +181,7 @@ pipeline {
node {
stage("Build Test ${node_name}") {
docker.withRegistry('https://registry.hub.docker.com', 'docker_hub_dagar') {
docker.image("lorenzmeier/px4-dev-snapdragon:2017-10-23").inside {
docker.image("lorenzmeier/px4-dev-snapdragon:2017-12-29").inside('-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw') {
stage("${node_name}") {
checkout scm
sh "make clean"
@@ -186,8 +197,29 @@ pipeline {
}
// GCC7 tests
for (def option in ["posix_sitl_default", "nuttx_px4fmu-v5_default"]) {
// GCC7 posix
for (def option in ["sitl_default"]) {
def node_name = "${option}"
builds["${node_name} (GCC7)"] = {
node {
stage("Build Test ${node_name} (GCC7)") {
docker.image('px4io/px4-dev-base-archlinux:2017-12-30').inside('-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw') {
stage("${node_name}") {
checkout scm
sh "make clean"
sh "ccache -z"
sh "make posix_${node_name}"
sh "ccache -s"
}
}
}
}
}
}
// GCC7 nuttx
for (def option in ["px4fmu-v5_default"]) {
def node_name = "${option}"
builds["${node_name} (GCC7)"] = {
@@ -198,7 +230,7 @@ pipeline {
checkout scm
sh "make clean"
sh "ccache -z"
sh "make ${node_name}"
sh "make nuttx_${node_name}"
sh "ccache -s"
}
}
@@ -215,24 +247,95 @@ pipeline {
stage('Test') {
parallel {
// temporarily disabled until build resources are available
//stage('clang-tidy') {
// agent {
// docker {
// image 'px4io/px4-dev-clang:2017-10-23'
// args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw'
// }
// }
// steps {
// sh 'make clean'
// sh 'make clang-tidy-quiet'
// }
//}
stage('check style') {
agent {
docker {
image 'px4io/px4-dev-base:2017-12-30'
args '-e CI=true'
}
}
steps {
sh 'make check_format'
}
}
stage('clang analyzer') {
agent {
docker {
image 'px4io/px4-dev-clang:2017-12-30'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw'
}
}
steps {
sh 'make clean'
sh 'make scan-build'
// publish html
publishHTML target: [
reportTitles: 'clang static analyzer',
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'build/scan-build/report_latest',
reportFiles: '*',
reportName: 'Clang Static Analyzer'
]
}
when {
anyOf {
branch 'master'
branch 'beta'
branch 'stable'
}
}
}
stage('clang tidy') {
agent {
docker {
image 'px4io/px4-dev-clang:2017-12-30'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw'
}
}
steps {
sh 'make clean'
sh 'make clang-tidy-quiet'
}
}
stage('cppcheck') {
agent {
docker {
image 'px4io/px4-dev-base:ubuntu17.10'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw'
}
}
steps {
sh 'make clean'
sh 'make cppcheck'
// publish html
publishHTML target: [
reportTitles: 'Cppcheck',
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'build/cppcheck/',
reportFiles: '*',
reportName: 'Cppcheck'
]
}
when {
anyOf {
branch 'master'
branch 'beta'
branch 'stable'
}
}
}
stage('tests') {
agent {
docker {
image 'px4io/px4-dev-base:2017-10-23'
image 'px4io/px4-dev-base:2017-12-30'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw'
}
}
@@ -243,11 +346,227 @@ pipeline {
}
}
stage('ROS vtol mission new 1') {
agent {
docker {
image 'px4io/px4-dev-ros:2017-12-31'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw -e HOME=$WORKSPACE'
}
}
steps {
sh 'make clean; rm -rf .ros; rm -rf .gazebo'
sh 'git fetch --tags'
sh 'make posix_sitl_default'
sh 'make posix_sitl_default sitl_gazebo'
sh './test/rostest_px4_run.sh mavros_posix_test_mission.test mission:=vtol_new_1.txt vehicle:=vtol_standard'
}
post {
success {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_new_1.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI .ros/rootfs/fs/microsd/log/*/*.ulg'
}
failure {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_new_1.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI --email "${CHANGE_AUTHOR_EMAIL}" .ros/rootfs/fs/microsd/log/*/*.ulg'
archiveArtifacts '**/*.ulg'
archiveArtifacts '.ros/*/px4/**.xml'
archiveArtifacts '.ros/log/**.log'
}
}
}
stage('ROS vtol mission new 2') {
agent {
docker {
image 'px4io/px4-dev-ros:2017-12-31'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw -e HOME=$WORKSPACE'
}
}
steps {
sh 'make clean; rm -rf .ros; rm -rf .gazebo'
sh 'git fetch --tags'
sh 'make posix_sitl_default'
sh 'make posix_sitl_default sitl_gazebo'
sh './test/rostest_px4_run.sh mavros_posix_test_mission.test mission:=vtol_new_2.txt vehicle:=vtol_standard'
}
post {
success {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_new_2.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI .ros/rootfs/fs/microsd/log/*/*.ulg'
}
failure {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_new_2.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI --email "${CHANGE_AUTHOR_EMAIL}" .ros/rootfs/fs/microsd/log/*/*.ulg'
archiveArtifacts '**/*.ulg'
archiveArtifacts '.ros/*/px4/**.xml'
archiveArtifacts '.ros/log/**.log'
}
}
}
stage('ROS vtol mission old 1') {
agent {
docker {
image 'px4io/px4-dev-ros:2017-12-31'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw -e HOME=$WORKSPACE'
}
}
steps {
sh 'make clean; rm -rf .ros; rm -rf .gazebo'
sh 'git fetch --tags'
sh 'make posix_sitl_default'
sh 'make posix_sitl_default sitl_gazebo'
sh './test/rostest_px4_run.sh mavros_posix_test_mission.test mission:=vtol_old_1.txt vehicle:=vtol_standard'
}
post {
success {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_old_1.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI .ros/rootfs/fs/microsd/log/*/*.ulg'
}
failure {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_old_1.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI --email "${CHANGE_AUTHOR_EMAIL}" .ros/rootfs/fs/microsd/log/*/*.ulg'
archiveArtifacts '**/*.ulg'
archiveArtifacts '.ros/*/px4/**.xml'
archiveArtifacts '.ros/log/**.log'
}
}
}
stage('ROS vtol mission old 2') {
agent {
docker {
image 'px4io/px4-dev-ros:2017-12-31'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw -e HOME=$WORKSPACE'
}
}
steps {
sh 'make clean; rm -rf .ros; rm -rf .gazebo'
sh 'git fetch --tags'
sh 'make posix_sitl_default'
sh 'make posix_sitl_default sitl_gazebo'
sh './test/rostest_px4_run.sh mavros_posix_test_mission.test mission:=vtol_old_2.txt vehicle:=vtol_standard'
}
post {
success {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_old_2.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI .ros/rootfs/fs/microsd/log/*/*.ulg'
}
failure {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_old_2.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI --email "${CHANGE_AUTHOR_EMAIL}" .ros/rootfs/fs/microsd/log/*/*.ulg'
archiveArtifacts '**/*.ulg'
archiveArtifacts '.ros/*/px4/**.xml'
archiveArtifacts '.ros/log/**.log'
}
}
}
stage('ROS vtol mission old 3') {
agent {
docker {
image 'px4io/px4-dev-ros:2017-12-31'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw -e HOME=$WORKSPACE'
}
}
steps {
sh 'make clean; rm -rf .ros; rm -rf .gazebo'
sh 'git fetch --tags'
sh 'make posix_sitl_default'
sh 'make posix_sitl_default sitl_gazebo'
sh './test/rostest_px4_run.sh mavros_posix_test_mission.test mission:=vtol_old_3.txt vehicle:=vtol_standard'
}
post {
success {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_old_3.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI .ros/rootfs/fs/microsd/log/*/*.ulg'
}
failure {
sh './Tools/upload_log.py -q --description "ROS mission test vtol_old_3.txt: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI --email "${CHANGE_AUTHOR_EMAIL}" .ros/rootfs/fs/microsd/log/*/*.ulg'
archiveArtifacts '**/*.ulg'
archiveArtifacts '.ros/*/px4/**.xml'
archiveArtifacts '.ros/log/**.log'
}
}
}
stage('ROS MC mission box') {
agent {
docker {
image 'px4io/px4-dev-ros:2017-12-31'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw -e HOME=$WORKSPACE'
}
}
steps {
sh 'make clean; rm -rf .ros; rm -rf .gazebo'
sh 'git fetch --tags'
sh 'make posix_sitl_default'
sh 'make posix_sitl_default sitl_gazebo'
sh './test/rostest_px4_run.sh mavros_posix_test_mission.test mission:=multirotor_box.mission vehicle:=iris'
}
post {
success {
sh './Tools/upload_log.py -q --description "ROS mission test multirotor_box.mission: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI .ros/rootfs/fs/microsd/log/*/*.ulg'
}
failure {
sh './Tools/upload_log.py -q --description "ROS mission test multirotor_box.mission: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI --email "${CHANGE_AUTHOR_EMAIL}" .ros/rootfs/fs/microsd/log/*/*.ulg'
archiveArtifacts '**/*.ulg'
archiveArtifacts '.ros/*/px4/**.xml'
archiveArtifacts '.ros/log/**.log'
}
}
}
stage('ROS offboard att') {
agent {
docker {
image 'px4io/px4-dev-ros:2017-12-31'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw -e HOME=$WORKSPACE'
}
}
steps {
sh 'make clean; rm -rf .ros; rm -rf .gazebo'
sh 'git fetch --tags'
sh 'make posix_sitl_default'
sh 'make posix_sitl_default sitl_gazebo'
sh './test/rostest_px4_run.sh mavros_posix_tests_offboard_attctl.test'
}
post {
success {
sh './Tools/upload_log.py -q --description "ROS offboard attitude test: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI .ros/rootfs/fs/microsd/log/*/*.ulg'
}
failure {
sh './Tools/upload_log.py -q --description "ROS offboard attitude test: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI --email "${CHANGE_AUTHOR_EMAIL}" .ros/rootfs/fs/microsd/log/*/*.ulg'
archiveArtifacts '**/*.ulg'
archiveArtifacts '.ros/*/px4/**.xml'
archiveArtifacts '.ros/log/**.log'
}
}
}
stage('ROS offboard pos') {
agent {
docker {
image 'px4io/px4-dev-ros:2017-12-31'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw -e HOME=$WORKSPACE'
}
}
steps {
sh 'make clean; rm -rf .ros; rm -rf .gazebo'
sh 'git fetch --tags'
sh 'make posix_sitl_default'
sh 'make posix_sitl_default sitl_gazebo'
sh './test/rostest_px4_run.sh mavros_posix_tests_offboard_posctl.test'
}
post {
success {
sh './Tools/upload_log.py -q --description "ROS offboard position test: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI .ros/rootfs/fs/microsd/log/*/*.ulg'
}
failure {
sh './Tools/upload_log.py -q --description "ROS offboard position test: ${CHANGE_ID}" --feedback "${CHANGE_TITLE} - ${CHANGE_URL}" --source CI --email "${CHANGE_AUTHOR_EMAIL}" .ros/rootfs/fs/microsd/log/*/*.ulg'
archiveArtifacts '**/*.ulg'
archiveArtifacts '.ros/*/px4/**.xml'
archiveArtifacts '.ros/log/**.log'
}
}
}
// temporarily disabled until stable
//stage('tests coverage') {
// agent {
// docker {
// image 'px4io/px4-dev-base:2017-10-23'
// image 'px4io/px4-dev-base:2017-12-30'
// args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw'
// }
// }
@@ -275,7 +594,7 @@ pipeline {
stage('airframe') {
agent {
docker { image 'px4io/px4-dev-base:2017-10-23' }
docker { image 'px4io/px4-dev-base:2017-12-30' }
}
steps {
sh 'make airframe_metadata'
@@ -285,7 +604,7 @@ pipeline {
stage('parameter') {
agent {
docker { image 'px4io/px4-dev-base:2017-10-23' }
docker { image 'px4io/px4-dev-base:2017-12-30' }
}
steps {
sh 'make parameters_metadata'
@@ -295,19 +614,32 @@ pipeline {
stage('module') {
agent {
docker { image 'px4io/px4-dev-base:2017-10-23' }
docker { image 'px4io/px4-dev-base:2017-12-30' }
}
steps {
sh 'make module_documentation'
archiveArtifacts(artifacts: 'modules/*.md', fingerprint: true)
}
}
stage('uorb graphs') {
agent {
docker {
image 'px4io/px4-dev-nuttx:2017-12-30'
args '-e CI=true -e CCACHE_BASEDIR=$WORKSPACE -e CCACHE_DIR=/tmp/ccache -v /tmp/ccache:/tmp/ccache:rw -e HOME=$WORKSPACE'
}
}
steps {
sh 'make uorb_graphs'
archiveArtifacts(artifacts: 'Tools/uorb_graph/graph_sitl.json')
}
}
}
}
stage('S3 Upload') {
agent {
docker { image 'px4io/px4-dev-base:2017-10-23' }
docker { image 'px4io/px4-dev-base:2017-12-30' }
}
when {
+29 -33
View File
@@ -218,7 +218,7 @@ check_rtps: \
check_posix_sitl_rtps \
sizes
.PHONY: sizes check quick_check check_rtps
.PHONY: sizes check quick_check check_rtps uorb_graphs
sizes:
@-find build -name *.elf -type f | xargs size 2> /dev/null || :
@@ -235,6 +235,14 @@ check_%:
@$(MAKE) --no-print-directory $(subst check_,,$@)
@echo
uorb_graphs:
@./Tools/uorb_graph/create_from_startupscript.sh
@./Tools/uorb_graph/create.py --src-path src --exclude-path src/examples --file Tools/uorb_graph/graph_full
@$(MAKE) --no-print-directory px4fmu-v2_default uorb_graph
@$(MAKE) --no-print-directory px4fmu-v4_default uorb_graph
@$(MAKE) --no-print-directory posix_sitl_default uorb_graph
.PHONY: coverity_scan
coverity_scan: posix_sitl_default
@@ -256,37 +264,6 @@ module_documentation:
px4_metadata: parameters_metadata airframe_metadata module_documentation
# S3 upload helpers
# --------------------------------------------------------------------
# s3cmd uses these ENV variables
# AWS_ACCESS_KEY_ID
# AWS_SECRET_ACCESS_KEY
# AWS_S3_BUCKET
.PHONY: s3put_firmware s3put_qgc_firmware s3put_px4fmu_firmware s3put_misc_qgc_extra_firmware s3put_metadata s3put_scan-build s3put_cppcheck s3put_coverage
s3put_qgc_firmware: s3put_px4fmu_firmware s3put_misc_qgc_extra_firmware
s3put_px4fmu_firmware: px4fmu_firmware
@find $(SRC_DIR)/build -name "*.px4" -exec $(SRC_DIR)/Tools/s3put.sh "{}" \;
s3put_misc_qgc_extra_firmware: misc_qgc_extra_firmware
@find $(SRC_DIR)/build -name "*.px4" -exec $(SRC_DIR)/Tools/s3put.sh "{}" \;
s3put_metadata: px4_metadata
@$(SRC_DIR)/Tools/s3put.sh airframes.md
@$(SRC_DIR)/Tools/s3put.sh airframes.xml
@$(SRC_DIR)/Tools/s3put.sh parameters.xml
@$(SRC_DIR)/Tools/s3put.sh parameters.md
s3put_scan-build: scan-build
@$(SRC_DIR)/Tools/s3put.sh `find $(SRC_DIR)/build/scan-build -mindepth 1 -maxdepth 1 -type d`/
s3put_cppcheck: cppcheck
@$(SRC_DIR)/Tools/s3put.sh $(SRC_DIR)/build/cppcheck/
s3put_coverage: tests_coverage
@$(SRC_DIR)/Tools/s3put.sh $(SRC_DIR)/build/posix_sitl_default/coverage-html/
# Astyle
# --------------------------------------------------------------------
.PHONY: check_format format
@@ -302,7 +279,7 @@ format:
# Testing
# --------------------------------------------------------------------
.PHONY: tests tests_coverage
.PHONY: tests tests_coverage tests_mission tests_offboard rostest
tests:
@$(MAKE) --no-print-directory posix_sitl_default test_results \
@@ -310,9 +287,25 @@ tests:
UBSAN_OPTIONS="color=always"
tests_coverage:
@$(MAKE) clean
@$(MAKE) --no-print-directory posix_sitl_default PX4_CMAKE_BUILD_TYPE=Coverage
@$(MAKE) --no-print-directory posix_sitl_default sitl_gazebo PX4_CMAKE_BUILD_TYPE=Coverage
@$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_missions.test
@$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_offboard_attctl.test
@$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_offboard_posctl.test
@$(MAKE) --no-print-directory posix_sitl_default test_coverage_genhtml PX4_CMAKE_BUILD_TYPE=Coverage
@echo "Open $(SRC_DIR)/build/posix_sitl_default/coverage-html/index.html to see coverage"
rostest: posix_sitl_default
@$(MAKE) --no-print-directory posix_sitl_default sitl_gazebo
tests_mission: rostest
@$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_missions.test
tests_offboard: rostest
@$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_offboard_attctl.test
@$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_offboard_posctl.test
# static analyzers (scan-build, clang-tidy, cppcheck)
# --------------------------------------------------------------------
.PHONY: scan-build posix_sitl_default-clang clang-tidy clang-tidy-fix clang-tidy-quiet cppcheck check_stack
@@ -320,9 +313,12 @@ tests_coverage:
scan-build:
@export CCC_CC=clang
@export CCC_CXX=clang++
@rm -rf $(SRC_DIR)/build/posix_sitl_default-scan-build
@rm -rf $(SRC_DIR)/build/scan-build/report_latest
@mkdir -p $(SRC_DIR)/build/posix_sitl_default-scan-build
@cd $(SRC_DIR)/build/posix_sitl_default-scan-build && scan-build cmake $(SRC_DIR) -GNinja -DCONFIG=posix_sitl_default
@scan-build -o $(SRC_DIR)/build/scan-build cmake --build $(SRC_DIR)/build/posix_sitl_default-scan-build
@find $(SRC_DIR)/build/scan-build -maxdepth 1 -mindepth 1 -type d -exec cp -r "{}" $(SRC_DIR)/build/scan-build/report_latest \;
posix_sitl_default-clang:
@mkdir -p $(SRC_DIR)/build/posix_sitl_default-clang
+44 -32
View File
@@ -1,34 +1,42 @@
## PX4 Pro Drone Autopilot ##
# PX4 Pro Drone Autopilot
[![Releases](https://img.shields.io/github/release/PX4/Firmware.svg)](https://github.com/PX4/Firmware/releases) [![DOI](https://zenodo.org/badge/22634/PX4/Firmware.svg)](https://zenodo.org/badge/latestdoi/22634/PX4/Firmware) [![Build Status](https://travis-ci.org/PX4/Firmware.svg?branch=master)](https://travis-ci.org/PX4/Firmware) [![Coverity Scan](https://scan.coverity.com/projects/3966/badge.svg?flat=1)](https://scan.coverity.com/projects/3966?tab=overview)
[![Releases](https://img.shields.io/github/release/PX4/Firmware.svg)](https://github.com/PX4/Firmware/releases) [![DOI](https://zenodo.org/badge/22634/PX4/Firmware.svg)](https://zenodo.org/badge/latestdoi/22634/PX4/Firmware)
[![Build Status](http://ci.px4.io:8080/buildStatus/icon?job=Firmware/master)](http://ci.px4.io:8080/blue/organizations/jenkins/Firmware/activity) [![Coverity Scan](https://scan.coverity.com/projects/3966/badge.svg?flat=1)](https://scan.coverity.com/projects/3966?tab=overview)
[![Slack](https://px4-slack.herokuapp.com/badge.svg)](http://slack.px4.io)
This repository holds the [PX4 Pro](http://px4.io) flight control solution for drones, with the main applications located in the [src/modules](https://github.com/PX4/Firmware/tree/master/src/modules) directory. It also contains the PX4 Drone Middleware Platform, which provides drivers and middleware to run drones.
* Official Website: http://px4.io (License: BSD 3-clause, [LICENSE.md](https://github.com/PX4/Firmware/blob/master/LICENSE.md))
* Supported airframes:
* [Multicopters](http://px4.io/portfolio_category/multicopter/)
* [Fixed wing](http://px4.io/portfolio_category/plane/)
* [VTOL](http://px4.io/portfolio_category/vtol/)
* many more experimental types (Rovers, Blimps, Boats, Submarines, etc)
* Releases: [Downloads](https://github.com/PX4/Firmware/releases)
* Official Website: http://px4.io (License: BSD 3-clause, [LICENSE](https://github.com/PX4/Firmware/blob/master/LICENSE))
* [Supported airframes](https://docs.px4.io/en/airframes/airframe_reference.html) ([portfolio](http://px4.io/#airframes)):
* [Multicopters](https://docs.px4.io/en/airframes/airframe_reference.html#copter)
* [Fixed wing](https://docs.px4.io/en/airframes/airframe_reference.html#plane)
* [VTOL](https://docs.px4.io/en/airframes/airframe_reference.html#vtol)
* many more experimental types (Rovers, Blimps, Boats, Submarines, etc)
* Releases: [Downloads](https://github.com/PX4/Firmware/releases)
## PX4 Users
The [PX4 User Guide](https://docs.px4.io/en/) explains how to assemble [supported vehicles](https://docs.px4.io/en/airframes/airframe_reference.html) and fly drones with PX4.
See the [forum and chat](https://docs.px4.io/en/#support) if you need help!
## PX4 Developers
This [Developer Guide](https://dev.px4.io/) is for software developers who want to modify the flight stack and middleware (e.g. to add new flight modes), hardware integrators who want to support new flight controller boards and peripherals, and anyone who wants to get PX4 working on a new (unsupported) airframe/vehicle.
Developers should read the [Guide for Contributions](https://dev.px4.io/en/contribute/).
See the [forum and chat](https://dev.px4.io/en/#support) if you need help!
Please refer to the [user documentation](https://docs.px4.io/en/) and [user forum](http://discuss.px4.io) for flying drones with the PX4 flight stack.
### Weekly Dev Call
The PX4 Dev Team syncs up on a [weekly dev call](https://dev.px4.io/en/contribute/).
The PX4 Dev Team syncs up on a [weekly dev call](https://dev.px4.io/en/contribute/#dev_call).
* [Wednesday 17:00 Central European Time, 11:00 Eastern Time, 08:00 Pacific Standard Time](https://www.google.com/calendar/embed?src=bGludXhmb3VuZGF0aW9uLm9yZ19nMjF0dmFtMjRtN3BtN2poZXYwMWJ2bHFoOEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t)
* [Uber conference (dial-in or web client)](https://www.uberconference.com/lf-dronecode)
* The agenda is announced in advance on the [PX4 Discuss](http://discuss.px4.io/c/weekly-dev-call)
* Issues and PRs may be labelled [devcall](https://github.com/PX4/Firmware/issues?q=is%3Aopen+is%3Aissue+label%3Adevcall) to flag them for discussion
> **Note** The dev call is open to all interested developers (not just the core dev team). This is a great opportunity to meet the team and contribute to the ongoing development of the platform.
### Developers ###
* [Developer Guide](https://dev.px4.io/)
* [Build instructions](https://dev.px4.io/en/setup/building_px4.html)
* [Guide for Contributions](https://dev.px4.io/en/contribute/)
## Maintenance Team
@@ -71,28 +79,32 @@ The PX4 Dev Team syncs up on a [weekly dev call](https://dev.px4.io/en/contribut
* [Airmind MindPX / MindRacer](https://github.com/PX4/Firmware/labels/mindpx) - [Henry Zhang](https://github.com/iZhangHui)
* RTPS/ROS2 Interface - [Vicente Monge](https://github.com/vicenteeprosima)
See also [About Us](http://px4.io/about-us/#development_team) (px4.io) and the [contributors list](https://github.com/PX4/Firmware/graphs/contributors) (Github).
## Supported Hardware
This repository contains code supporting these boards:
* [Snapdragon Flight](https://dev.px4.io/en/flight_controller/snapdragon_flight.html)
* [Intel Aero](https://dev.px4.io/en/flight_controller/intel_aero.html)
* [Raspberry PI with Navio 2](https://dev.px4.io/en/flight_controller/raspberry_pi.html)
* [Snapdragon Flight](https://docs.px4.io/en/flight_controller/snapdragon_flight.html)
* [Intel Aero](https://docs.px4.io/en/flight_controller/intel_aero.html)
* [Raspberry PI with Navio 2](https://docs.px4.io/en/flight_controller/raspberry_pi_navio2.html)
* [Parrot Bebop 2](https://dev.px4.io/en/advanced/parrot_bebop.html)
* FMUv2.x
* [Pixhawk](https://dev.px4.io/en/flight_controller/pixhawk.html)
* Pixhawk Mini
* [Pixfalcon](https://dev.px4.io/en/flight_controller/pixfalcon.html)
* [Pixhawk](https://docs.px4.io/en/flight_controller/pixhawk.html)
* [Pixhawk Mini](https://docs.px4.io/en/flight_controller/pixhawk_mini.html)
* [Pixfalcon](https://docs.px4.io/en/flight_controller/pixfalcon.html)
* FMUv3.x [Pixhawk 2](https://pixhawk.org/modules/pixhawk2)
* FMUv4.x
* [Pixracer](https://dev.px4.io/en/flight_controller/pixracer.html)
* Pixhawk 3 Pro
* [Pixracer](https://docs.px4.io/en/flight_controller/pixracer.html)
* [Pixhawk 3 Pro](https://docs.px4.io/en/flight_controller/pixhawk3_pro.html)
* FMUv5.x (ARM Cortex M7, future Pixhawk)
* STM32F4Discovery (basic support) [Tutorial](https://pixhawk.org/modules/stm32f4discovery)
* Gumstix AeroCore (v1 and v2)
* [STM32F4Discovery](http://www.st.com/en/evaluation-tools/stm32f4discovery.html) (basic support) [Tutorial](https://pixhawk.org/modules/stm32f4discovery)
* [Gumstix AeroCore](https://www.gumstix.com/aerocore-2/) (only v2)
* [Airmind MindPX V2.8](http://www.mindpx.net/assets/accessories/UserGuide_MindPX.pdf)
* [Airmind MindRacer V1.2](http://mindpx.net/assets/accessories/mindracer_user_guide_v1.2.pdf)
* [Bitcraze Crazyflie 2.0](https://dev.px4.io/en/flight_controller/crazyflie2.html)
* [Bitcraze Crazyflie 2.0](https://docs.px4.io/en/flight_controller/crazyflie2.html)
## Project Milestones
Additional information about supported hardware can be found in [PX4 user Guide > Autopilot Hardware](https://docs.px4.io/en/flight_controller/).
The PX4 software and Pixhawk hardware (which has been designed for it) has been created in 2011 by [Lorenz Meier](https://github.com/LorenzMeier).
## Project Roadmap
A high level project roadmap is available [here](https://www.dronecode.org/roadmap/).
@@ -8,7 +8,6 @@
# @maintainer Lorenz Meier <lorenz@px4.io>
#
sh /etc/init.d/rc.mc_defaults
sh /etc/init.d/4001_quad_x
set MIXER quad_x
param set SYS_HITL 1
@@ -17,7 +17,6 @@
# @output AUX4 Rudder
# @output AUX5 Throttle
#
# @board px4fmu-v1 exclude
sh /etc/init.d/rc.vtol_defaults
@@ -16,6 +16,8 @@
#
# @maintainer Roman Bapst <roman@px4.io>
#
# @board px4fmu-v2 exclude
#
sh /etc/init.d/rc.vtol_defaults
+2
View File
@@ -7,6 +7,8 @@
#
# @maintainer Samay Siga <samay_s@icloud.com>
#
# @board px4fmu-v2 exclude
#
sh /etc/init.d/rc.vtol_defaults
+1 -1
View File
@@ -11,7 +11,7 @@
# @type Quadrotor x
# @class Copter
#
# @maintainer Lucas de Marchi
# @maintainer Beat Kueng <beat@px4.io>
#
sh /etc/init.d/rc.mc_defaults
@@ -10,6 +10,8 @@
#
# @maintainer
#
# @board px4fmu-v2 exclude
#
sh /etc/init.d/rc.ugv_defaults
@@ -14,6 +14,8 @@
# @output MAIN7 pass-through of control group 0, channel 6
# @output MAIN8 pass-through of control group 0, channel 7
#
# @board px4fmu-v2 exclude
#
sh /etc/init.d/rc.axialracing_ax10_defaults
@@ -12,6 +12,8 @@
#
# @maintainer Marco Zorzi
#
# @board px4fmu-v2 exclude
#
sh /etc/init.d/rc.ugv_defaults
+29 -2
View File
@@ -69,6 +69,9 @@ fi
if ver hwcmp PX4FMU_V2
then
# V2 build hwtypecmp is always false
set BOARD_FMUV3 0
# External I2C bus
hmc5883 -C -T -X start
lis3mdl -X start
@@ -79,8 +82,6 @@ then
# Internal SPI bus ICM-20608-G
mpu6000 -T 20608 start
# V2 build hwtypecmp is always false
set BOARD_FMUV3 0
# V3 build hwtypecmp supports V2|V2M|V30
if ver hwtypecmp V30
then
@@ -99,6 +100,26 @@ then
fi
fi
# Check if a Pixhack (which reports as V2M) is present
if ver hwtypecmp V2M
then
# Pixhawk Mini doesn't have these sensors,
# so if they are found we know its a Pixhack
# external MPU6K is rotated 180 degrees yaw
if mpu6000 -S -R 4 start
then
set BOARD_FMUV3 20
else
# Check for Pixhack 3.1
# external MPU9250 is rotated 180 degrees yaw
if mpu9250 -S -R 4 start
then
set BOARD_FMUV3 21
fi
fi
fi
if [ $BOARD_FMUV3 != 0 ]
then
# sensor heating is available, but we disable it for now
@@ -372,6 +393,12 @@ then
teraranger start
fi
# Benewake TFMini
if param greater SENS_EN_TFMINI 0
then
tfmini start
fi
# Wait 20 ms for sensors (because we need to wait for the HRT and work queue callbacks to fire)
usleep 20000
sensors start
+9 -12
View File
@@ -4,20 +4,17 @@ set VEHICLE_TYPE vtol
if [ $AUTOCNF == yes ]
then
param set MC_ROLL_P 6.0
param set MC_PITCH_P 6.0
param set MC_YAW_P 4
#
# Default parameters for mission and position handling
#
param set NAV_ACC_RAD 3
param set MPC_TKO_SPEED 1.0
param set MPC_LAND_SPEED 0.7
param set MPC_Z_VEL_MAX_DN 1.5
param set MPC_XY_VEL_MAX 4.0
param set MIS_TAKEOFF_ALT 20
param set MIS_YAW_TMT 10
param set MPC_ACC_HOR_MAX 2.0
param set MPC_LAND_SPEED 0.7
param set MPC_TKO_SPEED 1.0
param set MPC_XY_VEL_MAX 4.0
param set MPC_Z_VEL_MAX_DN 1.5
param set NAV_ACC_RAD 3
param set RTL_LAND_DELAY 0
fi
+3 -10
View File
@@ -60,7 +60,6 @@ set LOG_FILE /fs/microsd/bootlog.txt
# REBOOTWORK this needs to start after the flight control loop
if mount -t vfat /dev/mmcsd0 /fs/microsd
then
echo "[i] microSD mounted: /fs/microsd"
if hardfault_log check
then
tone_alarm error
@@ -79,9 +78,9 @@ else
then
if mount -t vfat /dev/mmcsd0 /fs/microsd
then
echo "INFO [init] MicroSD card formatted"
echo "INFO [init] card formatted"
else
echo "ERROR [init] Format failed"
echo "ERROR [init] format failed"
tone_alarm MNBG
set LOG_FILE /dev/null
fi
@@ -97,7 +96,6 @@ fi
set FRC /fs/microsd/etc/rc.txt
if [ -f $FRC ]
then
echo "INFO [init] Executing script: ${FRC}"
sh $FRC
set MODE custom
fi
@@ -194,7 +192,7 @@ then
set MAV_TYPE none
set FAILSAFE none
set USE_IO no
set LOGGER_BUF 16
set LOGGER_BUF 14
if ver hwcmp PX4FMU_V4
then
@@ -316,8 +314,6 @@ then
if px4io checkcrc ${IO_FILE}
then
echo "[init] PX4IO CRC OK" >> $LOG_FILE
set IO_PRESENT yes
else
tone_alarm MLL32CP8MB
@@ -464,7 +460,6 @@ then
then
if param compare UAVCAN_ENABLE 0
then
echo "OVERRIDING UAVCAN_ENABLE = 3" >> $LOG_FILE
param set UAVCAN_ENABLE 3
fi
fi
@@ -505,7 +500,6 @@ then
if mkblctrl $MKBLCTRL_ARG
then
else
echo "MK start failed" >> $LOG_FILE
tone_alarm $TUNE_ERR
fi
unset MKBLCTRL_ARG
@@ -823,7 +817,6 @@ then
# Still no MAV_TYPE found
if [ $MAV_TYPE == none ]
then
echo "Unknown MAV_TYPE"
param set MAV_TYPE 2
else
param set MAV_TYPE ${MAV_TYPE}
+15 -6
View File
@@ -3,8 +3,17 @@
function check_git_submodule {
# The .git exists in a submodule if init and update have been done.
if [ "$CI" != "true" ] && [[ -f $1"/.git" || -d $1"/.git" ]];
if [[ -f $1"/.git" || -d $1"/.git" ]];
then
if [ "$CI" == "true" ];
then
git submodule sync --recursive -- $1
git submodule update --init --recursive --force -- $1 || true
git submodule update --init --recursive --force -- $1
exit 0
fi
SUBMODULE_STATUS=$(git submodule summary "$1")
STATUSRETVAL=$(echo $SUBMODULE_STATUS | grep -A20 -i "$1")
if ! [[ -z "$STATUSRETVAL" ]];
@@ -35,8 +44,8 @@ then
elif [ "$user_cmd" == "u" ]
then
git submodule sync --recursive -- $1
git submodule update --init --recursive --force --quiet -- $1 || true
git submodule update --init --recursive -- $1
git submodule update --init --recursive -- $1 || true
git submodule update --init --recursive --force -- $1
echo "Submodule fixed, continuing build.."
else
echo "Build aborted."
@@ -44,9 +53,9 @@ then
fi
fi
else
git submodule sync --recursive -- $1
git submodule update --init --recursive --force -- $1 || true
git submodule update --init --recursive --force -- $1
git submodule sync --recursive --quiet -- $1
git submodule update --init --recursive -- $1 || true
git submodule update --init --recursive -- $1
fi
}
+5 -5
View File
@@ -7,22 +7,22 @@ if [ -z ${PX4_DOCKER_REPO+x} ]; then
PX4_DOCKER_REPO="px4io/px4-dev-nuttx:2017-10-23"
elif [[ $@ =~ .*rpi.* ]] || [[ $@ =~ .*bebop.* ]]; then
# posix_rpi_cross, posix_bebop_default
PX4_DOCKER_REPO="px4io/px4-dev-raspi:2017-10-23"
PX4_DOCKER_REPO="px4io/px4-dev-raspi:2017-12-30"
elif [[ $@ =~ .*eagle.* ]] || [[ $@ =~ .*excelsior.* ]]; then
# eagle, excelsior
PX4_DOCKER_REPO="lorenzmeier/px4-dev-snapdragon:2017-10-23"
PX4_DOCKER_REPO="lorenzmeier/px4-dev-snapdragon:2017-12-29"
elif [[ $@ =~ .*ocpoc.* ]]; then
# posix_ocpoc_ubuntu
PX4_DOCKER_REPO="px4io/px4-dev-armhf:2017-10-23"
PX4_DOCKER_REPO="px4io/px4-dev-armhf:2017-12-30"
elif [[ $@ =~ .*clang.* ]] || [[ $@ =~ .*scan-build.* ]]; then
# clang tools
PX4_DOCKER_REPO="px4io/px4-dev-clang:2017-10-23"
PX4_DOCKER_REPO="px4io/px4-dev-clang:2017-12-30"
elif [[ $@ =~ .*cppcheck.* ]]; then
# TODO: remove this once px4io/px4-dev-base updates
PX4_DOCKER_REPO="px4io/px4-dev-base:ubuntu17.10"
elif [[ $@ =~ .*tests* ]]; then
# run all tests with simulation
PX4_DOCKER_REPO="px4io/px4-dev-simulation:2017-10-23"
PX4_DOCKER_REPO="px4io/px4-dev-simulation:2017-12-30"
fi
else
echo "PX4_DOCKER_REPO is set to '$PX4_DOCKER_REPO'";
+9
View File
@@ -488,9 +488,18 @@ class uploader(object):
print("FORCED WRITE, FLASHING ANYWAY!")
else:
raise IOError(msg)
# Prevent uploads where the image would overflow the flash
if self.fw_maxsize < fw.property('image_size'):
raise RuntimeError("Firmware image is too large for this board")
# Prevent uploads where the maximum image size of the board config is smaller than the flash
# of the board. This is a hint the user chose the wrong config and will lack features
# for this particular board.
if self.fw_maxsize > fw.property('image_maxsize'):
raise RuntimeError("Board can accept larger flash images (%u bytes) than board config (%u bytes). Please use the correct board configuration to avoid lacking critical functionality."
% (self.fw_maxsize, fw.property('image_maxsize')))
# OTP added in v4:
if self.bl_rev > 3:
for byte in range(0, 32*6, 4):
-23
View File
@@ -1,23 +0,0 @@
#!/bin/bash
filename=${1}
# Requires these ENV variables
# AWS_ACCESS_KEY_ID
# AWS_SECRET_ACCESS_KEY
# AWS_S3_BUCKET
[ -z "$AWS_ACCESS_KEY_ID" ] && { echo "ERROR: Need to set AWS_ACCESS_KEY_ID"; exit 1; }
[ -z "$AWS_SECRET_ACCESS_KEY" ] && { echo "ERROR: Need to set AWS_SECRET_ACCESS_KEY"; exit 1; }
[ -z "$AWS_S3_BUCKET" ] && { echo "ERROR: Need to set AWS_S3_BUCKET"; exit 1; }
if [ -f ${filename} ]; then
base_file_name=`basename $filename`
s3cmd --access_key=${AWS_ACCESS_KEY_ID} --secret_key=${AWS_SECRET_ACCESS_KEY} put ${filename} s3://${AWS_S3_BUCKET}/${base_file_name}
elif [ -d ${filename} ]; then
dir_name=$filename
s3cmd --access_key=${AWS_ACCESS_KEY_ID} --secret_key=${AWS_SECRET_ACCESS_KEY} put -r ${dir_name} s3://${AWS_S3_BUCKET}/
else
echo "ERROR: ${file} doesn't exist"
exit 1
fi
+2
View File
@@ -0,0 +1,2 @@
*.json
+641
View File
@@ -0,0 +1,641 @@
#! /usr/bin/env python
from __future__ import print_function
import argparse
import os
import codecs
import re
import colorsys
import json
parser = argparse.ArgumentParser(
description='Generate uORB pub/sub dependency graph from source code')
parser.add_argument('-s', '--src-path', action='append',
help='Source path(s) (default=src, can be specified multiple times)',
default=[])
parser.add_argument('-e', '--exclude-path', action='append',
help='Excluded path(s), can be specified multiple times',
default=[])
parser.add_argument('-f', '--file', metavar='file', action='store',
help='output file name prefix',
default='graph')
parser.add_argument('-o', '--output', metavar='output', action='store',
help='output format (json or graphviz)',
default='json')
parser.add_argument('--use-topic-union', action='store_true',
help='''
Use the union of all publication and subscription topics (useful for complete
graphs or only few/single module(s)). The default is to use the intersection
(remove topics that have no subscriber or no publisher)''')
parser.add_argument('-m', '--modules', action='store',
help='Comma-separated whitelist of modules (the module\'s '+
'MAIN, e.g. from a startup script)',
default='')
args = parser.parse_args()
g_debug = False
def dbg_print(string):
if g_debug:
print(string)
def get_N_colors(N, s=0.8, v=0.9):
""" get N distinct colors as a list of hex strings """
HSV_tuples = [(x*1.0/N, s, v) for x in range(N)]
hex_out = []
for rgb in HSV_tuples:
rgb = map(lambda x: int(x*255), colorsys.hsv_to_rgb(*rgb))
hex_out.append("#"+"".join(map(lambda x: format(x, '02x'), rgb)))
return hex_out
class PubSub:
""" Collects either publication or subscription information for nodes
(modules and topics) & edges """
def __init__(self, is_publication, topic_blacklist, orb_pub_sub_regexes, special_cases):
"""
:param is_publication: if True, publications, False for
subscriptions
:param topic_blacklist: list of topics to blacklist
:param orb_pub_sub_regexes: list of regexes to extract orb calls
(e.g. orb_subscribe). They need to have 2 captures, the second
one is the one capturing ORB_ID(<topic>
"""
self._module_pubsubs = {} # key = module name, value = set of topic names
self._special_cases = special_cases
self._special_cases_matched = None
self._topic_blacklist = topic_blacklist
self._orb_pub_sub_regexes = orb_pub_sub_regexes
if is_publication:
self._method = 'Publication'
else:
self._method = 'Subscription'
def reset(self):
self._special_cases_matched = [False]*len(self._special_cases)
def filter_modules(self, module_whitelist):
remove = [k for k in self._module_pubsubs if k not in module_whitelist]
for k in remove: del self._module_pubsubs[k]
def check_if_match_found(self, modules):
""" check if all special cases got a match (if not, it means the source
code got changed)
"""
for i, (module_match, file_match_re, src_match_re, _) in enumerate(self._special_cases):
if module_match in modules and src_match_re is not None:
if not self._special_cases_matched[i]:
raise Exception('Module '+module_match+
': no match for '+self._method+' special case'+
src_match_re.pattern+'. The case needs to be updated')
def extract(self, file_name, src_str, module, orb_id_vehicle_attitude_controls_topic):
""" Extract subscribed/published topics from a source string
:param src_str: string of C/C++ code with comments and whitespace removed
"""
orb_pubsub_matches = []
for regex in self._orb_pub_sub_regexes:
orb_pubsub_matches += re.findall(regex, src_str)
orb_id = 'ORB_ID('
for _, match in orb_pubsub_matches:
if match == 'ORB_ID_VEHICLE_ATTITUDE_CONTROLS': # special case
match = orb_id+orb_id_vehicle_attitude_controls_topic
# match has the form: '[ORB_ID(]<topic_name>'
if match.startswith(orb_id):
topic_name = match[len(orb_id):]
self._add_topic(topic_name, file_name, module)
else:
ignore_found = False
for module_match, file_match_re, _, ignore_re in self._special_cases:
if module == module_match:
if file_match_re.search(file_name):
if ignore_re.search(match):
ignore_found = True
if not ignore_found:
# If we land here, we need to add another special case
raise Exception(self._method+' w/o ORB_ID(): '+match+' in '
+file_name+' ('+module+'). You need to add another special case.')
# handle special cases
for i, (module_match, file_match_re, src_match_re, _) in enumerate(self._special_cases):
if src_match_re is None:
continue
if module == module_match:
if file_match_re.search(file_name):
matches = src_match_re.findall(src_str)
for match in matches:
# match has the form: '[ORB_ID(]<topic_name>'
if match.startswith(orb_id):
topic_name = match[len(orb_id):]
dbg_print('Found '+self._method+' for special case in '
+module+': '+topic_name)
self._add_topic(topic_name, file_name, module)
self._special_cases_matched[i] = True
else:
# this is not fatal, as it could be a method delaration/definition
dbg_print('Special case '+self._method+' w/o ORB_ID(): '
+match+' in '+file_name+' ('+module+')')
def _add_topic(self, topic_name, file_name, module):
""" add a subscription/publication for a module
"""
if topic_name in self._topic_blacklist:
dbg_print('ignoring blacklisted topic '+topic_name)
return
if module is None:
if not file_name.endswith('hott/messages.cpp'): # hott has a special module structure. just ignore it
print('Warning: found '+self._method+' without associated module: '
+topic_name+' in '+file_name)
return
if not module in self._module_pubsubs:
self._module_pubsubs[module] = set()
self._module_pubsubs[module].add(topic_name)
def get_topics(self, modules):
""" get the set of topics
:param modules: list of modules to take into account
"""
topics = set()
for module in modules:
if module in self._module_pubsubs:
topics |= self._module_pubsubs[module]
return topics
@property
def pubsubs(self):
""" get dict of all publication/subscriptions (key=modules, value=set of
topic names"""
return self._module_pubsubs
class Graph:
""" Collects Node and Edge information by parsing the source tree """
def __init__(self, module_whitelist=[], topic_blacklist=[]):
self._current_module = [] # stack with current module (they can be nested)
self._all_modules = set() # set of all found modules
self._comment_remove_pattern = re.compile(
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE)
self._whitespace_pattern = re.compile(r'\s+')
self._module_whitelist = module_whitelist
self._excluded_paths = []
self._orb_id_vehicle_attitude_controls_topic = 'actuator_controls_0'
self._orb_id_vehicle_attitude_controls_re = \
re.compile(r'\#define\s+ORB_ID_VEHICLE_ATTITUDE_CONTROLS\s+([^,)]+)')
self._module_subscriptions = {} # key = module name, value = set of topic names
self._module_publications = {} # key = module name, value = set of topic names
self._modules = set() # all modules
self._topics = set() # all topics
self._topic_colors = {} # key = topic, value = color (html string)
# handle special cases
# format: list of tuples with 4 entries:
# - module name to match (module MAIN)
# - regex for file name(s) to match within the module (matched against the full path)
# - regex to extract the topic name: the match must be ORB_ID(<topic_name>
# Note: whitespace is removed from source code, so it does not need to be
# accounted for in the regex.
# If this is None, it will just be ignored
# - regex to ignore matches in the form orb_[subscribe|advertise](<match>
# (the expectation is that the previous matching ORB_ID() will be passed
# to this, so that we can ignore it)
special_cases_sub = [
('sensors', r'voted_sensors_update\.cpp$', r'\binit_sensor_class\b\(([^,)]+)', r'^meta$'),
('mavlink', r'.*', r'\badd_orb_subscription\b\(([^,)]+)', r'^_topic$'),
('sdlog2', r'.*', None, r'^topic$'),
('logger', r'.*', None, r'^(topic|sub\.metadata|_polling_topic_meta)$'),
('uavcan', r'uavcan_main\.cpp$', r'\b_control_topics\[[0-9]\]=([^,)]+)', r'^_control_topics\[i\]$'),
('tap_esc', r'.*', r'\b_control_topics\[[0-9]\]=([^,)]+)', r'^_control_topics\[i\]$'),
('pwm_out_sim', r'.*', r'\b_control_topics\[[0-9]\]=([^,)]+)', r'^_control_topics\[i\]$'),
('snapdragon_pwm_out', r'.*', r'\b_controls_topics\[[0-9]\]=([^,)]+)', r'^_controls_topics\[i\]$'),
('fmu', r'.*', r'\b_control_topics\[[0-9]\]=([^,)]+)', r'^_control_topics\[i\]$'),
('linux_pwm_out', r'.*', r'\b_controls_topics\[[0-9]\]=([^,)]+)', r'^_controls_topics\[i\]$'),
]
special_cases_sub = [(a, re.compile(b), re.compile(c) if c is not None else None, re.compile(d))
for a,b,c,d in special_cases_sub]
self._subscriptions = PubSub(False, topic_blacklist,
[r"\borb_subscribe(_multi|)\b\(([^,)]+)"],
special_cases_sub)
special_cases_pub = [
('replay', r'replay_main\.cpp$', None, r'^sub\.orb_meta$'),
('fw_pos_control_l1', r'FixedwingPositionControl\.cpp$', r'\b_attitude_setpoint_id=([^,)]+)', r'^_attitude_setpoint_id$'),
('mc_pos_control', r'mc_pos_control_main\.cpp$', r'\b_attitude_setpoint_id=([^,)]+)', r'^_attitude_setpoint_id$'),
('mc_att_control', r'mc_att_control_main\.cpp$', r'\b_rates_sp_id=([^,)]+)', r'^_rates_sp_id$'),
('mc_att_control', r'mc_att_control_main\.cpp$', r'\b_actuators_id=([^,)]+)', r'^_actuators_id$'),
('fw_att_control', r'fw_att_control_main\.cpp$', r'\b_rates_sp_id=([^,)]+)', r'^_rates_sp_id$'),
('fw_att_control', r'fw_att_control_main\.cpp$', r'\b_actuators_id=([^,)]+)', r'^_actuators_id$'),
('fw_att_control', r'fw_att_control_main\.cpp$', r'\b_attitude_setpoint_id=([^,)]+)', r'^_attitude_setpoint_id$'),
('uavcan', r'sensors/.*\.cpp$', r'\bUavcanCDevSensorBridgeBase\([^{]*DEVICE_PATH,([^,)]+)', r'^_orb_topic$'),
('batt_smbus', r'batt_smbus\.cpp$', r'\b_batt_orb_id=([^,)]+)', r'^_batt_orb_id$'),
]
special_cases_pub = [(a, re.compile(b), re.compile(c) if c is not None else None, re.compile(d))
for a,b,c,d in special_cases_pub]
self._publications = PubSub(True, topic_blacklist,
[r"\borb_advertise(_multi|_queue|_multi_queue|)\b\(([^,)]+)",
r"\borb_publish_auto()\b\(([^,)]+)"],
special_cases_pub)
def _get_current_module(self):
if len(self._current_module) == 0:
return None
return self._current_module[-1]
def build(self, src_path_list, excluded_paths=[], use_topic_pubsub_union=True):
""" parse the source tree & extract pub/sub information.
:param use_topic_pubsub_union: if true, use all topics that have a
publisher or subscriber. If false, use only topics with at least one
publisher and subscriber.
fill in self._module_subsciptions & self._module_publications
"""
self._subscriptions.reset()
self._publications.reset()
self._excluded_paths = [os.path.normpath(p) for p in excluded_paths]
for path in src_path_list:
self._build_recursive(path)
# filter by whitelist
if len(self._module_whitelist) > 0:
self._subscriptions.filter_modules(self._module_whitelist)
self._publications.filter_modules(self._module_whitelist)
# modules & topics sets
self._modules = set(self._publications.pubsubs.keys() +
self._subscriptions.pubsubs.keys())
print('number of modules: '+str(len(self._modules)))
self._topics = self._get_topics(use_topic_pubsub_union=use_topic_pubsub_union)
print('number of topics: '+str(len(self._topics)))
# initialize colors
color_list = get_N_colors(len(self._topics), 0.7, 0.85)
self._topic_colors = {}
for i, topic in enumerate(self._topics):
self._topic_colors[topic] = color_list[i]
# validate that all special rules got used
self._subscriptions.check_if_match_found(self._all_modules)
self._publications.check_if_match_found(self._all_modules)
def _get_topics(self, use_topic_pubsub_union=True):
""" get the set of topics
"""
subscribed_topics = self._subscriptions.get_topics(self._modules)
published_topics = self._publications.get_topics(self._modules)
if use_topic_pubsub_union:
return subscribed_topics | published_topics
return subscribed_topics & published_topics
def _build_recursive(self, path):
if os.path.normpath(path) in self._excluded_paths:
dbg_print('ignoring excluded path '+path)
return
entries = os.listdir(path)
# check if entering a new module
cmake_file = 'CMakeLists.txt'
new_module = False
if cmake_file in entries:
new_module = self._extract_module_name(os.path.join(path, cmake_file))
# iterate directories recursively
for entry in entries:
file_name = os.path.join(path, entry)
if os.path.isdir(file_name):
self._build_recursive(file_name)
# iterate source files
# Note: we could skip the entries if we're not in a module, but we don't
# so that we get appropriate error messages to know where we miss subs
# or pubs
for entry in entries:
file_name = os.path.join(path, entry)
if os.path.isfile(file_name):
_, ext = os.path.splitext(file_name)
if ext in ['.cpp', '.c', '.h', '.hpp']:
self._process_source_file(file_name)
if new_module:
self._current_module.pop()
def _extract_module_name(self, file_name):
""" extract the module name from a CMakeLists.txt file and store
in self._current_module if there is any """
datafile = file(file_name)
found_module_def = False
for line in datafile:
if 'px4_add_module' in line: # must contain 'px4_add_module'
found_module_def = True
words = line.split()
# get the definition of MAIN
if found_module_def and 'MAIN' in words and len(words) >= 2:
self._current_module.append(words[1])
self._all_modules.add(words[1])
dbg_print('Found module name: '+words[1])
return True
return False
def _process_source_file(self, file_name):
""" extract information from a single source file """
with codecs.open(file_name, 'r', 'utf-8') as f:
try:
content = f.read()
except:
print('Failed reading file: %s, skipping content.' % path)
return
current_module = self._get_current_module()
if current_module == 'uorb_tests': # skip this
return
if current_module == 'uorb':
# search and validate the ORB_ID_VEHICLE_ATTITUDE_CONTROLS define
matches = self._orb_id_vehicle_attitude_controls_re.findall(content)
for match in matches:
if match != 'ORB_ID('+self._orb_id_vehicle_attitude_controls_topic:
# if we land here, you need to change _orb_id_vehicle_attitude_controls_topic
raise Exception(
'The extracted define for ORB_ID_VEHICLE_ATTITUDE_CONTROLS '
'is '+match+' but expected ORB_ID('+
self._orb_id_vehicle_attitude_controls_topic)
return # skip uorb module for the rest
if content.lower().find('orb_') != -1: # approximative filter to quickly
# discard files we're not interested in
# (speedup the parsing)
src = self._comment_remover(content)
src = re.sub(self._whitespace_pattern, '', src) # remove all whitespace
# subscriptions
self._subscriptions.extract(file_name, src, current_module,
self._orb_id_vehicle_attitude_controls_topic)
# publications
self._publications.extract(file_name, src, current_module,
self._orb_id_vehicle_attitude_controls_topic)
# TODO: handle Publication & Subscription template classes
def _comment_remover(self, text):
""" remove C++ & C style comments.
Source: https://stackoverflow.com/a/241506 """
def replacer(match):
s = match.group(0)
if s.startswith('/'):
return " " # note: a space and not an empty string
else:
return s
return re.sub(self._comment_remove_pattern, replacer, text)
@property
def modules(self):
""" get the set of all modules """
return self._modules
@property
def topics(self):
""" get set set of all topics """
return self._topics
@property
def topic_colors(self):
""" get a dict of all topic colors with key=topic, value=color """
return self._topic_colors
@property
def module_subscriptions(self):
""" get a dict of all subscriptions with key=module name, value=set(topic names) """
return self._subscriptions.pubsubs
@property
def module_publications(self):
""" get a dict of all publications with key=module name, value=set(topic names) """
return self._publications.pubsubs
class OutputGraphviz:
""" write graph using Graphviz """
def __init__(self, graph):
self._graph = graph
def write(self, file_name, engine='fdp',
show_publications=True, show_subscriptions=True):
""" write the graph to a file
:param engine: graphviz engine
- fdp works for large graphs
- neato works better for smaller graphs
- circo works for single modules
CLI: fdp graph.fv -Tpdf -o test.pdf
"""
print('Writing to '+file_name)
ratio = 1 # aspect ratio
modules = self._graph.modules
topics = self._graph.topics
topic_colors = self._graph.topic_colors
module_publications = self._graph.module_publications
module_subscriptions = self._graph.module_subscriptions
graph_attr={'splines': 'true', 'ratio': str(ratio), 'overlap': 'false'}
graph_attr['sep'] = '"+15,15"' # increase spacing between nodes
graph = Digraph(comment='autogenerated graph with graphviz using uorb_graph.py',
engine=engine, graph_attr=graph_attr)
# nodes
for module in modules:
graph.node('m_'+module, module, shape='box', fontcolor='#ffffff',
style='filled', color='#666666', fontsize='16')
for topic in topics:
graph.node('t_'+topic, topic, shape='ellipse', fontcolor='#ffffff',
style='filled', color=topic_colors[topic])
# edges
if show_publications:
for module in modules:
if module in module_publications:
for topic in module_publications[module]:
if topic in topics:
graph.edge('m_'+module, 't_'+topic,
color=topic_colors[topic], style='dashed')
if show_subscriptions:
for module in modules:
if module in module_subscriptions:
for topic in module_subscriptions[module]:
if topic in topics:
graph.edge('t_'+topic, 'm_'+module,
color=topic_colors[topic])
graph.render(file_name, view=False)
class OutputJSON:
""" write graph to a JSON file (that can be used with D3.js) """
def __init__(self, graph):
self._graph = graph
def write(self, file_name):
print('Writing to '+file_name)
modules = self._graph.modules
topics = self._graph.topics
topic_colors = self._graph.topic_colors
module_publications = self._graph.module_publications
module_subscriptions = self._graph.module_subscriptions
data = {}
nodes = []
# nodes
# (sort by length, such that short names are last. The rendering order
# will be the same, so that in case of an overlap, the shorter label
# will be on top)
for module in sorted(modules, key=len, reverse=True):
node = {}
node['id'] = 'm_'+module
node['name'] = module
node['type'] = 'module'
node['color'] = '#666666'
# TODO: add url to open module documentation?
nodes.append(node)
for topic in sorted(topics, key=len, reverse=True):
node = {}
node['id'] = 't_'+topic
node['name'] = topic
node['type'] = 'topic'
node['color'] = topic_colors[topic]
# url is opened when double-clicking on the node
# TODO: does not work for multi-topics
node['url'] = 'https://github.com/PX4/Firmware/blob/master/msg/'+topic+'.msg'
nodes.append(node)
data['nodes'] = nodes
edges = []
# edges
for module in modules:
if module in module_publications:
for topic in module_publications[module]:
if topic in topics:
edge = {}
edge['source'] = 'm_'+module
edge['target'] = 't_'+topic
edge['color'] = topic_colors[topic]
edge['style'] = 'dashed'
edges.append(edge)
for module in modules:
if module in module_subscriptions:
for topic in module_subscriptions[module]:
if topic in topics:
edge = {}
edge['source'] = 't_'+topic
edge['target'] = 'm_'+module
edge['color'] = topic_colors[topic]
edge['style'] = 'normal'
edges.append(edge)
data['links'] = edges
with open(file_name, 'w') as outfile:
json.dump(data, outfile) # add indent=2 for readable formatting
# ignore topics that are subscribed/published by many topics, but are not really
# useful to show in the graph
topic_blacklist = [ 'parameter_update', 'mavlink_log', 'log_message' ]
print('Excluded topics: '+str(topic_blacklist))
if len(args.modules) == 0:
module_whitelist = []
else:
module_whitelist = [ m.strip() for m in args.modules.split(',')]
graph = Graph(module_whitelist=module_whitelist, topic_blacklist=topic_blacklist)
if len(args.src_path) == 0:
args.src_path = ['src']
graph.build(args.src_path, args.exclude_path, use_topic_pubsub_union=args.use_topic_union)
if args.output == 'json':
output_json = OutputJSON(graph)
output_json.write(args.file+'.json')
elif args.output == 'graphviz':
try:
from graphviz import Digraph
except:
print("Failed to import graphviz.")
print("You may need to install it with 'pip install graphviz'")
print("")
raise
output_graphviz = OutputGraphviz(graph)
engine='fdp' # use neato or fdp
output_graphviz.write(args.file+'.fv', engine=engine)
output_graphviz.write(args.file+'_subs.fv', show_publications=False, engine=engine)
output_graphviz.write(args.file+'_pubs.fv', show_subscriptions=False, engine=engine)
else:
print('Error: unknown output format '+args.output)
+13
View File
@@ -0,0 +1,13 @@
#! /bin/bash
# create the graph from a posix (e.g. SITL) startup script
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
startup_file="$SCRIPT_DIR"/../../posix-configs/SITL/init/ekf2/typhoon_h480
[ -n "$1" ] && startup_file=$1
# get the modules as comma-separated list
modules=$(cat "$startup_file"|cut -f1 -d' '|sort|uniq|tr '\n' ,)
cd "$SCRIPT_DIR/../.."
"$SCRIPT_DIR"/create.py --src-path src -m "$modules" -f "$SCRIPT_DIR/graph_runtime_sitl"
Vendored
-131
View File
@@ -1,131 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|
# Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search.
config.vm.box = "ubuntu/trusty64"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# MAVLink telemetry via UDP in SITL mode
config.vm.network "forwarded_port", guest: 14556, host: 14556, protocol: "udp"
# SITL simulation data
config.vm.network "forwarded_port", guest: 14560, host: 14560, protocol: "udp"
# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.10"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# NFS should be faster: https://stefanwrobel.com/how-to-make-vagrant-performance-not-suck
config.vm.synced_folder ".", "/Firmware", type: "nfs"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# This is to configure the machine to be as fast as possible
# Alternative: https://github.com/rdsubhas/vagrant-faster
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = false
vb.customize ["modifyvm", :id, "--ioapic", "on"]
#vb.customize ["modifyvm", :id, "--cpus", "2"]
config.vm.provider "virtualbox" do |v|
host = RbConfig::CONFIG['host_os']
# Give VM 1/4 system memory & access to all cpu cores on the host
if host =~ /darwin/
cpus = `sysctl -n hw.ncpu`.to_i
# sysctl returns Bytes and we need to convert to MB
mem = `sysctl -n hw.memsize`.to_i / 1024 / 1024 / 4
elsif host =~ /linux/
cpus = `nproc`.to_i
# meminfo shows KB and we need to convert to MB
mem = `grep 'MemTotal' /proc/meminfo | sed -e 's/MemTotal://' -e 's/ kB//'`.to_i / 1024 / 4
else # sorry Windows folks, I can't help you
cpus = 2
mem = 1024
end
v.customize ["modifyvm", :id, "--memory", mem]
v.customize ["modifyvm", :id, "--cpus", cpus]
end
# Since make and other tools freak out if they see timestamps
# from the future and we share directories, tightly lock the host and guest clocks together (clock sync if more than 2 seconds off)
vb.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 2000]
# Do this on start and restore
vb.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-start"]
vb.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-on-restore", "1"]
# Customize the amount of memory on the VM:
#vb.memory = "2048"
end
#
# View the documentation for the provider you are using for more
# information on available options.
# Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
# such as FTP and Heroku are also available. See the documentation at
# https://docs.vagrantup.com/v2/push/atlas.html for more information.
# config.push.define "atlas" do |push|
# push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
# end
# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", privileged: false, inline: <<-SHELL
# Ensure we start in the Firmware folder
echo "cd /Firmware" >> ~/.bashrc
# Install software
sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded -y
sudo add-apt-repository ppa:george-edison55/cmake-3.x -y
sudo apt-get update
sudo apt-get install -y build-essential ccache cmake clang-3.5 lldb-3.5 g++-4.8 gcc-4.8 genromfs libc6-i386 libncurses5-dev python-argparse python-empy python-serial s3cmd texinfo zlib1g-dev git-core zip gdb gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
pushd .
cd ~
wget -q https://launchpadlibrarian.net/186124160/gcc-arm-none-eabi-4_8-2014q3-20140805-linux.tar.bz2
tar -jxf gcc-arm-none-eabi-4_8-2014q3-20140805-linux.tar.bz2
exportline="export PATH=$HOME/gcc-arm-none-eabi-4_8-2014q3/bin:\$PATH"
if grep -Fxq "$exportline" ~/.profile; then echo nothing to do ; else echo $exportline >> ~/.profile; fi
exportline2="export HEXAGON_TOOLS_ROOT=$HOME/Qualcomm/HEXAGON_Tools/7.2.10/Tools"
if grep -Fxq "$exportline2" ~/.profile; then echo nothing to do ; else echo $exportline2 >> ~/.profile; fi
. ~/.profile
popd
# setup ccache
mkdir -p ~/bin
ln -s /usr/bin/ccache ~/bin/arm-none-eabi-g++
ln -s /usr/bin/ccache ~/bin/arm-none-eabi-gcc
ln -s /usr/bin/ccache ~/bin/g++-4.8
ln -s /usr/bin/ccache ~/bin/gcc-4.8
export PATH=~/bin:$PATH
# Configure hardware related bits
sudo apt-get -y remove modemmanager
sudo usermod -a -G dialout $USER
SHELL
end
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
+1 -1
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common IO px4io-v2)
@@ -49,6 +48,7 @@ set(config_module_list
drivers/bst
drivers/snapdragon_rc_pwm
drivers/lis3mdl
drivers/tfmini
#
# System commands
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
+1 -2
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
add_definitions(
-DFLASH_BASED_PARAMS
@@ -28,7 +27,7 @@ add_definitions(
)
px4_nuttx_make_uavcan_bootloadable(BOARD ${BOARD}
BIN ${CMAKE_CURRENT_BINARY_DIR}/src/firmware/nuttx/esc35-v1.bin
BIN ${PX4_BINARY_DIR}/platforms/nuttx/esc35-v1.bin
HWNAME ${uavcanblid_name}
HW_MAJOR ${uavcanblid_hw_version_major}
HW_MINOR ${uavcanblid_hw_version_minor}
+1 -1
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
@@ -52,6 +51,7 @@ set(config_module_list
drivers/camera_trigger
drivers/bst
drivers/snapdragon_rc_pwm
drivers/tfmini
#
# System commands
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
@@ -59,6 +58,7 @@ set(config_module_list
drivers/teraranger
drivers/vmount
modules/sensors
drivers/tfmini
#
# System commands
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m7 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
@@ -48,6 +47,8 @@ set(config_module_list
drivers/bst
drivers/snapdragon_rc_pwm
drivers/lis3mdl
drivers/tfmini
#
# System commands
@@ -167,4 +168,4 @@ set(config_module_list
# Hardware test
#examples/hwtest
)
)
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
add_definitions(
-DPARAM_NO_ORB
@@ -26,7 +25,7 @@ add_definitions(
)
px4_nuttx_make_uavcan_bootloadable(BOARD ${BOARD}
BIN ${PX4_BINARY_DIR}/src/firmware/nuttx/px4cannode-v1.bin
BIN ${PX4_BINARY_DIR}/platforms/nuttx/px4cannode-v1.bin
HWNAME ${uavcanblid_name}
HW_MAJOR ${uavcanblid_hw_version_major}
HW_MINOR ${uavcanblid_hw_version_minor}
+1 -2
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
add_definitions(
-DFLASH_BASED_PARAMS
@@ -28,7 +27,7 @@ add_definitions(
)
px4_nuttx_make_uavcan_bootloadable(BOARD ${BOARD}
BIN ${PX4_BINARY_DIR}/src/firmware/nuttx/px4esc-v1.bin
BIN ${PX4_BINARY_DIR}/platforms/nuttx/px4esc-v1.bin
HWNAME ${uavcanblid_name}
HW_MAJOR ${uavcanblid_hw_version_major}
HW_MINOR ${uavcanblid_hw_version_minor}
+1 -1
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common IO px4io-v2)
#set(config_uavcan_num_ifaces 2)
@@ -59,6 +58,7 @@ set(config_module_list
#drivers/ulanding
drivers/vmount
modules/sensors
#drivers/tfmini
#
# System commands
+1 -1
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_test)
@@ -48,6 +47,7 @@ set(config_module_list
#drivers/bst
#drivers/snapdragon_rc_pwm
#drivers/lis3mdl
drivers/tfmini
#
# System commands
+2 -1
View File
@@ -2,9 +2,9 @@
# FMUv3 is FMUv2 with access to the full 2MB flash
set(BOARD px4fmu-v2 CACHE string "" FORCE)
set(FW_NAME nuttx_px4fmu-v3_default.elf CACHE string "" FORCE)
set(FW_PROTOTYPE px4fmu-v3 CACHE string "" FORCE)
set(LD_SCRIPT ld_full.script CACHE string "" FORCE)
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common IO px4io-v2)
set(config_uavcan_num_ifaces 2)
@@ -64,6 +64,7 @@ set(config_module_list
drivers/ulanding
drivers/vmount
modules/sensors
drivers/tfmini
#
# System commands
+1 -1
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
@@ -56,6 +55,7 @@ set(config_module_list
drivers/teraranger
drivers/vmount
modules/sensors
drivers/tfmini
#
# System commands
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common IO px4io-v2)
@@ -56,6 +55,7 @@ set(config_module_list
drivers/teraranger
drivers/vmount
modules/sensors
drivers/tfmini
#
# System commands
+1 -1
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m7 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
@@ -56,6 +55,7 @@ set(config_module_list
drivers/teraranger
drivers/vmount
modules/sensors
drivers/tfmini
#
# System commands
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m3 CONFIG nsh)
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m7 CONFIG nsh ROMFS y ROMFSROOT px4fmu_common)
@@ -50,6 +49,7 @@ set(config_module_list
drivers/tap_esc
drivers/teraranger
modules/sensors
drivers/tfmini
#
# System commands
+1 -2
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
add_definitions(
-DPARAM_NO_ORB
@@ -26,7 +25,7 @@ include(configs/uavcan_board_ident/s2740vc-v1)
# N.B. this would be uncommented when there is an APP
#px4_nuttx_make_uavcan_bootloadable(BOARD ${BOARD}
# BIN ${CMAKE_CURRENT_BINARY_DIR}/src/firmware/nuttx/s2740vc-v1.bin
# BIN ${PX4_BINARY_DIR}/platforms/nuttx/s2740vc-v1.bin
# HWNAME ${uavcanblid_name}
# HW_MAJOR ${uavcanblid_hw_version_major}
# HW_MINOR ${uavcanblid_hw_version_minor}
-1
View File
@@ -1,4 +1,3 @@
include(nuttx/px4_impl_nuttx)
px4_nuttx_configure(HWCLASS m4 CONFIG nsh ROMFS y ROMFSROOT tap_common)
-1
View File
@@ -1,4 +1,3 @@
include(posix/px4_impl_posix)
set(CMAKE_TOOLCHAIN_FILE ${PX4_SOURCE_DIR}/cmake/toolchains/Toolchain-arm-linux-gnueabihf.cmake)
-1
View File
@@ -1,4 +1,3 @@
include(posix/px4_impl_posix)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PX4_SOURCE_DIR}/cmake/cmake_hexagon")
-1
View File
@@ -1,4 +1,3 @@
include(posix/px4_impl_posix)
set(CMAKE_TOOLCHAIN_FILE ${PX4_SOURCE_DIR}/cmake/cmake_hexagon/toolchain/Toolchain-arm-linux-gnueabihf.cmake)
-1
View File
@@ -6,7 +6,6 @@ set(CMAKE_PROGRAM_PATH
${CMAKE_PROGRAM_PATH}
)
include(posix/px4_impl_posix)
add_definitions(
-D__PX4_POSIX_OCPOC
-1
View File
@@ -5,7 +5,6 @@ set(CMAKE_PROGRAM_PATH
${CMAKE_PROGRAM_PATH}
)
include(posix/px4_impl_posix)
add_definitions(
-D__PX4_POSIX_OCPOC
-1
View File
@@ -1,7 +1,6 @@
# This file is shared between posix_rpi_native.cmake
# and posix_rpi_cross.cmake.
include(posix/px4_impl_posix)
# This definition allows to differentiate if this just the usual POSIX build
# or if it is for the RPi.
@@ -1,7 +1,6 @@
include(common/px4_git)
px4_add_git_submodule(TARGET git_cmake_hexagon PATH "cmake/cmake_hexagon")
include(posix/px4_impl_posix)
# Get $QC_SOC_TARGET from environment if existing.
if (DEFINED ENV{QC_SOC_TARGET})
@@ -1,7 +1,6 @@
include(common/px4_git)
px4_add_git_submodule(TARGET git_cmake_hexagon PATH "cmake/cmake_hexagon")
include(posix/px4_impl_posix)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PX4_SOURCE_DIR}/cmake/cmake_hexagon")
-1
View File
@@ -1,4 +1,3 @@
include(posix/px4_impl_posix)
set(CMAKE_TOOLCHAIN_FILE ${PX4_SOURCE_DIR}/cmake/toolchains/Toolchain-native.cmake)
-1
View File
@@ -1,4 +1,3 @@
include(posix/px4_impl_posix)
set(CMAKE_TOOLCHAIN_FILE ${PX4_SOURCE_DIR}/cmake/toolchains/Toolchain-native.cmake)
-1
View File
@@ -1,4 +1,3 @@
include(qurt/px4_impl_qurt)
if ("$ENV{HEXAGON_SDK_ROOT}" STREQUAL "")
message(FATAL_ERROR "Enviroment variable HEXAGON_SDK_ROOT must be set")
-1
View File
@@ -1,4 +1,3 @@
include(qurt/px4_impl_qurt)
if ("$ENV{HEXAGON_SDK_ROOT}" STREQUAL "")
message(FATAL_ERROR "Enviroment variable HEXAGON_SDK_ROOT must be set")
-1
View File
@@ -1,4 +1,3 @@
include(qurt/px4_impl_qurt)
if ("$ENV{HEXAGON_SDK_ROOT}" STREQUAL "")
message(FATAL_ERROR "Enviroment variable HEXAGON_SDK_ROOT must be set")
-1
View File
@@ -1,4 +1,3 @@
include(qurt/px4_impl_qurt)
if ("$ENV{HEXAGON_SDK_ROOT}" STREQUAL "")
message(FATAL_ERROR "Enviroment variable HEXAGON_SDK_ROOT must be set")
-1
View File
@@ -1,4 +1,3 @@
include(qurt/px4_impl_qurt)
set(CONFIG_SHMEM "1")
@@ -1,7 +1,6 @@
include(common/px4_git)
px4_add_git_submodule(TARGET git_cmake_hexagon PATH "cmake/cmake_hexagon")
include(qurt/px4_impl_qurt)
if ("$ENV{HEXAGON_SDK_ROOT}" STREQUAL "")
message(FATAL_ERROR "Enviroment variable HEXAGON_SDK_ROOT must be set")
-1
View File
@@ -1,7 +1,6 @@
include(common/px4_git)
px4_add_git_submodule(TARGET git_cmake_hexagon PATH "cmake/cmake_hexagon")
include(qurt/px4_impl_qurt)
if ("$ENV{HEXAGON_SDK_ROOT}" STREQUAL "")
message(FATAL_ERROR "Enviroment variable HEXAGON_SDK_ROOT must be set")
@@ -1,6 +1,6 @@
############################################################################
#
# Copyright (c) 2015 PX4 Development Team. All rights reserved.
# Copyright (c) 2017 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -32,16 +32,19 @@
############################################################################
#=============================================================================
# FILE: posix/px4_target_impl.cmake
#
# Each PX4 target OS must implement the cmake/${OS}/px4_target_impl.cmake
# rules for their target that implement the following macros:
# Converts a cygwin path (/cygdrive/c/...) to a mixed windows path (C:/...)
#
# px4_target_set_flags
# px4_target_validate_config
# px4_target_firmware
# px4_target_rules
# px4_target_testing
#
# The macros are called from the top level CMakeLists.txt
# It is called on every platform but only adjusts the output when
# called inside the cygwin environment.
#
macro (CYGPATH _path _cygpath)
if (CMAKE_HOST_SYSTEM_NAME STREQUAL CYGWIN)
EXECUTE_PROCESS(COMMAND cygpath.exe -m ${${_path}}
OUTPUT_VARIABLE ${_cygpath})
string (STRIP ${${_cygpath}} ${_cygpath})
else()
set(${_cygpath} ${${_path}})
endif ()
endmacro (CYGPATH)
-37
View File
@@ -1,37 +0,0 @@
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index 1ca1d66..9bc928b 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -194,6 +194,12 @@
#define EIGEN_ARCH_PPC 0
#endif
+/// \internal EIGEN_ARCH_HEXAGON set to 1 if the architecture is Hexagon
+#ifdef __HEXAGON_ARCH__
+ #define EIGEN_ARCH_HEXAGON 1
+#else
+ #define EIGEN_ARCH_HEXAGON 0
+#endif
// Operating system identification, EIGEN_OS_*
@@ -334,15 +340,16 @@
#endif
// Do we support r-value references?
-#if (__has_feature(cxx_rvalue_references) || \
+#if ((__has_feature(cxx_rvalue_references) || \
(defined(__cplusplus) && __cplusplus >= 201103L) || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || \
- (EIGEN_COMP_MSVC >= 1600))
+ (EIGEN_COMP_MSVC >= 1600)) && (!defined(EIGEN_ARCH_HEXAGON)))
#define EIGEN_HAVE_RVALUE_REFERENCES
#endif
// Does the compiler support result_of?
-#if (__has_feature(cxx_lambdas) || (defined(__cplusplus) && __cplusplus >= 201103L))
+#if ((__has_feature(cxx_lambdas) || (defined(__cplusplus) && __cplusplus >= 201103L)) && \
+ (!defined(EIGEN_ARCH_HEXAGON)))
#define EIGEN_HAS_STD_RESULT_OF 1
#endif
-52
View File
@@ -1,52 +0,0 @@
#!/usr/bin/env python
"""
The module facilitates testing in cmake.
It takes a command and a regex for failure ok passing.
It passes if:
* No stderr output.
* Stdout doesn't match failure regex.
* Stdout matches ok regex if given.
"""
from __future__ import print_function
import argparse
import subprocess
import re
import sys
#pylint: disable=invalid-name
parser = argparse.ArgumentParser()
parser.add_argument('cmd')
parser.add_argument('--re-fail')
parser.add_argument('--re-ok')
parser.add_argument('--verbose', '-v', dest='verbose', action='store_true')
parser.set_defaults(verbose=False)
args = parser.parse_args()
proc = subprocess.Popen(args.cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
if stderr != "":
print(stderr)
sys.exit(1)
if args.re_fail is not None:
fail_match = re.search(args.re_fail, stdout)
if fail_match is not None:
print(stdout)
sys.exit(1)
if args.re_ok is not None:
ok_match = re.search(args.re_ok, stdout)
if re.match(args.re_ok, stdout) is None:
print(stdout)
sys.exit(1)
if args.verbose:
print(stdout)
sys.exit(0)
# vim: set et ft=python fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
-27
View File
@@ -1,27 +0,0 @@
INFO Shell id is 47996278451456
WARN 1 starting task wkr_high (file /home/jgoppert/git/px4/cmake-Firmware/src/platforms/posix/px4_layer/px4_posix_tasks.cpp line 146)
WARN 54 starting task wkr_low (file /home/jgoppert/git/px4/cmake-Firmware/src/platforms/posix/px4_layer/px4_posix_tasks.cpp line 146)
WARN 100 starting task wkr_hrt (file /home/jgoppert/git/px4/cmake-Firmware/src/platforms/posix/px4_layer/px4_posix_tasks.cpp line 146)
App name: px4
Enter a command and its args:
----------------------------------
Running: uorb
Returning: uorb
Enter a command and its args:
----------------------------------
Running: accelsim
Returning: accelsim
Enter a command and its args:
----------------------------------
Running: px4_simple_app
Hello Sky!
[px4_simple_app] Got no data within a second
[px4_simple_app] Got no data within a second
[px4_simple_app] Got no data within a second
[px4_simple_app] Got no data within a second
[px4_simple_app] Got no data within a second
Returning: px4_simple_app
Enter a command and its args:
----------------------------------
Running: shutdown
Shutting down
-4
View File
@@ -1,4 +0,0 @@
uorb start
accelsim start
px4_simple_app
shutdown
@@ -37,21 +37,19 @@
#
# The shebang of this file is currently Python2 because some
# dependencies such as pymavlink don't play well with Python3 yet.
from __future__ import division
PKG = 'px4'
import unittest
import rospy
import rosbag
import time
from std_msgs.msg import Header
from std_msgs.msg import Float64
from geometry_msgs.msg import PoseStamped, Quaternion
from threading import Thread
from tf.transformations import quaternion_from_euler
from mavros_msgs.srv import CommandLong
from sensor_msgs.msg import NavSatFix
#from px4_test_helper import PX4TestHelper
from geometry_msgs.msg import PoseStamped, Quaternion, Vector3
from mavros_msgs.msg import AttitudeTarget, HomePosition, State
from mavros_msgs.srv import CommandBool, SetMode
from std_msgs.msg import Header
class MavrosOffboardAttctlTest(unittest.TestCase):
"""
@@ -62,90 +60,212 @@ class MavrosOffboardAttctlTest(unittest.TestCase):
"""
def setUp(self):
rospy.init_node('test_node', anonymous=True)
rospy.wait_for_service('mavros/cmd/arming', 30)
#self.helper = PX4TestHelper("mavros_offboard_attctl_test")
#self.helper.setUp()
rospy.Subscriber("mavros/local_position/pose", PoseStamped, self.position_callback)
rospy.Subscriber("mavros/global_position/global", NavSatFix, self.global_position_callback)
self.pub_att = rospy.Publisher('mavros/setpoint_attitude/attitude', PoseStamped, queue_size=10)
self.pub_thr = rospy.Publisher('mavros/setpoint_attitude/att_throttle', Float64, queue_size=10)
rospy.wait_for_service('mavros/cmd/command', 30)
self._srv_cmd_long = rospy.ServiceProxy('mavros/cmd/command', CommandLong, persistent=True)
self.rate = rospy.Rate(10) # 10hz
self.has_global_pos = False
self.local_position = PoseStamped()
self.state = State()
self.att = AttitudeTarget()
self.sub_topics_ready = {
key: False
for key in ['local_pos', 'home_pos', 'state']
}
# setup ROS topics and services
try:
rospy.wait_for_service('mavros/cmd/arming', 30)
rospy.wait_for_service('mavros/set_mode', 30)
except rospy.ROSException:
self.fail("failed to connect to mavros services")
self.set_arming_srv = rospy.ServiceProxy('mavros/cmd/arming',
CommandBool)
self.set_mode_srv = rospy.ServiceProxy('mavros/set_mode', SetMode)
self.local_pos_sub = rospy.Subscriber('mavros/local_position/pose',
PoseStamped,
self.local_position_callback)
self.home_pos_sub = rospy.Subscriber('mavros/home_position/home',
HomePosition,
self.home_position_callback)
self.state_sub = rospy.Subscriber('mavros/state', State,
self.state_callback)
self.att_setpoint_pub = rospy.Publisher(
'mavros/setpoint_raw/attitude', AttitudeTarget, queue_size=10)
# send setpoints in seperate thread to better prevent failsafe
self.att_thread = Thread(target=self.send_att, args=())
self.att_thread.daemon = True
self.att_thread.start()
def tearDown(self):
#self.helper.tearDown()
pass
#
# General callback functions used in tests
# Callback functions
#
def position_callback(self, data):
def local_position_callback(self, data):
self.local_position = data
def global_position_callback(self, data):
self.has_global_pos = True
if not self.sub_topics_ready['local_pos']:
self.sub_topics_ready['local_pos'] = True
def home_position_callback(self, data):
# this topic publishing seems to be a better indicator that the sim
# is ready, it's not actually needed
self.home_pos_sub.unregister()
if not self.sub_topics_ready['home_pos']:
self.sub_topics_ready['home_pos'] = True
def state_callback(self, data):
self.state = data
if not self.sub_topics_ready['state']:
self.sub_topics_ready['state'] = True
#
# Helper methods
#
def send_att(self):
rate = rospy.Rate(10) # Hz
self.att.body_rate = Vector3()
self.att.header = Header()
self.att.header.frame_id = "base_footprint"
self.att.orientation = Quaternion(*quaternion_from_euler(0.25, 0.25,
0))
self.att.thrust = 0.7
self.att.type_mask = 7 # ignore body rate
while not rospy.is_shutdown():
self.att.header.stamp = rospy.Time.now()
self.att_setpoint_pub.publish(self.att)
try: # prevent garbage in console output when thread is killed
rate.sleep()
except rospy.ROSInterruptException:
pass
def set_mode(self, mode, timeout):
"""mode: PX4 mode string, timeout(int): seconds"""
old_mode = self.state.mode
loop_freq = 1 # Hz
rate = rospy.Rate(loop_freq)
mode_set = False
for i in xrange(timeout * loop_freq):
if self.state.mode == mode:
mode_set = True
rospy.loginfo(
"set mode success | new mode: {0}, old mode: {1} | seconds: {2} of {3}".
format(mode, self.state.mode, i / loop_freq, timeout))
break
else:
try:
res = self.set_mode_srv(0, mode) # 0 is custom mode
if not res.mode_sent:
rospy.logerr("failed to send mode command")
except rospy.ServiceException as e:
rospy.logerr(e)
rate.sleep()
self.assertTrue(mode_set, (
"failed to set mode | new mode: {0}, old mode: {1} | timeout(seconds): {2}".
format(mode, old_mode, timeout)))
def set_arm(self, arm, timeout):
"""arm: True to arm or False to disarm, timeout(int): seconds"""
old_arm = self.state.armed
loop_freq = 1 # Hz
rate = rospy.Rate(loop_freq)
arm_set = False
for i in xrange(timeout * loop_freq):
if self.state.armed == arm:
arm_set = True
rospy.loginfo(
"set arm success | new arm: {0}, old arm: {1} | seconds: {2} of {3}".
format(arm, old_arm, i / loop_freq, timeout))
break
else:
try:
res = self.set_arming_srv(arm)
if not res.success:
rospy.logerr("failed to send arm command")
except rospy.ServiceException as e:
rospy.logerr(e)
rate.sleep()
self.assertTrue(arm_set, (
"failed to set arm | new arm: {0}, old arm: {1} | timeout(seconds): {2}".
format(arm, self.state.armed, timeout)))
def wait_for_topics(self, timeout):
"""wait for simulation to be ready, make sure we're getting topic info
from all topics by checking dictionary of flag values set in callbacks,
timeout(int): seconds"""
rospy.loginfo("waiting for simulation topics to be ready")
loop_freq = 1 # Hz
rate = rospy.Rate(loop_freq)
simulation_ready = False
for i in xrange(timeout * loop_freq):
if all(value for value in self.sub_topics_ready.values()):
simulation_ready = True
rospy.loginfo("simulation topics ready | seconds: {0} of {1}".
format(i / loop_freq, timeout))
break
rate.sleep()
self.assertTrue(simulation_ready, (
"failed to hear from all subscribed simulation topics | topic ready flags: {0} | timeout(seconds): {1}".
format(self.sub_topics_ready, timeout)))
#
# Test method
#
def test_attctl(self):
"""Test offboard attitude control"""
# boundary to cross
boundary_x = 5
boundary_y = 5
boundary_z = -5
# FIXME: hack to wait for simulation to be ready
while not self.has_global_pos:
self.rate.sleep()
# delay starting the mission
self.wait_for_topics(30)
# set some attitude and thrust
att = PoseStamped()
att.header = Header()
att.header.frame_id = "base_footprint"
att.header.stamp = rospy.Time.now()
quaternion = quaternion_from_euler(0.25, 0.25, 0)
att.pose.orientation = Quaternion(*quaternion)
rospy.loginfo("seting mission mode")
self.set_mode("OFFBOARD", 5)
rospy.loginfo("arming")
self.set_arm(True, 5)
throttle = Float64()
throttle.data = 0.7
armed = False
# does it cross expected boundaries in X seconds?
count = 0
timeout = 120
while count < timeout:
# update timestamp for each published SP
att.header.stamp = rospy.Time.now()
self.pub_att.publish(att)
#self.helper.bag_write('mavros/setpoint_attitude/attitude', att)
self.pub_thr.publish(throttle)
#self.helper.bag_write('mavros/setpoint_attitude/att_throttle', throttle)
self.rate.sleep()
# FIXME: arm and switch to offboard
# (need to wait the first few rounds until PX4 has the offboard stream)
if not armed and count > 5:
self._srv_cmd_long(False, 176, False,
1, 6, 0, 0, 0, 0, 0)
# make sure the first command doesn't get lost
time.sleep(1)
self._srv_cmd_long(False, 400, False,
# arm
1, 0, 0, 0, 0, 0, 0)
armed = True
if (self.local_position.pose.position.x > 5
and self.local_position.pose.position.z > 5
and self.local_position.pose.position.y < -5):
rospy.loginfo("run mission")
rospy.loginfo("attempting to cross boundary | x: {0}, y: {1}, z: {2}".
format(boundary_x, boundary_y, boundary_z))
# does it cross expected boundaries in 'timeout' seconds?
timeout = 12 # (int) seconds
loop_freq = 10 # Hz
rate = rospy.Rate(loop_freq)
crossed = False
for i in xrange(timeout * loop_freq):
if (self.local_position.pose.position.x > boundary_x and
self.local_position.pose.position.z > boundary_y and
self.local_position.pose.position.y < boundary_z):
rospy.loginfo("boundary crossed | seconds: {0} of {1}".format(
i / loop_freq, timeout))
crossed = True
break
count = count + 1
self.assertTrue(count < timeout, "took too long to cross boundaries")
rate.sleep()
self.assertTrue(crossed, (
"took too long to cross boundaries | current position x: {0}, y: {1}, z: {2} | timeout(seconds): {3}".
format(self.local_position.pose.position.x,
self.local_position.pose.position.y,
self.local_position.pose.position.z, timeout)))
rospy.loginfo("disarming")
self.set_arm(False, 5)
if __name__ == '__main__':
import rostest
rostest.rosrun(PKG, 'mavros_offboard_attctl_test', MavrosOffboardAttctlTest)
#unittest.main()
rospy.init_node('test_node', anonymous=True)
rostest.rosrun(PKG, 'mavros_offboard_attctl_test',
MavrosOffboardAttctlTest)
@@ -37,24 +37,21 @@
#
# The shebang of this file is currently Python2 because some
# dependencies such as pymavlink don't play well with Python3 yet.
from __future__ import division
PKG = 'px4'
import unittest
import rospy
import math
import rosbag
import time
from numpy import linalg
import numpy as np
from std_msgs.msg import Header
from geometry_msgs.msg import PoseStamped, Quaternion
from threading import Thread
from tf.transformations import quaternion_from_euler
from mavros_msgs.srv import CommandLong
from sensor_msgs.msg import NavSatFix
#from px4_test_helper import PX4TestHelper
from geometry_msgs.msg import PoseStamped, Quaternion
from mavros_msgs.msg import HomePosition, State
from mavros_msgs.srv import CommandBool, SetMode
from std_msgs.msg import Header
class MavrosOffboardPosctlTest(unittest.TestCase):
"""
@@ -62,115 +59,236 @@ class MavrosOffboardPosctlTest(unittest.TestCase):
via MAVROS.
For the test to be successful it needs to reach all setpoints in a certain time.
FIXME: add flight path assertion (needs transformation from ROS frame to NED)
"""
def setUp(self):
rospy.init_node('test_node', anonymous=True)
#self.helper = PX4TestHelper("mavros_offboard_posctl_test")
#self.helper.setUp()
rospy.Subscriber("mavros/local_position/pose", PoseStamped, self.position_callback)
rospy.Subscriber("mavros/global_position/global", NavSatFix, self.global_position_callback)
self.pub_spt = rospy.Publisher('mavros/setpoint_position/local', PoseStamped, queue_size=10)
rospy.wait_for_service('mavros/cmd/command', 30)
self._srv_cmd_long = rospy.ServiceProxy('mavros/cmd/command', CommandLong, persistent=True)
self.rate = rospy.Rate(10) # 10hz
self.has_global_pos = False
self.local_position = PoseStamped()
self.armed = False
self.state = State()
self.pos = PoseStamped()
self.sub_topics_ready = {
key: False
for key in ['local_pos', 'home_pos', 'state']
}
# setup ROS topics and services
try:
rospy.wait_for_service('mavros/cmd/arming', 30)
rospy.wait_for_service('mavros/set_mode', 30)
except rospy.ROSException:
self.fail("failed to connect to mavros services")
self.set_arming_srv = rospy.ServiceProxy('/mavros/cmd/arming',
CommandBool)
self.set_mode_srv = rospy.ServiceProxy('/mavros/set_mode', SetMode)
self.local_pos_sub = rospy.Subscriber('mavros/local_position/pose',
PoseStamped,
self.local_position_callback)
self.home_pos_sub = rospy.Subscriber('mavros/home_position/home',
HomePosition,
self.home_position_callback)
self.state_sub = rospy.Subscriber('mavros/state', State,
self.state_callback)
self.pos_setpoint_pub = rospy.Publisher(
'mavros/setpoint_position/local', PoseStamped, queue_size=10)
# send setpoints in seperate thread to better prevent failsafe
self.pos_thread = Thread(target=self.send_pos, args=())
self.pos_thread.daemon = True
self.pos_thread.start()
def tearDown(self):
#self.helper.tearDown()
pass
#
# General callback functions used in tests
# Callback functions
#
def position_callback(self, data):
def local_position_callback(self, data):
self.local_position = data
def global_position_callback(self, data):
self.has_global_pos = True
if not self.sub_topics_ready['local_pos']:
self.sub_topics_ready['local_pos'] = True
def home_position_callback(self, data):
# this topic publishing seems to be a better indicator that the sim
# is ready, it's not actually needed
self.home_pos_sub.unregister()
if not self.sub_topics_ready['home_pos']:
self.sub_topics_ready['home_pos'] = True
def state_callback(self, data):
self.state = data
if not self.sub_topics_ready['state']:
self.sub_topics_ready['state'] = True
#
# Helper methods
#
def send_pos(self):
rate = rospy.Rate(10) # Hz
self.pos.header = Header()
self.pos.header.frame_id = "base_footprint"
while not rospy.is_shutdown():
self.pos.header.stamp = rospy.Time.now()
self.pos_setpoint_pub.publish(self.pos)
try: # prevent garbage in console output when thread is killed
rate.sleep()
except rospy.ROSInterruptException:
pass
def set_mode(self, mode, timeout):
"""mode: PX4 mode string, timeout(int): seconds"""
old_mode = self.state.mode
loop_freq = 1 # Hz
rate = rospy.Rate(loop_freq)
mode_set = False
for i in xrange(timeout * loop_freq):
if self.state.mode == mode:
mode_set = True
rospy.loginfo(
"set mode success | new mode: {0}, old mode: {1} | seconds: {2} of {3}".
format(mode, old_mode, i / loop_freq, timeout))
break
else:
try:
res = self.set_mode_srv(0, mode) # 0 is custom mode
if not res.mode_sent:
rospy.logerr("failed to send mode command")
except rospy.ServiceException as e:
rospy.logerr(e)
rate.sleep()
self.assertTrue(mode_set, (
"failed to set mode | new mode: {0}, old mode: {1} | timeout(seconds): {2}".
format(mode, self.state.mode, timeout)))
def set_arm(self, arm, timeout):
"""arm: True to arm or False to disarm, timeout(int): seconds"""
old_arm = self.state.armed
loop_freq = 1 # Hz
rate = rospy.Rate(loop_freq)
arm_set = False
for i in xrange(timeout * loop_freq):
if self.state.armed == arm:
arm_set = True
rospy.loginfo(
"set arm success | new arm: {0}, old arm: {1} | seconds: {2} of {3}".
format(arm, old_arm, i / loop_freq, timeout))
break
else:
try:
res = self.set_arming_srv(arm)
if not res.success:
rospy.logerr("failed to send arm command")
except rospy.ServiceException as e:
rospy.logerr(e)
rate.sleep()
self.assertTrue(arm_set, (
"failed to set arm | new arm: {0}, old arm: {1} | timeout(seconds): {2}".
format(arm, self.state.armed, timeout)))
def wait_for_topics(self, timeout):
"""wait for simulation to be ready, make sure we're getting topic info
from all topics by checking dictionary of flag values set in callbacks,
timeout(int): seconds"""
rospy.loginfo("waiting for simulation topics to be ready")
loop_freq = 1 # Hz
rate = rospy.Rate(loop_freq)
simulation_ready = False
for i in xrange(timeout * loop_freq):
if all(value for value in self.sub_topics_ready.values()):
simulation_ready = True
rospy.loginfo("simulation topics ready | seconds: {0} of {1}".
format(i / loop_freq, timeout))
break
rate.sleep()
self.assertTrue(simulation_ready, (
"failed to hear from all subscribed simulation topics | topic ready flags: {0} | timeout(seconds): {1}".
format(self.sub_topics_ready, timeout)))
def is_at_position(self, x, y, z, offset):
rospy.logdebug("current position %f, %f, %f" %
(self.local_position.pose.position.x,
self.local_position.pose.position.y,
self.local_position.pose.position.z))
rospy.logdebug("current position | x:{0}, y:{1}, z:{2}".format(
self.local_position.pose.position.x, self.local_position.pose.
position.y, self.local_position.pose.position.z))
desired = np.array((x, y, z))
pos = np.array((self.local_position.pose.position.x,
self.local_position.pose.position.y,
self.local_position.pose.position.z))
return linalg.norm(desired - pos) < offset
return np.linalg.norm(desired - pos) < offset
def reach_position(self, x, y, z, timeout):
# set a position setpoint
pos = PoseStamped()
pos.header = Header()
pos.header.frame_id = "base_footprint"
pos.pose.position.x = x
pos.pose.position.y = y
pos.pose.position.z = z
self.pos.pose.position.x = x
self.pos.pose.position.y = y
self.pos.pose.position.z = z
rospy.loginfo("attempting to reach position | x: {0}, y: {1}, z: {2}".
format(x, y, z))
# For demo purposes we will lock yaw/heading to north.
yaw_degrees = 0 # North
yaw = math.radians(yaw_degrees)
quaternion = quaternion_from_euler(0, 0, yaw)
pos.pose.orientation = Quaternion(*quaternion)
self.pos.pose.orientation = Quaternion(*quaternion)
# does it reach the position in X seconds?
count = 0
while count < timeout:
# update timestamp for each published SP
pos.header.stamp = rospy.Time.now()
self.pub_spt.publish(pos)
#self.helper.bag_write('mavros/setpoint_position/local', pos)
# FIXME: arm and switch to offboard
# (need to wait the first few rounds until PX4 has the offboard stream)
if not self.armed and count > 5:
self._srv_cmd_long(False, 176, False,
1, 6, 0, 0, 0, 0, 0)
# make sure the first command doesn't get lost
time.sleep(1)
self._srv_cmd_long(False, 400, False,
# arm
1, 0, 0, 0, 0, 0, 0)
self.armed = True
if self.is_at_position(pos.pose.position.x, pos.pose.position.y, pos.pose.position.z, 1):
# does it reach the position in 'timeout' seconds?
loop_freq = 10 # Hz
rate = rospy.Rate(loop_freq)
reached = False
for i in xrange(timeout * loop_freq):
if self.is_at_position(self.pos.pose.position.x,
self.pos.pose.position.y,
self.pos.pose.position.z, 1):
rospy.loginfo("position reached | seconds: {0} of {1}".format(
i / loop_freq, timeout))
reached = True
break
count = count + 1
self.rate.sleep()
self.assertTrue(count < timeout, "took too long to get to position")
rate.sleep()
self.assertTrue(reached, (
"took too long to get to position | current position x: {0}, y: {1}, z: {2} | timeout(seconds): {3}".
format(self.local_position.pose.position.x,
self.local_position.pose.position.y,
self.local_position.pose.position.z, timeout)))
#
# Test method
#
def test_posctl(self):
"""Test offboard position control"""
# FIXME: hack to wait for simulation to be ready
while not self.has_global_pos:
self.rate.sleep()
# delay starting the mission
self.wait_for_topics(30)
positions = (
(0, 0, 0),
(2, 2, 2),
(2, -2, 2),
(-2, -2, 2),
(2, 2, 2))
rospy.loginfo("seting mission mode")
self.set_mode("OFFBOARD", 5)
rospy.loginfo("arming")
self.set_arm(True, 5)
for i in range(0, len(positions)):
self.reach_position(positions[i][0], positions[i][1], positions[i][2], 180)
rospy.loginfo("run mission")
positions = ((0, 0, 0), (2, 2, 2), (2, -2, 2), (-2, -2, 2), (2, 2, 2))
for i in xrange(len(positions)):
self.reach_position(positions[i][0], positions[i][1],
positions[i][2], 18)
rospy.loginfo("disarming")
self.set_arm(False, 5)
if __name__ == '__main__':
import rostest
rostest.rosrun(PKG, 'mavros_offboard_posctl_test', MavrosOffboardPosctlTest)
#unittest.main()
rospy.init_node('test_node', anonymous=True)
rostest.rosrun(PKG, 'mavros_offboard_posctl_test',
MavrosOffboardPosctlTest)
@@ -38,269 +38,399 @@
# The shebang of this file is currently Python2 because some
# dependencies such as pymavlink don't play well with Python3 yet.
from __future__ import division
PKG = 'px4'
import unittest
import rospy
import math
import rosbag
import sys
import os
import time
import glob
import json
import mavros
from pymavlink import mavutil
from mavros import mavlink
import math
import os
import px4tools
from geometry_msgs.msg import PoseStamped
from mavros_msgs.srv import CommandLong, WaypointPush
from mavros_msgs.msg import Mavlink, Waypoint, ExtendedState
from sensor_msgs.msg import NavSatFix
import sys
from mavros import mavlink
from mavros.mission import QGroundControlWP
#from px4_test_helper import PX4TestHelper
from pymavlink import mavutil
from threading import Thread
from mavros_msgs.msg import Altitude, ExtendedState, HomePosition, Mavlink, \
State, Waypoint
from mavros_msgs.srv import CommandBool, SetMode, WaypointPush
from sensor_msgs.msg import NavSatFix
def get_last_log():
try:
log_path = os.environ['PX4_LOG_DIR']
except KeyError:
log_path = os.path.join(os.environ['HOME'], 'ros/rootfs/fs/microsd/log')
last_log_dir = sorted(
glob.glob(os.path.join(log_path, '*')))[-1]
log_path = os.path.join(os.environ['HOME'],
'.ros/rootfs/fs/microsd/log')
last_log_dir = sorted(glob.glob(os.path.join(log_path, '*')))[-1]
last_log = sorted(glob.glob(os.path.join(last_log_dir, '*.ulg')))[-1]
return last_log
def read_new_mission(f):
d = json.load(f)
current = True
for wp in d['items']:
yield Waypoint(
is_current = current,
frame = int(wp['frame']),
command = int(wp['command']),
param1 = float(wp['param1']),
param2 = float(wp['param2']),
param3 = float(wp['param3']),
param4 = float(wp['param4']),
x_lat = float(wp['coordinate'][0]),
y_long = float(wp['coordinate'][1]),
z_alt = float(wp['coordinate'][2]),
autocontinue = bool(wp['autoContinue']))
is_current=current,
frame=int(wp['frame']),
command=int(wp['command']),
param1=float(wp['param1']),
param2=float(wp['param2']),
param3=float(wp['param3']),
param4=float(wp['param4']),
x_lat=float(wp['coordinate'][0]),
y_long=float(wp['coordinate'][1]),
z_alt=float(wp['coordinate'][2]),
autocontinue=bool(wp['autoContinue']))
if current:
current = False
class MavrosMissionTest(unittest.TestCase):
"""
Run a mission
"""
# dictionaries correspond to mavros ExtendedState msg
LAND_STATES = {
0: 'UNDEFINED',
1: 'ON_GROUND',
2: 'IN_AIR',
3: 'TAKEOFF',
4: 'LANDING'
}
VTOL_STATES = {
0: 'VTOL UNDEFINED',
1: 'VTOL MC->FW',
2: 'VTOL FW->MC',
3: 'VTOL MC',
4: 'VTOL FW'
}
def setUp(self):
rospy.init_node('test_node', anonymous=True)
self.rate = rospy.Rate(10) # 10hz
self.rate = rospy.Rate(10) # 10hz
self.has_global_pos = False
self.local_position = PoseStamped()
self.global_position = NavSatFix()
self.extended_state = ExtendedState()
self.home_alt = 0
self.altitude = Altitude()
self.state = State()
self.mc_rad = 5
self.fw_rad = 60
self.fw_alt_rad = 10
self.last_alt_d = 9999
self.last_pos_d = 9999
self.last_alt_d = None
self.last_pos_d = None
self.mission_name = ""
self.sub_topics_ready = {
key: False
for key in ['global_pos', 'home_pos', 'ext_state', 'alt', 'state']
}
# need to simulate heartbeat for datalink loss detection
rospy.Timer(rospy.Duration(0.5), self.send_heartbeat)
# setup ROS topics and services
try:
rospy.wait_for_service('mavros/mission/push', 30)
rospy.wait_for_service('mavros/cmd/arming', 30)
rospy.wait_for_service('mavros/set_mode', 30)
except rospy.ROSException:
self.fail("failed to connect to mavros services")
rospy.wait_for_service('mavros/cmd/command', 30)
self.pub_mavlink = rospy.Publisher('mavlink/to', Mavlink, queue_size=1)
self._srv_cmd_long = rospy.ServiceProxy('mavros/cmd/command', CommandLong, persistent=True)
self._srv_wp_push = rospy.ServiceProxy('mavros/mission/push', WaypointPush, persistent=True)
self.wp_push_srv = rospy.ServiceProxy('mavros/mission/push',
WaypointPush)
self.set_arming_srv = rospy.ServiceProxy('/mavros/cmd/arming',
CommandBool)
self.set_mode_srv = rospy.ServiceProxy('/mavros/set_mode', SetMode)
self.global_pos_sub = rospy.Subscriber('mavros/global_position/global',
NavSatFix,
self.global_position_callback)
self.home_pos_sub = rospy.Subscriber('mavros/home_position/home',
HomePosition,
self.home_position_callback)
self.ext_state_sub = rospy.Subscriber('mavros/extended_state',
ExtendedState,
self.extended_state_callback)
self.alt_sub = rospy.Subscriber('mavros/altitude', Altitude,
self.altitude_callback)
self.state_sub = rospy.Subscriber('mavros/state', State,
self.state_callback)
self.mavlink_pub = rospy.Publisher('mavlink/to', Mavlink, queue_size=1)
rospy.Subscriber("mavros/local_position/pose", PoseStamped, self.position_callback)
rospy.Subscriber("mavros/global_position/global", NavSatFix, self.global_position_callback)
rospy.Subscriber("mavros/extended_state", ExtendedState, self.extended_state_callback)
# need to simulate heartbeat to prevent datalink loss detection
self.hb_mav_msg = mavutil.mavlink.MAVLink_heartbeat_message(
mavutil.mavlink.MAV_TYPE_GCS, 0, 0, 0, 0, 0)
self.hb_mav_msg.pack(mavutil.mavlink.MAVLink('', 2, 1))
self.hb_ros_msg = mavlink.convert_to_rosmsg(self.hb_mav_msg)
self.hb_thread = Thread(target=self.send_heartbeat, args=())
self.hb_thread.daemon = True
self.hb_thread.start()
def tearDown(self):
#self.helper.tearDown()
pass
#
# General callback functions used in tests
# Callback functions
#
def position_callback(self, data):
self.local_position = data
def global_position_callback(self, data):
self.global_position = data
if not self.has_global_pos:
if data.altitude != 0:
self.home_alt = data.altitude
self.has_global_pos = True
if not self.sub_topics_ready['global_pos']:
self.sub_topics_ready['global_pos'] = True
def home_position_callback(self, data):
# this topic publishing seems to be a better indicator that the sim
# is ready, it's not actually needed
self.home_pos_sub.unregister()
if not self.sub_topics_ready['home_pos']:
self.sub_topics_ready['home_pos'] = True
def extended_state_callback(self, data):
if self.extended_state.vtol_state != data.vtol_state:
rospy.loginfo("VTOL state changed from {0} to {1}".format(
self.VTOL_STATES.get(self.extended_state.vtol_state),
self.VTOL_STATES.get(data.vtol_state)))
prev_state = self.extended_state.vtol_state;
if self.extended_state.landed_state != data.landed_state:
rospy.loginfo("landed state changed from {0} to {1}".format(
self.LAND_STATES.get(self.extended_state.landed_state),
self.LAND_STATES.get(data.landed_state)))
self.extended_state = data
if (prev_state != self.extended_state.vtol_state):
print("VTOL state change: %d" % self.extended_state.vtol_state);
if not self.sub_topics_ready['ext_state']:
self.sub_topics_ready['ext_state'] = True
def state_callback(self, data):
if self.state.armed != data.armed:
rospy.loginfo("armed state changed from {0} to {1}".format(
self.state.armed, data.armed))
if self.state.mode != data.mode:
rospy.loginfo("mode changed from {0} to {1}".format(
self.state.mode, data.mode))
self.state = data
# mavros publishes a disconnected state message on init
if not self.sub_topics_ready['state'] and data.connected:
self.sub_topics_ready['state'] = True
def altitude_callback(self, data):
self.altitude = data
# amsl has been observed to be nan while other fields are valid
if not self.sub_topics_ready['alt'] and not math.isnan(data.amsl):
self.sub_topics_ready['alt'] = True
#
# Helper methods
#
def send_heartbeat(self):
rate = rospy.Rate(2) # Hz
while not rospy.is_shutdown():
self.mavlink_pub.publish(self.hb_ros_msg)
try: # prevent garbage in console output when thread is killed
rate.sleep()
except rospy.ROSInterruptException:
pass
def set_mode(self, mode, timeout):
"""mode: PX4 mode string, timeout(int): seconds"""
old_mode = self.state.mode
loop_freq = 1 # Hz
rate = rospy.Rate(loop_freq)
mode_set = False
for i in xrange(timeout * loop_freq):
if self.state.mode == mode:
mode_set = True
rospy.loginfo(
"set mode success | new mode: {0}, old mode: {1} | seconds: {2} of {3}".
format(mode, old_mode, i / loop_freq, timeout))
break
else:
try:
res = self.set_mode_srv(0, mode) # 0 is custom mode
if not res.mode_sent:
rospy.logerr("failed to send mode command")
except rospy.ServiceException as e:
rospy.logerr(e)
rate.sleep()
self.assertTrue(mode_set, (
"failed to set mode | new mode: {0}, old mode: {1} | timeout(seconds): {2}".
format(mode, old_mode, timeout)))
def set_arm(self, arm, timeout):
"""arm: True to arm or False to disarm, timeout(int): seconds"""
old_arm = self.state.armed
loop_freq = 1 # Hz
rate = rospy.Rate(loop_freq)
arm_set = False
for i in xrange(timeout * loop_freq):
if self.state.armed == arm:
arm_set = True
rospy.loginfo(
"set arm success | new arm: {0}, old arm: {1} | seconds: {2} of {3}".
format(arm, old_arm, i / loop_freq, timeout))
break
else:
try:
res = self.set_arming_srv(arm)
if not res.success:
rospy.logerr("failed to send arm command")
except rospy.ServiceException as e:
rospy.logerr(e)
rate.sleep()
self.assertTrue(arm_set, (
"failed to set arm | new arm: {0}, old arm: {1} | timeout(seconds): {2}".
format(arm, old_arm, timeout)))
def is_at_position(self, lat, lon, alt, xy_offset, z_offset):
R = 6371000 # metres
"""alt(amsl), xy_offset, z_offset: meters"""
R = 6371000 # metres
rlat1 = math.radians(lat)
rlat2 = math.radians(self.global_position.latitude)
rlat_d = math.radians(self.global_position.latitude - lat)
rlon_d = math.radians(self.global_position.longitude - lon)
a = (math.sin(rlat_d / 2) * math.sin(rlat_d / 2) +
math.cos(rlat1) * math.cos(rlat2) *
math.sin(rlon_d / 2) * math.sin(rlon_d / 2))
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
a = (math.sin(rlat_d / 2) * math.sin(rlat_d / 2) + math.cos(rlat1) *
math.cos(rlat2) * math.sin(rlon_d / 2) * math.sin(rlon_d / 2))
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
d = R * c
alt_d = abs(alt - self.global_position.altitude)
#rospy.loginfo("d: %f, alt_d: %f", d, alt_d)
alt_d = abs(alt - self.altitude.amsl)
# remember best distances
if self.last_pos_d > d:
if not self.last_pos_d or self.last_pos_d > d:
self.last_pos_d = d
if self.last_alt_d > alt_d:
if not self.last_alt_d or self.last_alt_d > alt_d:
self.last_alt_d = alt_d
rospy.logdebug("d: {0}, alt_d: {1}".format(d, alt_d))
return d < xy_offset and alt_d < z_offset
def reach_position(self, lat, lon, alt, timeout, index):
"""alt(amsl): meters, timeout(int): seconds"""
# reset best distances
self.last_alt_d = 9999
self.last_pos_d = 9999
self.last_alt_d = None
self.last_pos_d = None
rospy.loginfo("trying to reach waypoint " +
"lat: %13.9f, lon: %13.9f, alt: %6.2f, timeout: %d, index: %d" %
(lat, lon, alt, timeout, index))
rospy.loginfo(
"trying to reach waypoint | lat: {0:13.9f}, lon: {1:13.9f}, alt: {2:6.2f}, index: {3}".
format(lat, lon, alt, index))
# does it reach the position in X seconds?
count = 0
while count < timeout:
# does it reach the position in 'timeout' seconds?
loop_freq = 10 # Hz
rate = rospy.Rate(loop_freq)
reached = False
for i in xrange(timeout * loop_freq):
# use MC radius by default
# FIXME: also check MAV_TYPE from system status, otherwise pure fixed-wing won't work
xy_radius = self.mc_rad
z_radius = self.mc_rad
# use FW radius if in FW or in transition
if (self.extended_state.vtol_state == ExtendedState.VTOL_STATE_FW or
self.extended_state.vtol_state == ExtendedState.VTOL_STATE_TRANSITION_TO_MC or
self.extended_state.vtol_state == ExtendedState.VTOL_STATE_TRANSITION_TO_FW):
if (self.extended_state.vtol_state == ExtendedState.VTOL_STATE_FW
or self.extended_state.vtol_state ==
ExtendedState.VTOL_STATE_TRANSITION_TO_MC or
self.extended_state.vtol_state ==
ExtendedState.VTOL_STATE_TRANSITION_TO_FW):
xy_radius = self.fw_rad
z_radius = self.fw_alt_rad
if self.is_at_position(lat, lon, alt, xy_radius, z_radius):
rospy.loginfo("position reached, index: %d, count: %d, pos_d: %f, alt_d: %f" %
(index, count, self.last_pos_d, self.last_alt_d))
reached = True
rospy.loginfo(
"position reached | pos_d: {0:.2f}, alt_d: {1:.2f}, index: {2} | seconds: {3} of {4}".
format(self.last_pos_d, self.last_alt_d, index, i /
loop_freq, timeout))
break
count = count + 1
self.rate.sleep()
rate.sleep()
vtol_state_string = "VTOL undefined"
self.assertTrue(reached, (
"({0}) took too long to get to position | lat: {1:13.9f}, lon: {2:13.9f}, alt: {3:6.2f}, xy off: {4}, z off: {5}, pos_d: {6:.2f}, alt_d: {7:.2f}, VTOL state: {8}, index: {9} | timeout(seconds): {10}".
format(self.mission_name, lat, lon, alt, xy_radius, z_radius,
self.last_pos_d, self.last_alt_d,
self.VTOL_STATES.get(self.extended_state.vtol_state), index,
timeout)))
if (self.extended_state.vtol_state == ExtendedState.VTOL_STATE_MC):
vtol_state_string = "VTOL MC"
if (self.extended_state.vtol_state == ExtendedState.VTOL_STATE_FW):
vtol_state_string = "VTOL FW"
if (self.extended_state.vtol_state == ExtendedState.VTOL_STATE_TRANSITION_TO_MC):
vtol_state_string = "VTOL FW->MC"
if (self.extended_state.vtol_state == ExtendedState.VTOL_STATE_TRANSITION_TO_FW):
vtol_state_string = "VTOL MC->FW"
self.assertTrue(count < timeout, (("(%s) took too long to get to position " +
"lat: %13.9f, lon: %13.9f, alt: %6.2f, xy off: %f, z off: %f, timeout: %d, index: %d, pos_d: %f, alt_d: %f, VTOL state: %s") %
(self.mission_name, lat, lon, alt, xy_radius, z_radius, timeout, index, self.last_pos_d, self.last_alt_d, vtol_state_string)))
def run_mission(self):
# Hack to wait until vehicle is ready
# TODO better integration with pre-flight status reporting
time.sleep(5)
"""switch mode: auto and arm"""
self._srv_cmd_long(False, 176, False,
# custom, auto, mission
1, 4, 4, 0, 0, 0, 0)
# make sure the first command doesn't get lost
time.sleep(1)
self._srv_cmd_long(False, 400, False,
# arm
1, 0, 0, 0, 0, 0, 0)
def wait_until_ready(self):
"""FIXME: hack to wait for simulation to be ready"""
while not self.has_global_pos:
self.rate.sleep()
def wait_on_landing(self, timeout, index):
"""Wait for landed state"""
rospy.loginfo("waiting for landing " +
"timeout: %d, index: %d" %
(timeout, index))
count = 0
while count < timeout:
if self.extended_state.landed_state == ExtendedState.LANDED_STATE_ON_GROUND:
def wait_for_topics(self, timeout):
"""wait for simulation to be ready, make sure we're getting topic info
from all topics by checking dictionary of flag values set in callbacks,
timeout(int): seconds"""
rospy.loginfo("waiting for simulation topics to be ready")
loop_freq = 1 # Hz
rate = rospy.Rate(loop_freq)
simulation_ready = False
for i in xrange(timeout * loop_freq):
if all(value for value in self.sub_topics_ready.values()):
simulation_ready = True
rospy.loginfo("simulation topics ready | seconds: {0} of {1}".
format(i / loop_freq, timeout))
break
count = count + 1
self.rate.sleep()
rate.sleep()
self.assertTrue(count < timeout, ("(%s) landing not detected after landing WP " +
"timeout: %d, index: %d") %
(self.mission_name, timeout, index))
self.assertTrue(simulation_ready, (
"failed to hear from all subscribed simulation topics | topic ready flags: {0} | timeout(seconds): {1}".
format(self.sub_topics_ready, timeout)))
def wait_on_landed_state(self, desired_landed_state, timeout, index):
rospy.loginfo(
"waiting for landed state | state: {0}, index: {1}".format(
self.LAND_STATES.get(desired_landed_state), index))
loop_freq = 10 # Hz
rate = rospy.Rate(loop_freq)
landed_state_confirmed = False
for i in xrange(timeout * loop_freq):
if self.extended_state.landed_state == desired_landed_state:
landed_state_confirmed = True
rospy.loginfo(
"landed state confirmed | state: {0}, index: {1}".format(
self.LAND_STATES.get(desired_landed_state), index))
break
rate.sleep()
self.assertTrue(landed_state_confirmed, (
"({0}) landed state not detected | desired: {1}, current: {2} | index: {3}, timeout(seconds): {4}".
format(self.mission_name,
self.LAND_STATES.get(desired_landed_state),
self.LAND_STATES.get(self.extended_state.landed_state),
index, timeout)))
def wait_on_transition(self, transition, timeout, index):
"""Wait for VTOL transition"""
rospy.loginfo("waiting for VTOL transition " +
"transition: %d, timeout: %d, index: %d" %
(transition, timeout, index))
count = 0
while count < timeout:
# transition to MC
if (transition == ExtendedState.VTOL_STATE_MC and
self.extended_state.vtol_state == ExtendedState.VTOL_STATE_MC):
"""Wait for VTOL transition, timeout(int): seconds"""
rospy.loginfo(
"waiting for VTOL transition | transition: {0}, index: {1}".format(
self.VTOL_STATES.get(transition), index))
loop_freq = 10 # Hz
rate = rospy.Rate(loop_freq)
transitioned = False
for i in xrange(timeout * loop_freq):
if transition == self.extended_state.vtol_state:
rospy.loginfo(
"transitioned | index: {0} | seconds: {1} of {2}".format(
index, i / loop_freq, timeout))
transitioned = True
break
# transition to FW
if (transition == ExtendedState.VTOL_STATE_FW and
self.extended_state.vtol_state == ExtendedState.VTOL_STATE_FW):
break
rate.sleep()
count = count + 1
self.rate.sleep()
self.assertTrue(count < timeout, ("(%s) transition not detected " +
"timeout: %d, index: %d") %
(self.mission_name, timeout, index))
def send_heartbeat(self, event=None):
# mav type gcs
mavmsg = mavutil.mavlink.MAVLink_heartbeat_message(6, 0, 0, 0, 0, 0)
# XXX: hack: using header object to set mav properties
mavmsg.pack(mavutil.mavlink.MAVLink_header(0, 0, 0, 2, 1))
rosmsg = mavlink.convert_to_rosmsg(mavmsg)
self.pub_mavlink.publish(rosmsg)
self.assertTrue(transitioned, (
"({0}) transition not detected | index: {1} | timeout(seconds): {2}, ".
format(self.mission_name, index, timeout)))
#
# Test method
#
def test_mission(self):
"""Test mission"""
@@ -309,11 +439,11 @@ class MavrosMissionTest(unittest.TestCase):
return
self.mission_name = sys.argv[1]
mission_file = os.path.dirname(os.path.realpath(__file__)) + "/" + sys.argv[1]
mission_file = os.path.dirname(
os.path.realpath(__file__)) + "/" + sys.argv[1]
rospy.loginfo("reading mission %s", mission_file)
rospy.loginfo("reading mission {0}".format(mission_file))
wps = []
with open(mission_file, 'r') as f:
mission_ext = os.path.splitext(mission_file)[1]
if mission_ext == '.mission':
@@ -330,62 +460,79 @@ class MavrosMissionTest(unittest.TestCase):
else:
raise IOError('unknown mission file extension', mission_ext)
rospy.loginfo("wait until ready")
self.wait_until_ready()
rospy.loginfo("send mission")
res = self._srv_wp_push(wps)
rospy.loginfo(res)
self.assertTrue(res.success, "(%s) mission could not be transfered" % self.mission_name)
result = False
try:
res = self.wp_push_srv(start_index=0, waypoints=wps)
result = res.success
except rospy.ServiceException as e:
rospy.logerr(e)
self.assertTrue(
result,
"({0}) mission could not be transfered".format(self.mission_name))
# delay starting the mission
self.wait_for_topics(30)
# make sure the simulation is ready to start the mission
self.wait_on_landed_state(ExtendedState.LANDED_STATE_ON_GROUND, 10, -1)
rospy.loginfo("seting mission mode")
self.set_mode("AUTO.MISSION", 5)
rospy.loginfo("arming")
self.set_arm(True, 5)
rospy.loginfo("run mission")
self.run_mission()
index = 0
for waypoint in wps:
for index, waypoint in enumerate(wps):
# only check position for waypoints where this makes sense
if waypoint.frame == Waypoint.FRAME_GLOBAL_REL_ALT or waypoint.frame == Waypoint.FRAME_GLOBAL:
alt = waypoint.z_alt
if waypoint.frame == Waypoint.FRAME_GLOBAL_REL_ALT:
alt += self.home_alt
alt += self.altitude.amsl - self.altitude.relative
self.reach_position(waypoint.x_lat, waypoint.y_long, alt, 600, index)
self.reach_position(waypoint.x_lat, waypoint.y_long, alt, 60,
index)
# check if VTOL transition happens if applicable
if waypoint.command == 84 or waypoint.command == 85 or waypoint.command == 3000:
transition = waypoint.param1
if waypoint.command == 84: # VTOL takeoff implies transition to FW
if waypoint.command == 84: # VTOL takeoff implies transition to FW
transition = ExtendedState.VTOL_STATE_FW
if waypoint.command == 85: # VTOL takeoff implies transition to MC
if waypoint.command == 85: # VTOL takeoff implies transition to MC
transition = ExtendedState.VTOL_STATE_MC
self.wait_on_transition(transition, 600, index)
self.wait_on_transition(transition, 60, index)
# after reaching position, wait for landing detection if applicable
if waypoint.command == 85 or waypoint.command == 21:
self.wait_on_landing(600, index)
self.wait_on_landed_state(ExtendedState.LANDED_STATE_ON_GROUND,
60, index)
index += 1
rospy.loginfo("disarming")
self.set_arm(False, 5)
rospy.loginfo("mission done, calculating performance metrics")
last_log = get_last_log()
rospy.loginfo("log file %s", last_log)
data = px4tools.ulog.read_ulog(last_log).concat(dt=0.1)
data = px4tools.ulog.compute_data(data)
rospy.loginfo("log file {0}".format(last_log))
data = px4tools.read_ulog(last_log).concat(dt=0.1)
data = px4tools.compute_data(data)
res = px4tools.estimator_analysis(data, False)
# enforce performance
self.assertTrue(abs(res['roll_error_mean']) < 5.0, str(res))
self.assertTrue(abs(res['roll_error_mean']) < 5.0, str(res))
self.assertTrue(abs(res['pitch_error_mean']) < 5.0, str(res))
self.assertTrue(abs(res['yaw_error_mean']) < 5.0, str(res))
self.assertTrue(res['roll_error_std'] < 5.0, str(res))
self.assertTrue(res['pitch_error_std'] < 5.0, str(res))
self.assertTrue(res['yaw_error_std'] < 5.0, str(res))
if __name__ == '__main__':
import rostest
rospy.init_node('test_node', anonymous=True)
name = "mavros_mission_test"
if len(sys.argv) > 1:
name += "-%s" % sys.argv[1]
-31
View File
@@ -1,31 +0,0 @@
#!/bin/bash
#
# Run container and start test execution
#
# License: according to LICENSE.md in the root directory of the PX4 Firmware repository
set -e
if [ -z "$WORKSPACE" ]; then
echo "\$WORKSPACE not set"
exit 1
fi
IMAGE=px4io/px4-dev-ros:v1.0
# Pulling latest image
echo "===> pull latest Docker image"
docker pull $IMAGE
# removing some images might fail
set +e
docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
set -e
echo "<==="
#
# Running SITL testing container
# Assuming that necessary source projects, including this one, are cloned in the build server workspace of this job.
#
echo "===> run container"
docker run --rm -v "$WORKSPACE:/job:rw" $IMAGE bash "/job/Firmware/integrationtests/run_tests.bash" /job/Firmware
echo "<==="
-140
View File
@@ -1,140 +0,0 @@
#!/bin/bash
#
# Starts tests from within the container
#
# License: according to LICENSE.md in the root directory of the PX4 Firmware repository
set -e
# TODO move to docker image
pip install --upgrade numpy -q
pip install px4tools pymavlink toml -q
# A POSIX variable
OPTIND=1 # Reset in case getopts has been used previously in the shell.
# Initialize our own variables:
do_clean=true
gui=false
while getopts "h?og" opt; do
case "$opt" in
h|\?)
echo """
$0 [-h] [-o] [-g]
-h show help
-o don't clean before building (to save time)
-g run gazebo gui
"""
exit 0
;;
o) do_clean=false
echo "not cleaning"
;;
g) gui=true
;;
esac
done
# determine the directory of the source given the directory of this script
pushd `dirname $0` > /dev/null
SCRIPTPATH=`pwd`
popd > /dev/null
ORIG_SRC=$(dirname $SCRIPTPATH)
# set paths
JOB_DIR=$(dirname $ORIG_SRC)
CATKIN_DIR=$JOB_DIR/catkin
BUILD_DIR=$CATKIN_DIR/build/px4
SRC_DIR=${CATKIN_DIR}/src/px4
echo setting up ROS paths
if [ -f /opt/ros/indigo/setup.bash ]
then
source /opt/ros/indigo/setup.bash
elif [ -f /opt/ros/kinetic/setup.bash ]
then
source /opt/ros/kinetic/setup.bash
else
echo "could not find /opt/ros/{ros-distro}/setup.bash"
exit 1
fi
export ROS_HOME=$JOB_DIR/.ros
export ROS_LOG_DIR=$ROS_HOME/log
export ROS_TEST_RESULT_DIR=$ROS_HOME/test_results/px4
export PX4_LOG_DIR=$ROS_HOME/rootfs/fs/microsd/log
TEST_RESULT_TARGET_DIR=$JOB_DIR/test_results
# TODO
# BAGS=$ROS_HOME
# CHARTS=$ROS_HOME/charts
# EXPORT_CHARTS=/sitl/testing/export_charts.py
if $do_clean
then
echo cleaning
rm -rf $CATKIN_DIR
rm -rf $ROS_HOME
rm -rf $TEST_RESULT_TARGET_DIR
else
echo skipping clean step
fi
echo "=====> compile ($SRC_DIR)"
mkdir -p $ROS_HOME
mkdir -p $CATKIN_DIR/src
mkdir -p $TEST_RESULT_TARGET_DIR
if ! [ -d $SRC_DIR ]
then
ln -s $ORIG_SRC $SRC_DIR
ln -s $ORIG_SRC/Tools/sitl_gazebo ${CATKIN_DIR}/src/mavlink_sitl_gazebo
fi
cd $CATKIN_DIR
catkin_make
. ./devel/setup.bash
echo "<====="
# print paths to user
echo -e "JOB_DIR\t\t: $JOB_DIR"
echo -e "ROS_HOME\t: $ROS_HOME"
echo -e "CATKIN_DIR\t: $CATKIN_DIR"
echo -e "BUILD_DIR\t: $BUILD_DIR"
echo -e "SRC_DIR\t\t: $SRC_DIR"
echo -e "ROS_TEST_RESULT_DIR\t: $ROS_TEST_RESULT_DIR"
echo -e "ROS_LOG_DIR\t\t: $ROS_LOG_DIR"
echo -e "PX4_LOG_DIR\t\t: $PX4_LOG_DIR"
echo -e "TEST_RESULT_TARGET_DIR\t: $TEST_RESULT_TARGET_DIR"
# don't exit on error anymore (because single tests or exports might fail)
# however, stop executing tests after the first failure
set +e
echo "=====> run tests"
test $? -eq 0 && rostest px4 mavros_posix_tests_iris.launch gui:=$gui
# commented out optical flow test for now since ci server has
# an issue producing the simulated flow camera currently
#test $? -eq 0 && rostest px4 mavros_posix_tests_iris_opt_flow.launch gui:=$gui
test $? -eq 0 && rostest px4 mavros_posix_tests_standard_vtol.launch gui:=$gui
TEST_RESULT=$?
echo "<====="
# TODO
echo "=====> process test results"
# cd $BAGS
# for bag in `ls *.bag`
# do
# echo "processing bag: $bag"
# python $EXPORT_CHARTS $CHARTS $bag
# done
echo "copy build test results to job directory"
cp -r $ROS_TEST_RESULT_DIR/* ${TEST_RESULT_TARGET_DIR}
cp -r $ROS_LOG_DIR/* ${TEST_RESULT_TARGET_DIR}
cp -r $PX4_LOG_DIR/* ${TEST_RESULT_TARGET_DIR}
# cp $BAGS/*.bag ${TEST_RESULT_TARGET_DIR}/
# cp -r $CHARTS ${TEST_RESULT_TARGET_DIR}/
echo "<====="
# need to return error if tests failed, else Jenkins won't notice the failure
exit $TEST_RESULT
-19
View File
@@ -1,19 +0,0 @@
#!/bin/bash
#
# Upload SITL CI logs to Flight Review
#
# License: according to LICENSE.md in the root directory of the PX4 Firmware repository
if [ -z "$WORKSPACE" ] || [ -z "${ghprbActualCommitAuthorEmail}" ] || [ -z "${ghprbPullDescription}" ]; then
echo "Environment not set. Needs to be called from within Jenkins."
exit 1
fi
echo "Uploading test logs to Flight Review"
CMD="$WORKSPACE/Firmware/Tools/upload_log.py"
find "$WORKSPACE/test_results" -name \*.ulg -exec "$CMD" -q \
--description "${ghprbPullDescription}" --source CI "{}" \;
# XXX: move up if we want email notifications
# --email "${ghprbActualCommitAuthorEmail}" \
+1 -1
View File
@@ -9,7 +9,7 @@
<arg name="Y" default="0"/>
<arg name="est" default="lpe"/>
<arg name="est" default="ekf2"/>
<arg name="vehicle" default="iris"/>
<arg name="world" default="$(find mavlink_sitl_gazebo)/worlds/empty.world"/>
<arg name="sdf" default="$(find mavlink_sitl_gazebo)/models/$(arg vehicle)/$(arg vehicle).sdf"/>
+2 -2
View File
@@ -7,7 +7,7 @@
<arg name="R" default="0"/>
<arg name="P" default="0"/>
<arg name="Y" default="0"/>
<arg name="est" default="lpe"/>
<arg name="est" default="ekf2"/>
<arg name="vehicle" default="iris"/>
<arg name="world" default="$(find mavlink_sitl_gazebo)/worlds/empty.world"/>
<arg name="sdf" default="$(find mavlink_sitl_gazebo)/models/$(arg vehicle)/$(arg vehicle).sdf"/>
@@ -40,4 +40,4 @@
</launch>
<!-- vim: set et ft=xml fenc=utf-8 ff=unix sts=0 sw=4 ts=4 : -->
<!-- vim: set et ft=xml fenc=utf-8 ff=unix sts=0 sw=4 ts=4 : -->

Some files were not shown because too many files have changed in this diff Show More