364 Commits
Author SHA1 Message Date
Sem van der Hoeven 634a00a837 remove checking of nan 2023-05-15 15:47:45 +02:00
Sem van der Hoeven da5ee7fc88 remove checking of nan 2023-05-15 15:46:36 +02:00
Sem van der Hoeven d8305499ab add check for NAN 2023-05-15 15:41:48 +02:00
Sem van der Hoeven 7d316ce740 add only sending setpoint when new setpoint has arrived 2023-05-15 15:33:58 +02:00
Sem van der Hoeven 1dc9234400 log incoming request 2023-05-15 15:11:18 +02:00
Sem van der Hoeven 71ba5cb171 change trajectory message to separate x y and z values 2023-05-15 12:36:44 +02:00
Sem van der Hoeven f6873d553e add checking for NaN when handling velocity 2023-05-15 11:28:05 +02:00
Sem van der Hoeven 1ba1d21487 change values that don't need to be changed to NaNA 2023-05-15 11:23:36 +02:00
Sem van der Hoeven 5afec281a2 try continuous sending of setpoints 2023-05-15 11:10:19 +02:00
Sem van der Hoeven fa4af5b39f add logs of which setpoint is being sent 2023-05-15 11:02:30 +02:00
Sem van der Hoeven d50758cb73 only send trajectory setpoint once 2023-05-15 11:01:25 +02:00
Sem van der Hoeven 61ee751642 better logging 2023-05-15 10:54:20 +02:00
Sem van der Hoeven 25a9aa3509 add logging of receiving correct trajectory setpoint message 2023-05-15 10:51:56 +02:00
Sem van der Hoeven 8cb032b8d7 fix trajectory setpoint control mode checking 2023-05-15 10:49:15 +02:00
Sem van der Hoeven 3d74ee2c41 add proper checking of control modes 2023-05-15 10:45:20 +02:00
Sem van der Hoeven 3ee881772c edit commands for test controller and remove spamming logs 2023-05-15 10:37:47 +02:00
Sem van der Hoeven d1c8ca537f change flying bool to user_in_control for clarity 2023-05-15 10:33:27 +02:00
Sem van der Hoeven 33872ab999 typo 2023-05-15 10:30:00 +02:00
Sem van der Hoeven e240058f44 change types of service 2023-05-15 10:29:17 +02:00
Sem van der Hoeven 1575afc49c add new services to cmakelists.txt 2023-05-15 10:16:23 +02:00
Sem van der Hoeven dcd707fb34 add arm and disarm service that return boolean for status and use this in test controller 2023-05-15 10:15:31 +02:00
Sem van der Hoeven 03e9b2f20f add logs after connecting to services 2023-05-15 09:55:18 +02:00
Sem van der Hoeven 71a7c30cef arming?? 2023-05-12 17:52:20 +02:00
Sem van der Hoeven f080d283f6 arming? 2023-05-12 17:49:45 +02:00
Sem van der Hoeven 4257b90da7 remove arming 2023-05-12 17:45:08 +02:00
Sem van der Hoeven 0c86cdcb53 test 2023-05-12 17:43:55 +02:00
Sem van der Hoeven eb599f7641 test 2023-05-12 17:42:54 +02:00
Sem van der Hoeven 5654e44088 huh 2023-05-12 17:42:02 +02:00
Sem van der Hoeven fa16f6e304 add arm service instead of message 2023-05-12 17:40:45 +02:00
Sem van der Hoeven e245e143ca correct control modes 2023-05-12 17:34:36 +02:00
Sem van der Hoeven f58fb50f26 actually send control mode 2023-05-12 17:33:02 +02:00
Sem van der Hoeven a670aa8c1a add ability to arm 2023-05-12 17:30:00 +02:00
Sem van der Hoeven ff9b01cc79 add changing control modes in test controller 2023-05-12 17:25:02 +02:00
Sem van der Hoeven 5b4c6c149c change back control mode 2023-05-12 16:19:27 +02:00
Sem van der Hoeven 2c4f601759 add trajectory setpoint handling 2023-05-12 16:18:39 +02:00
Sem van der Hoeven 46d32066a2 bruh 2023-05-12 15:46:22 +02:00
Sem van der Hoeven 3b41f4f81d add test arming back after 20 setpoints 2023-05-12 15:13:08 +02:00
Sem van der Hoeven eae3620848 remove new_setpoint bool 2023-05-12 15:06:05 +02:00
Sem van der Hoeven 3ba698cc5c log variables 2023-05-12 15:02:13 +02:00
Sem van der Hoeven 94c71e4aa0 log 2023-05-12 14:59:01 +02:00
Sem van der Hoeven e4e9d60ead add more logs 2023-05-12 14:54:22 +02:00
Sem van der Hoeven cdc8a9fed2 add extra log 2023-05-12 14:20:37 +02:00
Sem van der Hoeven 503d8f80a9 fix name of arm service variable 2023-05-12 14:05:38 +02:00
Sem van der Hoeven ceb1c8222b fix include name 2023-05-12 14:03:05 +02:00
Sem van der Hoeven 77262e42e5 setting default yaw speed 2023-05-12 13:57:54 +02:00
Sem van der Hoeven 55e7af159f add sending different setpoints 2023-05-12 13:56:49 +02:00
Sem van der Hoeven 3da7ac0306 change service response to success boolean 2023-05-12 12:52:33 +02:00
Sem van der Hoeven 6bc357b6f8 add control modes h file 2023-05-12 12:42:13 +02:00
Sem van der Hoeven 10191e122b change checking of control_mode 2023-05-12 12:29:31 +02:00
Sem van der Hoeven b20a75dc92 typo 2023-05-12 12:22:47 +02:00
Sem van der Hoeven 9faab231e7 change checking of set bit 2023-05-12 12:19:03 +02:00
Sem van der Hoeven 9785136a48 defines and logging control mode 2023-05-12 12:16:14 +02:00
Sem van der Hoeven 5424cfb3f4 add drone control mode message definition 2023-05-11 14:02:24 +02:00
Sem van der Hoeven 89a37a8f9c add print of service 2023-05-10 16:40:01 +02:00
Sem van der Hoeven 567604033b ; 2023-05-10 16:28:46 +02:00
Sem van der Hoeven 436051db5e typo 2023-05-10 16:28:01 +02:00
Sem van der Hoeven 3665d0ddd7 add bind and fix typo 2023-05-10 16:27:10 +02:00
Sem van der Hoeven b3d170a3db add include for drone services 2023-05-10 16:25:02 +02:00
Sem van der Hoeven 8a94168414 try to build 2023-05-10 16:23:01 +02:00
Sem van der Hoeven 1d5ecf96c8 add drone services in dependencies of heartbeat target 2023-05-10 15:43:57 +02:00
Sem van der Hoeven 55ec3d7f89 merge with main 2023-05-10 15:42:15 +02:00
Sem van der Hoeven 7ad74287e4 add changing control mode of heartbeat through service 2023-05-10 15:31:37 +02:00
Sem van der Hoeven b1dbd291a8 remove images 2023-05-10 14:45:14 +02:00
Sem van der Hoeven 678d0e5443 remove log file 2023-05-10 14:44:45 +02:00
Sem van der Hoeven e9b80144c7 remove webcam shot 2023-05-10 14:44:28 +02:00
SemvdH 1036530ed2 Merge pull request #6 from SemvdH/camera
Camera node to take pictures is done
2023-05-10 14:43:47 +02:00
Sem van der Hoeven 35207a0c04 add vehicle control service to drone services 2023-05-10 14:42:00 +02:00
Sem van der Hoeven b178db9c33 add seetting resolution according to variables 2023-05-10 11:36:40 +02:00
Sem van der Hoeven d0800b90ab add images 2023-05-10 11:32:45 +02:00
Sem van der Hoeven 6880dcc8b2 fix result image path 2023-05-10 11:31:20 +02:00
Sem van der Hoeven 905360db88 remove opencv 2023-05-10 11:29:47 +02:00
Sem van der Hoeven 6c4050742b add taking picture with fswebcam 2023-05-10 11:27:38 +02:00
Sem van der Hoeven fdab7ff112 camera img 2023-05-10 10:36:32 +02:00
Sem van der Hoeven e739736477 camera img 2023-05-10 10:34:47 +02:00
Sem van der Hoeven 021b75dd39 bruh 2023-05-10 10:26:11 +02:00
Sem van der Hoeven 097ca3c533 fjkdashfjdal 2023-05-10 10:17:59 +02:00
Sem van der Hoeven 57662f42b4 fjkdashfjdal 2023-05-10 10:14:02 +02:00
Sem van der Hoeven e4c0db4553 the fuck 2023-05-10 10:11:43 +02:00
Sem van der Hoeven 31f3959de4 add services 2023-05-09 12:48:18 +02:00
Sem van der Hoeven 7ff51fc904 smaller movements to be safe 2023-05-09 08:45:11 +02:00
Sem van der Hoeven 5aad5c4ce2 add small up or down to test controller 2023-05-09 08:43:56 +02:00
Sem van der Hoeven 5d07a5975f add opencv back 2023-05-08 18:14:24 +02:00
Sem van der Hoeven 1fb07c5cc3 remove opencv 2023-05-08 18:09:24 +02:00
Sem van der Hoeven 8fb2121056 add picamera 2023-05-08 18:08:41 +02:00
Sem van der Hoeven 1d80e9530c smaller resolution 2023-05-08 17:55:33 +02:00
Sem van der Hoeven c7fac34a23 add print of resolution 2023-05-08 17:54:56 +02:00
Sem van der Hoeven 59871da656 add resize function 2023-05-08 17:53:41 +02:00
Sem van der Hoeven 4117f415c7 change setting resolution in constructor 2023-05-08 17:44:24 +02:00
Sem van der Hoeven ecc49c0751 convert result tuple to string 2023-05-08 17:39:53 +02:00
Sem van der Hoeven 63b40d7e8f add setting resolution 2023-05-08 17:38:40 +02:00
Sem van der Hoeven cc78c73349 add setting resolution 2023-05-08 17:35:55 +02:00
Sem van der Hoeven 475d2c20c0 add 4k capture 2023-05-08 17:30:42 +02:00
Sem van der Hoeven 228b140c95 add drone image 2023-05-08 17:21:10 +02:00
Sem van der Hoeven 3366364778 add dedicated folder 2023-05-08 17:19:42 +02:00
Sem van der Hoeven 93b09a49a9 add formatting image name 2023-05-08 17:17:58 +02:00
Sem van der Hoeven 68dd9d4a01 add image? 2023-05-08 17:14:30 +02:00
Sem van der Hoeven ed68bf3a03 add image? 2023-05-08 17:12:53 +02:00
Sem van der Hoeven 43e8245844 remove import * 2023-05-08 17:10:54 +02:00
Sem van der Hoeven 7d82c1f33a use opencv for image taking and writing 2023-05-08 17:08:34 +02:00
Sem van der Hoeven d9707d6157 add service to cmakelists.txt of drone_services package 2023-05-08 16:25:57 +02:00
Sem van der Hoeven 3cb0184771 fill in setup.py for camera controller 2023-05-08 16:23:29 +02:00
Sem van der Hoeven f83520c29a add camera service 2023-05-08 16:20:37 +02:00
Sem van der Hoeven 124466c65b add camera package to src folder 2023-05-08 15:50:46 +02:00
Sem van der Hoeven a236b0d52f add camera package 2023-05-08 15:44:55 +02:00
SemvdH 10d03949ca Merge pull request #5 from SemvdH/service
merge Service branch into main
2023-05-08 15:42:59 +02:00
Sem van der Hoeven 44b3f135a9 add comments and improve code for object_detection package 2023-05-05 16:28:27 +02:00
Sem van der Hoeven 0a1ef8af3d add comments and code to lidar node 2023-05-05 16:19:24 +02:00
Sem van der Hoeven 6a29220bc9 add comments 2023-05-05 12:57:48 +02:00
Sem van der Hoeven 07f0202d51 remove unnecessary pipe operator from height 2023-05-05 12:49:18 +02:00
Sem van der Hoeven 615190ca06 add comments to heartbeat 2023-05-05 11:52:29 +02:00
Sem van der Hoeven b93a616f58 add emergency stop 2023-05-04 14:55:39 +02:00
Sem van der Hoeven 4f4c148b69 add printing q only if new setpoint has been received 2023-05-04 14:53:05 +02:00
Sem van der Hoeven 5bd2885ad8 add print of q_d 2023-05-04 14:49:07 +02:00
Sem van der Hoeven 3baad7c7bd set proper getting average of base_q 2023-05-04 14:43:39 +02:00
Sem van der Hoeven e9e6e033d1 add printing of base_q 2023-05-04 14:27:30 +02:00
Sem van der Hoeven 97a72d5a4a add calculation of base_q into message setpoint 2023-05-04 14:25:29 +02:00
Sem van der Hoeven 5ab0a39ee3 change up to 0.05 2023-05-04 11:53:40 +02:00
Sem van der Hoeven 2485647c72 add checking for up or down with sshkeyboard¨v 2023-05-04 11:51:59 +02:00
Sem van der Hoeven 7133a11e92 change char to key 2023-05-04 11:49:06 +02:00
Sem van der Hoeven 96edc69227 use sshkeyboard library 2023-05-04 11:23:03 +02:00
Sem van der Hoeven be2ef48f0e add _1 placeholder to subscription bind 2023-05-03 16:49:39 +02:00
Sem van der Hoeven 78d5221633 add base_q amount 2023-05-03 16:40:59 +02:00
Sem van der Hoeven 2b287c561d add subscription to vehicle attitude 2023-05-03 16:33:09 +02:00
Sem van der Hoeven 5f90c53128 add extra print in service receive: 2023-05-03 15:45:18 +02:00
Sem van der Hoeven 741fa5b096 change sending to floats 2023-05-03 15:38:45 +02:00
Sem van der Hoeven c88e82d42d bug 2023-05-03 15:36:10 +02:00
Sem van der Hoeven adac3eb022 change setting thrust and angles 2023-05-03 15:34:57 +02:00
Sem van der Hoeven db1322e2de add incrementing/decrementing values 2023-05-03 15:21:49 +02:00
Sem van der Hoeven 2c3123039e change pitch and yaw 2023-05-03 15:08:58 +02:00
Sem van der Hoeven 72b252a970 change pitch and yaw 2023-05-03 15:01:51 +02:00
Sem van der Hoeven bb26e74f54 change position of parameters 2023-05-03 14:58:00 +02:00
Sem van der Hoeven a23286f282 change service to be correct 2023-05-03 14:38:22 +02:00
Sem van der Hoeven fbef263682 remove yaw pitch and roll body 2023-05-03 14:35:44 +02:00
Sem van der Hoeven 6db6c89bd3 add increasing/decreasing yaw pitch roll instead of setting 2023-05-03 14:23:42 +02:00
Sem van der Hoeven 779a5c9987 remove prints of keys 2023-05-03 14:20:21 +02:00
Sem van der Hoeven 85b56aef7b change vk to ints 2023-05-03 14:19:28 +02:00
Sem van der Hoeven bb426cf1dc add printing directions 2023-05-03 14:18:02 +02:00
Sem van der Hoeven 80fa83a42f remove waiting on service for testing 2023-05-03 14:12:40 +02:00
Sem van der Hoeven 4fd44cec46 add controls info 2023-05-03 14:12:09 +02:00
Sem van der Hoeven 1b48c1d4b7 change every self.logger to self.get_logger 2023-05-03 14:09:54 +02:00
Sem van der Hoeven cfa773231e add on_release 2023-05-03 14:06:05 +02:00
Sem van der Hoeven d23a16358b test keys 2023-05-03 14:03:11 +02:00
Sem van der Hoeven e5ae3dedfb add package description and licence 2023-05-03 14:02:01 +02:00
Sem van der Hoeven 8a017bd7b9 add entry point 2023-05-03 13:54:34 +02:00
Sem van der Hoeven 5b779a9ae3 add keyboard listener 2023-05-03 13:49:36 +02:00
Sem van der Hoeven 0a56a1fbb9 change passing q array by reference 2023-05-03 12:30:04 +02:00
Sem van der Hoeven 66880f710d add print of q 2023-05-03 12:23:48 +02:00
Sem van der Hoeven 1ea831d1c4 add extra checks for when armed or not armed 2023-05-03 12:06:10 +02:00
Sem van der Hoeven ade2b38a58 add extra checks for when armed or not armed 2023-05-03 12:05:03 +02:00
Sem van der Hoeven d084827f67 add empty service 2023-05-03 11:54:41 +02:00
Sem van der Hoeven 796c74f318 add disarm service 2023-05-03 11:48:25 +02:00
Sem van der Hoeven 09b6c6110e change to use _body msg params 2023-05-02 16:39:13 +02:00
Sem van der Hoeven 0a18a68f5c change to attitude heartbeat 2023-05-02 16:24:24 +02:00
Sem van der Hoeven b0f261848c change to attitude setpoint 2023-05-02 16:10:01 +02:00
Sem van der Hoeven 38079342ff change to attitude 2023-05-02 15:40:54 +02:00
Sem van der Hoeven 5b04a69e78 change to trajectorysetpoint 2023-05-02 14:26:27 +02:00
Sem van der Hoeven 7d2624e717 add import for velocity service 2023-05-02 14:08:24 +02:00
Sem van der Hoeven dab4077cef change to acceleration setpoints 2023-05-02 13:55:19 +02:00
Sem van der Hoeven a62a640c73 Merge branch 'service' of github.com:SemvdH/5g_drone_ROS2 into service 2023-05-02 13:55:13 +02:00
Sem van der Hoeven b971c7989e change to acceleration setpoints 2023-05-02 13:55:06 +02:00
Sem van der Hoeven 9852edb8b6 add python package for testing controls 2023-05-02 13:48:52 +02:00
Sem van der Hoeven a65c6b5894 Merge branch 'service' of github.com:SemvdH/5g_drone_ROS2 into service 2023-05-02 13:48:48 +02:00
Sem van der Hoeven e134bb2b72 add python package for testing controls 2023-05-02 13:48:41 +02:00
Sem van der Hoeven dd474bf8ea add more log 2023-05-02 12:11:46 +02:00
Sem van der Hoeven 2a69321147 Merge branch 'service' of github.com:SemvdH/5g_drone_ROS2 into service 2023-05-02 12:01:41 +02:00
Sem van der Hoeven b058713903 fix bug v2 2023-05-02 12:01:36 +02:00
Sem van der Hoeven e25abc3973 fix bug 2023-05-02 12:00:57 +02:00
Sem van der Hoeven 1e521ea890 add service control 2023-05-02 11:54:57 +02:00
Sem van der Hoeven 517240a463 change to gradually increase thrust 2023-05-02 11:43:35 +02:00
Sem van der Hoeven ce89e730fa change to attitude setpoints 2023-05-02 11:40:15 +02:00
Sem van der Hoeven 716c80d905 add back offboard control mode publisher 2023-05-02 11:27:05 +02:00
Sem van der Hoeven f23415f60d test 2023-05-02 11:24:06 +02:00
Sem van der Hoeven 0b5d4c2c4f change px4 controller to setvelocity service 2023-05-02 11:08:53 +02:00
Sem van der Hoeven 4249f2b589 add setAttitude service 2023-05-02 11:05:51 +02:00
Sem van der Hoeven d149b72c24 change printout 2023-05-01 16:17:39 +02:00
Sem van der Hoeven 767c658900 add service back 2023-05-01 16:15:49 +02:00
Sem van der Hoeven 2513e56631 add include srv 2023-05-01 16:13:55 +02:00
Sem van der Hoeven a9b91d7a49 add drone services to package.xml 2023-05-01 16:11:24 +02:00
Sem van der Hoeven 64464d06a5 remove srv from px4controller 2023-05-01 16:07:49 +02:00
Sem van der Hoeven 0f0c84cf0c add separate package for service 2023-05-01 16:06:43 +02:00
ubuntu bb3942c301 add services package 2023-05-01 16:02:19 +02:00
Sem van der Hoeven c219359487 test 2023-05-01 15:58:15 +02:00
Sem van der Hoeven ea4cfb17ec test 2023-05-01 15:55:15 +02:00
Sem van der Hoeven 8efa23948d no placeholders? 2023-05-01 15:53:39 +02:00
Sem van der Hoeven a919c5b7f7 add test 2023-05-01 15:52:38 +02:00
Sem van der Hoeven 8be8a6d1f3 bull 2023-05-01 15:51:01 +02:00
Sem van der Hoeven a24c145968 remove attitude message codes 2023-05-01 15:48:06 +02:00
Sem van der Hoeven baad3abae2 use pointers 2023-05-01 15:42:29 +02:00
Sem van der Hoeven 0b98dfbf02 add processing of service request 2023-05-01 15:41:51 +02:00
Sem van der Hoeven 4846ee5052 add placeholders back 2023-05-01 15:31:02 +02:00
Sem van der Hoeven 22126929a7 remove placeholders 2023-05-01 15:30:30 +02:00
Sem van der Hoeven d74b7db6b3 add request header? 2023-05-01 15:29:57 +02:00
Sem van der Hoeven 8f7e496107 add placeholders 2023-05-01 15:28:58 +02:00
Sem van der Hoeven de2af0cf7c try according to tutorial 2023-05-01 15:27:15 +02:00
Sem van der Hoeven 9abee2b965 add shared ptr 2023-05-01 15:18:06 +02:00
Sem van der Hoeven f4819381a5 stupid 2023-05-01 15:16:45 +02:00
Sem van der Hoeven 1ff1218359 try something else 2023-05-01 14:50:41 +02:00
Sem van der Hoeven 1c995253bd oops 2023-05-01 14:48:08 +02:00
Sem van der Hoeven 8f807bdfa3 try setting callback with bind 2023-05-01 14:47:22 +02:00
Sem van der Hoeven b9b8c99f20 add server function 2023-05-01 14:46:06 +02:00
Sem van der Hoeven 6129216d80 add message code hpp file 2023-05-01 14:41:28 +02:00
Sem van der Hoeven 5996ac225a add include own package 2023-05-01 14:34:07 +02:00
Sem van der Hoeven e7582c5760 add srv include 2023-05-01 14:32:39 +02:00
Sem van der Hoeven db2b25e60d change int to int8 2023-05-01 14:29:11 +02:00
Sem van der Hoeven fb34e50b38 add service definition 2023-05-01 14:28:00 +02:00
ubuntu d82b1925a4 add srv file 2023-05-01 14:17:59 +02:00
Sem van der Hoeven 3e740de48e add circling 2023-05-01 14:07:09 +02:00
Sem van der Hoeven c7dd7a25a0 try changing yawspeed 2023-05-01 14:02:23 +02:00
Sem van der Hoeven 65cd11ca11 add changing yawspeed 2023-05-01 13:59:48 +02:00
ubuntu eeb67733d3 create drone_controls package 2023-05-01 13:49:31 +02:00
Sem van der Hoeven 568197a95a change to use d_speed 2023-05-01 12:47:31 +02:00
Sem van der Hoeven 500356f4e9 fix bug 2023-05-01 12:45:34 +02:00
Sem van der Hoeven 7b0520c920 use pointer method get 2023-05-01 12:43:41 +02:00
Sem van der Hoeven 3f2ffd6dc7 add hover after 20 s 2023-05-01 12:43:02 +02:00
Sem van der Hoeven 04cad041b6 change value 2023-05-01 12:39:12 +02:00
Sem van der Hoeven ac759ace13 change to not check for 30 2023-05-01 12:38:25 +02:00
Sem van der Hoeven a739fb51c3 change value 2023-05-01 12:36:38 +02:00
Sem van der Hoeven a9c63cc235 change value 2023-05-01 12:35:08 +02:00
Sem van der Hoeven e0c9c2601d add launch file to cmakelists 2023-05-01 11:38:16 +02:00
Sem van der Hoeven 6348e5371f add launch file 2023-05-01 11:30:06 +02:00
ubuntu 4eb876df0c add run script 2023-05-01 11:27:38 +02:00
Sem van der Hoeven 9c3dcb463d make dat boi schmoov 2023-05-01 11:23:25 +02:00
Sem van der Hoeven 048a1b4929 change values 2023-05-01 11:18:35 +02:00
Sem van der Hoeven 346e41f475 change values 2023-05-01 11:08:39 +02:00
Sem van der Hoeven 33d173d1e0 try to hover 2023-05-01 11:07:27 +02:00
Sem van der Hoeven 088af872f9 try negative down speed 2023-05-01 11:02:50 +02:00
Sem van der Hoeven 60033323d4 change speeds 2023-05-01 11:01:24 +02:00
Sem van der Hoeven 6b33ded940 add compensation for earth gravity pull 2023-05-01 10:56:43 +02:00
Sem van der Hoeven ae18d7834a try up velocity of 1 2023-05-01 10:55:01 +02:00
Sem van der Hoeven 4449c6cc1f change checking of ready to fly 2023-05-01 10:51:03 +02:00
Sem van der Hoeven 23a59a449c typo 2023-05-01 10:21:03 +02:00
Sem van der Hoeven 3fe7b60374 add try sending trajectory setpoints 2023-05-01 10:19:45 +02:00
Sem van der Hoeven 19d1987484 try adding hover? 2023-04-28 21:01:12 +02:00
Sem van der Hoeven c0d327165c change formatting numbers to f in strings 2023-04-28 20:59:38 +02:00
Sem van der Hoeven 799ef4237e try adding hover? 2023-04-28 20:57:35 +02:00
Sem van der Hoeven 0c543614a9 oops 2023-04-28 20:52:38 +02:00
Sem van der Hoeven c4e9e3bb10 remove heartbeat from px4 controller 2023-04-28 20:52:02 +02:00
Sem van der Hoeven 37b5f14f72 change throttle 2023-04-28 20:48:07 +02:00
Sem van der Hoeven 1515206e2e set throttle to negative 2023-04-28 20:46:41 +02:00
Sem van der Hoeven 52f237fcb5 add extra parameters 2023-04-28 20:45:08 +02:00
Sem van der Hoeven a037b7f00e try diff values 2023-04-28 20:40:28 +02:00
Sem van der Hoeven b775f8015c try diff values 2023-04-28 20:36:01 +02:00
Sem van der Hoeven 10c0b5ae5f increase thrust 2023-04-28 20:33:20 +02:00
Sem van der Hoeven 4b063ce9b2 try with increasing thrust 2023-04-28 18:36:23 +02:00
Sem van der Hoeven f767ee2583 try different values 2023-04-28 18:29:20 +02:00
Sem van der Hoeven 1224735954 waited longer before arming 2023-04-28 18:25:22 +02:00
Sem van der Hoeven a3b0b761e7 made px4controller also send heartbeat 2023-04-28 18:22:41 +02:00
Sem van der Hoeven 806317a04c oops v2 2023-04-28 18:07:42 +02:00
Sem van der Hoeven b03951faab oops 2023-04-28 18:07:04 +02:00
Sem van der Hoeven 5b935af894 change attitude value 2023-04-28 18:03:43 +02:00
Sem van der Hoeven 7545a8a2a8 add disarm 2023-04-28 18:03:14 +02:00
Sem van der Hoeven 9464dbf5ac try different values 2023-04-28 17:57:32 +02:00
Sem van der Hoeven c9f546cb0c try different values 2023-04-28 17:53:46 +02:00
Sem van der Hoeven f883d826ec change to 100% thrust 2023-04-28 17:50:15 +02:00
Sem van der Hoeven 5a7a54fc53 change 0.5 thrust to 0.8 2023-04-28 17:44:22 +02:00
Sem van der Hoeven 7a2f19d311 add comment 2023-04-28 17:37:07 +02:00
Sem van der Hoeven b8f572d86f fix 2023-04-28 17:31:16 +02:00
Sem van der Hoeven c8a61cac40 change name of quaternion array 2023-04-28 17:29:35 +02:00
Sem van der Hoeven 52132684d2 test move up 2023-04-28 17:25:26 +02:00
Sem van der Hoeven 8acd7f2c73 add print of quaternion 2023-04-28 16:50:28 +02:00
Sem van der Hoeven b4494a726d change heartbeat to attitude 2023-04-28 16:47:54 +02:00
Sem van der Hoeven c44dcb7f89 change ptr to std::array 2023-04-28 16:40:12 +02:00
Sem van der Hoeven 29931565e2 change ptr to std::array 2023-04-28 16:40:00 +02:00
Sem van der Hoeven abd5931461 add calculating quaternion 2023-04-28 15:53:44 +02:00
Sem van der Hoeven 7fa1cd5816 100% thrust 2023-04-28 15:19:04 +02:00
Sem van der Hoeven 1775cae443 remove timesync includes 2023-04-28 15:16:13 +02:00
Sem van der Hoeven d24f91512f change quaternion values 2023-04-28 15:12:08 +02:00
Sem van der Hoeven bd8cec8516 typo 2023-04-28 14:51:14 +02:00
Sem van der Hoeven 388963511a test with 0 values 2023-04-28 14:47:36 +02:00
Sem van der Hoeven e3466a1077 change float f to .0 2023-04-28 13:39:18 +02:00
Sem van der Hoeven 0107bb3c0b change vehicle attitude setpoint to trajectory setpoint for velocity 2023-04-28 12:46:05 +02:00
Sem van der Hoeven 6bdb10dd5c change vehicle attitude setpoint to trajectory setpoint for velocity 2023-04-28 12:45:27 +02:00
Sem van der Hoeven 5496e400cf it finally works 2023-04-25 15:45:14 +00:00
Sem van der Hoeven 4ed6dde80e typo v3 2023-04-25 16:58:10 +02:00
Sem van der Hoeven 78ac1963df typo v2 2023-04-25 16:55:55 +02:00
Sem van der Hoeven fd2ace29ce typo 2023-04-25 16:54:57 +02:00
Sem van der Hoeven 455c495685 add setting to offboard mode and arming 2023-04-25 16:53:40 +02:00
Sem van der Hoeven 4540a24d85 fix name 2023-04-25 16:46:28 +02:00
Sem van der Hoeven a12d1836fe add filling message with test values 2023-04-25 16:45:01 +02:00
Sem van der Hoeven 43f3838979 add vehicle attitude setpoint publisher 2023-04-25 16:39:15 +02:00
Sem van der Hoeven 5b6c097bd9 update CMakeLists.txt to be similar to object detection 2023-04-25 16:34:05 +02:00
Sem van der Hoeven b5daa4a77a add px4 controller cmakelists 2023-04-25 14:32:19 +00:00
Sem van der Hoeven 15e530067e remove send setpoints 2023-04-25 14:24:28 +00:00
Sem van der Hoeven 8b1790f763 change CMakeLists.txt of heartbeat to include packages for ros 2023-04-25 16:15:03 +02:00
Sem van der Hoeven 010559ea9b put px4_connection package in src folder 2023-04-25 13:56:48 +00:00
Sem van der Hoeven 9ace6a70b3 add heartbeat package 2023-04-25 13:52:47 +00:00
Sem van der Hoeven 5ea8d5674f finish sending offboard control and check if 5 seconds elapsed 2023-04-25 14:24:56 +02:00
Sem van der Hoeven f53385ae0a add sending offboardcontrolmode message 2023-04-25 14:08:42 +02:00
Sem van der Hoeven c748bc5da8 add timer and publisher 2023-04-25 11:58:21 +00:00
Sem van der Hoeven 5c4d47b590 add message includes for sending offboard control mode messages 2023-04-25 11:53:49 +00:00
Sem van der Hoeven 0d52a66d2a Merge branch 'main' into send_setpoints 2023-04-25 11:27:04 +00:00
Sem van der Hoeven 40facd933b move microxrcedds log to script_outputs 2023-04-25 11:15:32 +00:00
Sem van der Hoeven 59421316b4 add script log outputs 2023-04-25 11:15:09 +00:00
Sem van der Hoeven 078a4a1a1a tested microxrcedds 2023-04-25 11:13:18 +00:00
SemvdH 39ca39e983 Merge pull request #4 from SemvdH/heigth_sensor
merge Heigth sensor into main
2023-04-25 11:12:28 +02:00
Sem van der Hoeven 9af542d4ad everything built 2023-04-25 09:11:44 +00:00
Sem van der Hoeven 48b5016897 why 2023-04-24 15:41:11 +00:00
Sem van der Hoeven 09cda4e1d0 bruh 2023-04-24 17:20:42 +02:00
Sem van der Hoeven 8aa5e6fe35 add generators to cmake 2023-04-24 17:19:22 +02:00
Sem van der Hoeven 8fb86a5e2d add publishing of topic 2023-04-24 15:48:50 +02:00
Sem van der Hoeven ed542e2f21 update package.xml of height package 2023-04-24 15:41:57 +02:00
Sem van der Hoeven df18c9bba6 add height message definition 2023-04-24 15:38:16 +02:00
Sem van der Hoeven 1c1ea30dc0 created node to read basics of height sensor 2023-04-24 13:36:08 +00:00
Sem van der Hoeven b258131480 Revert "add node with basic code to read sensor"
This reverts commit 5f98cb2f10.
2023-04-24 13:18:42 +00:00
Sem van der Hoeven 5f98cb2f10 add node with basic code to read sensor 2023-04-24 15:12:34 +02:00
Sem van der Hoeven 8cbf27cd63 add dependencies for terabee api 2023-04-24 14:52:31 +02:00
Sem van der Hoeven 85390c0d4d add height sensor files 2023-04-24 12:47:15 +00:00
Sem van der Hoeven 6da45f1240 remove unnecessary folders 2023-04-24 12:49:44 +02:00
Sem van der Hoeven 9942e65bd3 merge main into this branch 2023-04-24 12:48:30 +02:00
SemvdH 0c944ce3b6 Merge pull request #3 from SemvdH/object_detection
Finished object detection nodes
2023-04-24 12:41:12 +02:00
Sem van der Hoeven 2103260f0f oops 2023-04-24 12:31:23 +02:00
Sem van der Hoeven 1fc71c7ca7 add parameter and launch for lidar reader 2023-04-24 12:29:53 +02:00
Sem van der Hoeven 8fd8662e0d add launch file 2023-04-24 12:21:43 +02:00
Sem van der Hoeven e8ecc7eac4 add publishing message 2023-04-24 12:10:34 +02:00
Sem van der Hoeven fd83eb616a fix typo in include 2023-04-24 12:05:10 +02:00
Sem van der Hoeven 3110abcbf0 add message definition include 2023-04-24 12:04:12 +02:00
Sem van der Hoeven 076bb6507b add message interface for multiflex readings 2023-04-24 12:00:48 +02:00
Sem van der Hoeven de9510c096 add example reading of multiflex data 2023-04-24 11:57:13 +02:00
Sem van der Hoeven 32d73ba229 add files for multiflex reader 2023-04-24 09:41:08 +00:00
Sem van der Hoeven 91354beb0b stuff 2023-04-24 09:18:37 +00:00
Sem van der Hoeven a1b778b74b fix typo 2023-04-20 16:00:09 +02:00
Sem van der Hoeven be267f2aff fix typo 2023-04-20 15:59:16 +02:00
Sem van der Hoeven 615d026eb6 fix typo 2023-04-20 15:58:01 +02:00
Sem van der Hoeven 263f1c154e comment 2023-04-20 15:56:18 +02:00
Sem van der Hoeven 68cb8effa9 add px4 includes 2023-04-20 15:54:47 +02:00
Sem van der Hoeven a444ce3193 add setpoints package 2023-04-20 13:49:43 +00:00
Sem van der Hoeven 091fe9a4ee add putting reading values in message 2023-04-20 13:21:54 +02:00
Sem van der Hoeven 988c546f15 add i to cout of distance data 2023-04-20 12:04:26 +02:00
Sem van der Hoeven 225c9ef7ae fix typo 2023-04-20 12:02:56 +02:00
Sem van der Hoeven 16192c6c8b add imu data to message 2023-04-20 11:50:24 +02:00
Sem van der Hoeven cedff67864 add todo 2023-04-19 17:00:06 +02:00
Sem van der Hoeven 682b18d396 add terabee log 2023-04-19 14:59:11 +00:00
Sem van der Hoeven 38a34a6de7 Merge branch 'object_detection' of github.com:SemvdH/5g_drone_ROS2 into object_detection 2023-04-19 14:56:52 +00:00
Sem van der Hoeven 1ac0bfead3 lil fix 2023-04-19 16:56:38 +02:00
Sem van der Hoeven 8712315b92 Merge branch 'object_detection' of github.com:SemvdH/5g_drone_ROS2 into object_detection 2023-04-19 14:55:31 +00:00
Sem van der Hoeven 7ae5295134 change to pointer 2023-04-19 16:55:17 +02:00
Sem van der Hoeven bec6025654 Merge branch 'object_detection' of github.com:SemvdH/5g_drone_ROS2 into object_detection 2023-04-19 14:52:45 +00:00
Sem van der Hoeven 4d4647f348 add example code from terabee 2023-04-19 16:52:29 +02:00
Sem van der Hoeven 98668938cc Merge branch 'object_detection' of github.com:SemvdH/5g_drone_ROS2 into object_detection 2023-04-19 14:44:08 +00:00
Sem van der Hoeven 99b34fa55e custom msg 2023-04-19 14:43:51 +00:00
Sem van der Hoeven f3e4468339 custom message bullshit doesnt fucking work 2023-04-19 16:19:20 +02:00
Sem van der Hoeven 645754e56f add include of message 2023-04-19 16:14:48 +02:00
Sem van der Hoeven 200f1f97ec add message definition 2023-04-19 16:10:27 +02:00
Sem van der Hoeven 1c3ab27707 add object detection package 2023-04-19 14:00:44 +00:00
Sem van der Hoeven 4e8e1c8177 change binary mode 2023-03-03 14:54:55 +01:00
Sem van der Hoeven 0f0324ab9d add modes and remove close of port 2023-03-03 14:52:43 +01:00
Sem van der Hoeven 126ff49a35 change string to char* 2023-03-03 14:47:11 +01:00
Sem van der Hoeven 345e796392 decrease timer delay 2023-03-03 14:45:26 +01:00
Sem van der Hoeven e5ddab280e add printing of T value 2023-03-03 14:45:06 +01:00
Sem van der Hoeven 9e5f2363f6 extra print 2023-03-03 14:26:09 +01:00
Sem van der Hoeven 4f530da21d change T to number 2023-03-03 14:22:08 +01:00
Sem van der Hoeven 1df349b478 add reading bytes when getting a T 2023-03-03 14:19:42 +01:00
Sem van der Hoeven 24fc0c2ca5 fix error 2023-03-03 14:04:14 +01:00
Sem van der Hoeven 31503b8b70 add check start of measurement test 2023-03-03 13:59:11 +01:00
Sem van der Hoeven a6fd08738c change test method 2023-03-03 12:55:22 +00:00
Sem van der Hoeven b88d8beb39 add test calling method while node spinning 2023-03-03 13:37:31 +01:00
Sem van der Hoeven 4df0d69b53 Merge branch 'heigth_sensor' of github.com:SemvdH/5g_drone_ROS2 into heigth_sensor 2023-03-03 13:29:09 +01:00
Sem van der Hoeven ed71dfb0e9 test 2023-03-03 13:28:41 +01:00
Sem van der Hoeven 353bf74930 change wait to 1 ms 2023-03-03 12:23:20 +00:00
Sem van der Hoeven 015d7d7596 reading single byte 2023-03-03 13:10:05 +01:00
Sem van der Hoeven f0f63b1817 serial port test if it can be opened 2023-03-03 12:58:55 +01:00
Sem van der Hoeven eaeb2dba5a add test print 2023-03-03 12:47:04 +01:00
Sem van der Hoeven ee2d5c4d54 add gitignore 2023-03-03 11:29:59 +01:00
Sem van der Hoeven 5ce3d43841 initial commit 2023-03-03 10:15:52 +00:00
71 changed files with 9899 additions and 6 deletions
+1
View File
@@ -1,3 +1,4 @@
.vscode/
build/ build/
install/ install/
log/ log/
+4 -1
View File
@@ -10,7 +10,10 @@
"/home/ubuntu/ros2_ws/src/beacon_positioning/include/**", "/home/ubuntu/ros2_ws/src/beacon_positioning/include/**",
"/usr/include/**", "/usr/include/**",
"/mnt/Homework/Avans/AFSTUDEERSTAGE/positioning_systems_api/rtls_driver/include/**", "/mnt/Homework/Avans/AFSTUDEERSTAGE/positioning_systems_api/rtls_driver/include/**",
"/mnt/Homework/Avans/AFSTUDEERSTAGE/positioning_systems_api/serial_communication/include/**" "/mnt/Homework/Avans/AFSTUDEERSTAGE/positioning_systems_api/serial_communication/include/**",
"/mnt/Homework/Avans/AFSTUDEERSTAGE/terabee_api/include/**",
"/home/ubuntu/ros2_ws/build/px4_msgs/rosidl_generator_cpp/px4_msgs/msg/**",
"/home/ubuntu/ros2_ws/src/px4_connection/include/**"
], ],
"name": "ROS", "name": "ROS",
"intelliSenseMode": "gcc-x64", "intelliSenseMode": "gcc-x64",
+60 -1
View File
@@ -1,7 +1,66 @@
{ {
"ros.distro": "humble", "ros.distro": "humble",
"files.associations": { "files.associations": {
"chrono": "cpp" "chrono": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"csignal": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"functional": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"memory": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"numeric": "cpp",
"optional": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"semaphore": "cpp",
"shared_mutex": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"thread": "cpp",
"type_traits": "cpp",
"tuple": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"variant": "cpp"
}, },
"python.autoComplete.extraPaths": [ "python.autoComplete.extraPaths": [
"/home/ubuntu/ros2_ws/install/px4_msgs/lib/python3.8/site-packages", "/home/ubuntu/ros2_ws/install/px4_msgs/lib/python3.8/site-packages",
View File
View File
+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
lidarserial=00000000001A
heightserial=369A378F3439
find_by_id(){
v=${1%:*}; p=${1#*:} # split vid:pid into 2 vars
v=${v#${v%%[!0]*}}; p=${p#${p%%[!0]*}} # strip leading zeros
grep -il "^PRODUCT=$v/$p" /sys/bus/usb/devices/*:*/uevent |
sed s,uevent,, |
xargs -r grep -r '^DEVNAME=' --include uevent
}
ids=$(find_by_id 0483:5740)
echo $ids
for device in $ids
do
id=$(echo $device | cut -d "=" -f 2)
serial=$(/bin/udevadm info --name=/dev/$id | grep SERIAL_SHORT | cut -d = -f 2)
echo "device "$id" has serial number "$serial
if [ $serial = $lidarserial ]
then
echo "LIDAR on port" $id
echo $id > /home/ubuntu/drone_conf/lidar.conf
elif [ $serial = $heightserial ]
then
echo "height sensor on port" $id
echo $id > /home/ubuntu/drone_conf/height.conf
else
echo "unknown serial number" $serial
fi
done
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
. /home/ubuntu/source_ros2.sh
SERIAL=$(cat /home/ubuntu/drone_conf/height.conf)
echo "serial port is "$SERIAL
echo ros2 run height height_reader --ros-args -p height_serial_port:=/dev/${SERIAL}
ros2 run height height_reader --ros-args -p height_serial_port:=/dev/${SERIAL} | tee /home/ubuntu/drone_log/height.log
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
. /home/ubuntu/source_ros2.sh
SERIAL=$(cat /home/ubuntu/drone_conf/lidar.conf)
echo "serial port is "$SERIAL
echo ros2 run object_detection lidar_reader --ros-args -p lidar_serial_port:=/dev/${SERIAL}
ros2 run object_detection lidar_reader --ros-args -p lidar_serial_port:=/dev/${SERIAL} | tee /home/ubuntu/drone_log/lidar.log
Executable
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
echo "updating git..."
./fgit.sh
echo "building package..."
colcon build --packages-select px4_connection
#echo "launching controller..."
#ros2 run px4_connection px4_controller
+1
View File
@@ -0,0 +1 @@
/bin/udevadm info --name=/dev/ttyACM0 | grep SERIAL_SHORT | cut -d = -f 2
+1051
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+12
View File
@@ -0,0 +1,12 @@
[Unit]
Description=Service to start the script that sets the serial ports for the USB sensors
[Service]
Type=simple
Restart=on-failure
User=ubuntu
ExecStart=/home/ubuntu/drone_scripts/find_id.sh
WorkingDirectory=/home/ubuntu
[Install]
WantedBy=multi-user.target
+14
View File
@@ -0,0 +1,14 @@
[Unit]
Description=Height sensor for drone running in ROS 2
After=drone_find_usb_devices.service
[Service]
Type=simple
Restart=on-failure
User=ubuntu
ExecStart=/home/ubuntu/drone_scripts/start_height_sensor.sh
Environment="HOME=root"
WorkingDirectory=/home/ubuntu
[Install]
WantedBy=multi-user.target
+14
View File
@@ -0,0 +1,14 @@
[Unit]
Description=Height sensor for drone running in ROS 2
After=drone_find_usb_devices.service
[Service]
Type=simple
Restart=on-failure
User=ubuntu
ExecStart=/home/ubuntu/drone_scripts/start_lidar.sh
Environment="HOME=root"
WorkingDirectory=/home/ubuntu
[Install]
WantedBy=multi-user.target
+3 -1
View File
@@ -31,7 +31,9 @@ rosidl_generate_interfaces(${PROJECT_NAME}
) )
add_executable(tracker_position src/tracker_position.cpp) add_executable(tracker_position src/tracker_position.cpp)
ament_target_dependencies(tracker_position rclcpp std_msgs beacon_positioning) ament_target_dependencies(tracker_position rclcpp std_msgs
beacon_positioning
)
target_link_libraries(tracker_position target_link_libraries(tracker_position
positioning_systems_api::serial_communication positioning_systems_api::serial_communication
@@ -149,7 +149,7 @@ int main(int argc, char **argv)
if (tracker_msg.is_valid_position) if (tracker_msg.is_valid_position)
{ {
RCLCPP_INFO(node->get_logger(), "x = %f, y = %f, z = %f", tracker_msg.tracker_position_xyz.at(0), tracker_msg.tracker_position_xyz.at(1), tracker_msg.tracker_position_xyz.at(2)); RCLCPP_INFO(node->get_logger(), "x = %f, y = %f, z = %f", tracker_msg.tracker_position_xyz.at(0), tracker_msg.tracker_position_xyz.at(1), tracker_msg.tracker_position_xyz.at(2));
for (int i = 0; i < tracker_msg.anchors_data.size(); i++) for (size_t i = 0; i < tracker_msg.anchors_data.size(); i++)
{ {
RCLCPP_INFO(node->get_logger(), "anchor number= %d, distance = %d, x = %d, y = %d, z = %d", tracker_msg.anchors_data[i].number, tracker_msg.anchors_data[i].distance, tracker_msg.anchors_data[i].pos_x, tracker_msg.anchors_data[i].pos_y, tracker_msg.anchors_data[i].pos_z); RCLCPP_INFO(node->get_logger(), "anchor number= %d, distance = %d, x = %d, y = %d, z = %d", tracker_msg.anchors_data[i].number, tracker_msg.anchors_data[i].distance, tracker_msg.anchors_data[i].pos_x, tracker_msg.anchors_data[i].pos_y, tracker_msg.anchors_data[i].pos_z);
} }
@@ -160,7 +160,7 @@ int main(int argc, char **argv)
message.y_pos = tracker_msg.tracker_position_xyz.at(1); message.y_pos = tracker_msg.tracker_position_xyz.at(1);
message.z_pos = tracker_msg.tracker_position_xyz.at(2); message.z_pos = tracker_msg.tracker_position_xyz.at(2);
message.anchor_distances = {0, 0, 0, 0}; message.anchor_distances = {0, 0, 0, 0};
for (int i = 0; i < tracker_msg.anchors_data.size(); i++) for (size_t i = 0; i < tracker_msg.anchors_data.size(); i++)
{ {
message.anchor_distances[i] = tracker_msg.anchors_data[i].distance; message.anchor_distances[i] = tracker_msg.anchors_data[i].distance;
} }
View File
+50
View File
@@ -0,0 +1,50 @@
import rclpy
from rclpy.node import Node
from drone_services.srv import TakePicture
import os
from datetime import datetime
# import cv2
RES_4K_H = 3496
RES_4K_W = 4656
class CameraController(Node):
def __init__(self):
super().__init__('camera_controller')
self.get_logger().info("Camera controller started. Waiting for service call...")
self.srv = self.create_service(
TakePicture, 'drone/picture', self.take_picture_callback)
def take_picture_callback(self, request, response):
if (request.input_name == "default"):
self.get_logger().info("Taking picture with default filename")
now = datetime.now().strftime("droneimage_%Y-%m-%d_%H-%M-%S")
imagename = "/home/ubuntu/drone_img/" + now + ".jpg"
response.filename = imagename
else:
response.filename = request.input_name
os.system('fswebcam -r ' + RES_4K_W + 'x' + RES_4K_H + ' ' + response.filename)
self.get_logger().info("Picture saved as " + response.filename)
return response
def main(args=None):
rclpy.init(args=args)
test_controller = CameraController()
rclpy.spin(test_controller)
# Destroy the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
test_controller.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>camera</name>
<version>0.0.0</version>
<description>Package for controlling the camera of the drone</description>
<maintainer email="semmer99@gmail.com">ubuntu</maintainer>
<license>Apache License 2.0</license>
<exec_depend>rclpy</exec_depend>
<exec_depend>drone_services</exec_depend>
<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>
View File
+4
View File
@@ -0,0 +1,4 @@
[develop]
script-dir=$base/lib/camera
[install]
install-scripts=$base/lib/camera
+26
View File
@@ -0,0 +1,26 @@
from setuptools import setup
package_name = 'camera'
setup(
name=package_name,
version='0.0.0',
packages=[package_name],
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='ubuntu',
maintainer_email='semmer99@gmail.com',
description='Package for controlling the camera of the drone',
license='Apache License 2.0',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'camera_controller = camera.camera_controller:main'
],
},
)
+23
View File
@@ -0,0 +1,23 @@
# Copyright 2015 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ament_copyright.main import main
import pytest
@pytest.mark.copyright
@pytest.mark.linter
def test_copyright():
rc = main(argv=['.', 'test'])
assert rc == 0, 'Found errors'
+25
View File
@@ -0,0 +1,25 @@
# Copyright 2017 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ament_flake8.main import main_with_errors
import pytest
@pytest.mark.flake8
@pytest.mark.linter
def test_flake8():
rc, errors = main_with_errors(argv=[])
assert rc == 0, \
'Found %d code style errors / warnings:\n' % len(errors) + \
'\n'.join(errors)
+23
View File
@@ -0,0 +1,23 @@
# Copyright 2015 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ament_pep257.main import main
import pytest
@pytest.mark.linter
@pytest.mark.pep257
def test_pep257():
rc = main(argv=['.', 'test'])
assert rc == 0, 'Found code style errors / warnings'
+33
View File
@@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.5)
project(drone_controls)
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>drone_controls</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="ubuntu@todo.todo">ubuntu</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
+45
View File
@@ -0,0 +1,45 @@
cmake_minimum_required(VERSION 3.5)
project(drone_services)
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"srv/SetAttitude.srv"
"srv/SetTrajectory.srv"
"srv/SetVelocity.srv"
"srv/TakePicture.srv"
"srv/SetVehicleControl.srv"
"srv/ArmDrone.srv"
"srv/DisarmDrone.srv"
"msg/DroneControlMode.msg"
)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
@@ -0,0 +1,5 @@
# control mode of the drone
# 1: Attitude
# 2: Velocity
# 3: Position
int8 control_mode
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>drone_services</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="ubuntu@todo.todo">ubuntu</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
+2
View File
@@ -0,0 +1,2 @@
---
bool success
+2
View File
@@ -0,0 +1,2 @@
---
bool success
+11
View File
@@ -0,0 +1,11 @@
#service to set attitude setpoints for manual attitude control
#all angles are in degrees
float32 yaw
float32 pitch
float32 roll
#thrust between -1 and 1
float32 thrust
---
bool success
+10
View File
@@ -0,0 +1,10 @@
# control mode velocity or position, refer to drone_services/msg/DroneControlMode.msg
int8 control_mode
# x, y, z values
#float32[3] values
float32 x
float32 y
float32 z
float32 yaw
---
bool success
@@ -0,0 +1,16 @@
# service to set control mode for heartbeat messages
# bitmask for control:
# bit 0: actuator
# bit 1: body rate
# bit 2: attitude
# bit 3: acceleration
# bit 4: velocity
# bit 5: position
# used control modes:
# 4: attitude and thrust
# 16: velocity
# 32: position
int32 control # control bitmask
---
bool success # if operation succeeded
+9
View File
@@ -0,0 +1,9 @@
#all speeds are in meters/second
float32 x_speed
float32 y_speed
float32 z_speed
#angle is in degrees
float32 angle
---
bool success
+3
View File
@@ -0,0 +1,3 @@
wstring input_name "default" # name of the input file
---
wstring filename # output file name
+58
View File
@@ -0,0 +1,58 @@
cmake_minimum_required(VERSION 3.5)
project(height)
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(TerabeeApi REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(height REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/HeightData.msg"
)
add_executable(height_reader src/height_reader.cpp)
target_include_directories(height_reader PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_link_libraries(height_reader ${TerabeeApi_LIBRARIES})
target_include_directories(height_reader PUBLIC ${TerabeeApi_INCLUDE_DIRS})
ament_target_dependencies(
height_reader
rclcpp
TerabeeApi
height
)
install(TARGETS height_reader
DESTINATION lib/${PROJECT_NAME})
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
+2
View File
@@ -0,0 +1,2 @@
float32[4] heights
float32 min_height
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>height</name>
<version>0.0.0</version>
<description>package to read Terabee node</description>
<maintainer email="semmer99@gmail.com">ubuntu</maintainer>
<license>Apache License 2.0</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
<depend>rclcpp</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<build_depend>TerabeeApi</build_depend>
<exec_depend>TerabeeApi</exec_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
+101
View File
@@ -0,0 +1,101 @@
/**
* @file height_reader.cpp
* @author Sem van der Hoeven (sem.hoeven@gmail.com)
* @brief Uses the Terabee API to read the Terabee Evo Mini
* height sensor data and publishes it on a /drone/height topic
*/
#include <chrono>
#include "rclcpp/rclcpp.hpp"
#include "height/msg/height_data.hpp"
#include <terabee/ITerarangerFactory.hpp>
#include <terabee/ITerarangerEvoMini.hpp>
#include <terabee/DistanceData.hpp>
using namespace std::chrono_literals;
using terabee::DistanceData;
using terabee::ITerarangerEvoMini;
class HeightReader : public rclcpp::Node
{
public:
HeightReader() : rclcpp::Node("height_reader")
{
rcl_interfaces::msg::ParameterDescriptor descriptor = rcl_interfaces::msg::ParameterDescriptor{};
descriptor.description = "serial port for the USB port of the height sensor";
this->declare_parameter("height_serial_port", "/dev/ttyACM0", descriptor);
factory = terabee::ITerarangerFactory::getFactory();
evo_mini = factory->createTerarangerEvoMini(this->get_parameter("height_serial_port").as_string());
if (!evo_mini)
{
RCLCPP_ERROR(this->get_logger(), "Failed to create Evo Mini!");
return;
}
evo_mini->setPixelMode(ITerarangerEvoMini::Px4Mode);
if (!evo_mini->initialize())
{
RCLCPP_ERROR(this->get_logger(), "Failed to initialize evo mini!");
return;
}
RCLCPP_INFO(this->get_logger(), "Succesfully initialized Evo mini!");
timer_ = this->create_wall_timer(500ms, std::bind(&HeightReader::read_height, this));
publisher_ = this->create_publisher<height::msg::HeightData>("drone/height", 10);
}
private:
/**
* @brief reads the height value from the Terabee Evo Mini sensor and publishes a
*
*/
void read_height()
{
auto msg = height::msg::HeightData();
// high initial minimal value
float min = 255;
terabee::DistanceData distance_data = evo_mini->getDistance();
// add readings and calculate mimimum value
for (size_t i = 0; i < distance_data.size(); i++)
{
msg.heights[i] = distance_data.distance[i];
if (distance_data.distance[i] < min && distance_data.distance[i] >= 0)
{
min = distance_data.distance[i];
}
}
// add minimum value and publish message
msg.min_height = min;
publisher_->publish(msg);
RCLCPP_INFO(this->get_logger(), "publishing message with min distance %f", msg.min_height);
}
// timer for publishing height readings
rclcpp::TimerBase::SharedPtr timer_;
// publisher for height readings
rclcpp::Publisher<height::msg::HeightData>::SharedPtr publisher_;
// factory for height sensor
std::unique_ptr<terabee::ITerarangerFactory> factory;
// height sensor object pointer
std::unique_ptr<terabee::ITerarangerEvoMini> evo_mini;
};
int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<HeightReader>());
rclcpp::shutdown();
return 0;
}
+71
View File
@@ -0,0 +1,71 @@
cmake_minimum_required(VERSION 3.5)
project(object_detection)
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
find_package(rclcpp REQUIRED)
find_package(TerabeeApi REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(object_detection REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/LidarReading.msg"
"msg/MultiflexReading.msg"
)
add_executable(lidar_reader src/lidar_reader.cpp)
ament_target_dependencies(lidar_reader rclcpp
object_detection
)
target_link_libraries(lidar_reader ${TerabeeApi_LIBRARIES})
target_include_directories(lidar_reader PUBLIC ${TerabeeApi_INCLUDE_DIRS})
add_executable(multiflex_reader src/multiflex_reader.cpp)
ament_target_dependencies(multiflex_reader rclcpp
object_detection
)
target_link_libraries(multiflex_reader ${TerabeeApi_LIBRARIES})
target_include_directories(multiflex_reader PUBLIC ${TerabeeApi_INCLUDE_DIRS})
install(TARGETS
lidar_reader
multiflex_reader
DESTINATION lib/${PROJECT_NAME}
)
install(
DIRECTORY launch
DESTINATION share/${PROJECT_NAME}
)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
@@ -0,0 +1,23 @@
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package="object_detection",
executable="multiflex_reader",
name="multiflex_reader",
parameters=[
{"multiflex_serial_port": "/dev/ttyACM0"}
]
),
Node(
package="object_detection",
executable="lidar_reader",
name="lidar_reader",
parameters=[
{"lidar_serial_port": "/dev/ttyUSB0"} # TODO test
]
)
])
@@ -0,0 +1,15 @@
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package="object_detection",
executable="multiflex_reader",
name="multiflex_reader",
parameters=[
{"multiflex_serial_port": "/dev/ttyACM0"}
]
)
])
@@ -0,0 +1,6 @@
float32 sensor_1
float32 sensor_2
float32 sensor_3
float32 sensor_4
float32[] imu_data
@@ -0,0 +1 @@
float32[6] distance_data
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>object_detection</name>
<version>0.0.0</version>
<description>Package to read the TeraBee lidar and multiflex sensors</description>
<maintainer email="semmer99@gmail.com">sem</maintainer>
<license>Apache License 2.0</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<build_depend>rclcpp</build_depend>
<build_depend>TerabeeApi</build_depend>
<exec_depend>TerabeeApi</exec_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
+94
View File
@@ -0,0 +1,94 @@
#include <chrono>
#include "rclcpp/rclcpp.hpp"
#include "object_detection/msg/lidar_reading.hpp"
#include <terabee/ITerarangerFactory.hpp>
#include <terabee/ITerarangerTowerEvo.hpp>
#include <terabee/TowerDistanceData.hpp>
#include <terabee/ImuData.hpp>
using terabee::ImuData;
using terabee::ITerarangerTowerEvo;
using terabee::TowerDistanceData;
using namespace std::chrono_literals;
class LidarReader : public rclcpp::Node
{
public:
LidarReader()
: Node("lidar_reader")
{
// get serial port of sensor through parameter
rcl_interfaces::msg::ParameterDescriptor descriptor = rcl_interfaces::msg::ParameterDescriptor{};
descriptor.description = "serial port for the USB port of the LIDAR";
this->declare_parameter("lidar_serial_port", "/dev/ttyACM0", descriptor);
// create publisher and bind timer to publish function
publisher_ = this->create_publisher<object_detection::msg::LidarReading>("drone/object_detection", 10);
timer_ = this->create_wall_timer(500ms, std::bind(&LidarReader::read_lidar_data, this));
factory = terabee::ITerarangerFactory::getFactory();
tower = factory->createTerarangerTowerEvo(this->get_parameter("lidar_serial_port").as_string());
if (!tower) // check if the object could be created
{
RCLCPP_ERROR(this->get_logger(), "Failed to create TerarangerTowerEvo");
return;
}
// set lidar to measure including IMU
tower->setImuMode(ITerarangerTowerEvo::QuaternionLinearAcc);
if (!tower->initialize()) // check if communication with the sensor works
{
RCLCPP_ERROR(this->get_logger(), "Failed to initialize TerarangerTowerEvo");
return;
}
}
private:
// publisher for lidar data
rclcpp::Publisher<object_detection::msg::LidarReading>::SharedPtr publisher_;
// timer for publishing readings
rclcpp::TimerBase::SharedPtr timer_;
// terabee tower evo variables
std::unique_ptr<terabee::ITerarangerTowerEvo> tower;
std::unique_ptr<terabee::ITerarangerFactory> factory;
/**
* @brief Reads the data from the LIDAR distance modules and the IMU, and publishes it onto the drone/object_detection topic
*
*/
void read_lidar_data()
{
auto msg = object_detection::msg::LidarReading();
// read distance data from all sensors
msg.sensor_1 = tower->getDistance().distance.at(0);
msg.sensor_2 = tower->getDistance().distance.at(2);
msg.sensor_3 = tower->getDistance().distance.at(4);
msg.sensor_4 = tower->getDistance().distance.at(6);
// read data from built-in IMU
ImuData imu_data = tower->getImuData();
for (size_t i = 0; i < imu_data.data.size(); i++)
{
msg.imu_data.push_back(imu_data.data[i]);
}
// publish message
publisher_->publish(msg);
RCLCPP_INFO(this->get_logger(), "Publishing message");
}
};
int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<LidarReader>());
rclcpp::shutdown();
return 0;
}
@@ -0,0 +1,92 @@
#include <chrono>
#include "rclcpp/rclcpp.hpp"
#include "object_detection/msg/multiflex_reading.hpp"
#include <terabee/ITerarangerFactory.hpp>
#include <terabee/ITerarangerMultiflex.hpp>
#include <terabee/DistanceData.hpp>
// #include <iostream>
using terabee::DistanceData;
using namespace std::chrono_literals;
class MultiflexReader : public rclcpp::Node
{
public:
MultiflexReader()
: Node("multiflex_reader")
{
// get serial port of sensor through parameter
rcl_interfaces::msg::ParameterDescriptor serial_port_descriptor = rcl_interfaces::msg::ParameterDescriptor{};
serial_port_descriptor.description = "Serial port of the USB port that the multiflex PCB is connected to.";
this->declare_parameter("multiflex_serial_port", "/dev/ttyACM0", serial_port_descriptor);
// create the sensor object
factory = terabee::ITerarangerFactory::getFactory();
multiflex = factory->createTerarangerMultiflex(this->get_parameter("multiflex_serial_port").as_string());
if (!multiflex) // check if the object can be created
{
RCLCPP_ERROR(this->get_logger(), "Failed to create multiflex");
return;
}
if (!multiflex->initialize()) // check if communication with the sensor works
{
RCLCPP_ERROR(this->get_logger(), "Failed to initialize multiflex");
return;
}
if (!multiflex->configureNumberOfSensors(0x7)) // check if all 6 distance sensors work
{
RCLCPP_ERROR(this->get_logger(), "Failed to set the number of sensors to 3!");
return;
}
RCLCPP_INFO(this->get_logger(), "Multiflex initialized");
publisher_ = this->create_publisher<object_detection::msg::MultiflexReading>("drone/object_detection", 10);
timer_ = this->create_wall_timer(500ms, std::bind(&MultiflexReader::read_multiflex_data, this));
}
private:
// factory and object for multiflex sensor
std::unique_ptr<terabee::ITerarangerFactory> factory;
std::unique_ptr<terabee::ITerarangerMultiflex> multiflex;
// timer and publisher for publishing message onto topic
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<object_detection::msg::MultiflexReading>::SharedPtr publisher_;
/**
* @brief Reads distance data from the sensor and publishes it onto the drone/object_detection topic
*
*/
void read_multiflex_data()
{
// get distance reading
terabee::DistanceData data = multiflex->getDistance();
// populate message with readings
auto msg = object_detection::msg::MultiflexReading();
for (size_t i = 0; i < data.size(); i++)
{
RCLCPP_INFO(this->get_logger(), "distance %f", data.distance[i]);
// msg.distance_data[i] = data.distance[i];
}
// publish message
publisher_->publish(msg);
}
};
int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MultiflexReader>());
rclcpp::shutdown();
return 0;
}
+74
View File
@@ -0,0 +1,74 @@
cmake_minimum_required(VERSION 3.5)
project(px4_connection)
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(px4_ros_com REQUIRED)
find_package(px4_msgs REQUIRED)
find_package(drone_services REQUIRED)
find_package(std_srvs REQUIRED)
include_directories(include)
add_executable(heartbeat src/heartbeat.cpp)
ament_target_dependencies(
heartbeat
rclcpp
px4_ros_com
px4_msgs
drone_services
)
add_executable(px4_controller src/px4_controller.cpp)
ament_target_dependencies(
px4_controller
rclcpp
px4_ros_com
px4_msgs
drone_services
std_srvs
)
target_include_directories(heartbeat PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_include_directories(px4_controller PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
install(TARGETS heartbeat px4_controller
DESTINATION lib/${PROJECT_NAME})
install(
DIRECTORY launch
DESTINATION share/${PROJECT_NAME}
)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
# set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
# set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
@@ -0,0 +1,8 @@
#ifndef ATTITUDE_MSG_CODE_HPP
#define ATTITUDE_MSG_CODE_HPP
#define ATTITUDE_STATUS_OK 0
#define ATTITUDE_STATUS_ERROR 1
#endif
@@ -0,0 +1,20 @@
#ifndef DRONE_CONTROL_MODES_H
#define DRONE_CONTROL_MODES_H
#define CONTROL_MODE_ATTITUDE 1
#define CONTROL_MODE_VELOCITY 2
#define CONTROL_MODE_POSITION 3
#define CONTROL_MODE_MIN CONTROL_MODE_ATTITUDE
#define CONTROL_MODE_MAX CONTROL_MODE_POSITION
#define CONTROL_ACTUATOR_POS 0
#define CONTROL_BODY_RATE_POS 1
#define CONTROL_ATTITUDE_POS 2
#define CONTROL_ACCELERATION_POS 3
#define CONTROL_VELOCITY_POS 4
#define CONTROL_POSITION_POS 5
#endif
@@ -0,0 +1,15 @@
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package="px4_connection",
executable="heartbeat"
),
Node(
package="px4_connection",
executable="px4_controller"
)
])
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>px4_connection</name>
<version>0.0.0</version>
<description>Package to communicate with PX4 through the XRCE-DDS bridge</description>
<maintainer email="semmer99@gmail.com">ubuntu</maintainer>
<license>Apache License 2.0</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
<depend>px4_ros_com</depend>
<depend>px4_msgs</depend>
<depend>drone_services</depend>
<depend>std_srvs</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
+138
View File
@@ -0,0 +1,138 @@
/**
* @file heartbeat.cpp
* @author Sem van der Hoeven (sem.hoeven@gmail.com)
* @brief Heartbeat node that keeps the connection between the flight computer
* and PX4 flight controller alive by sending OffboardControl messages
*/
#include <chrono>
#include "rclcpp/rclcpp.hpp"
#include <px4_msgs/msg/offboard_control_mode.hpp>
#include <drone_services/srv/set_vehicle_control.hpp>
#include <drone_services/msg/drone_control_mode.hpp>
#include "drone_control_modes.h"
using namespace std::chrono_literals;
class HeartBeat : public rclcpp::Node
{
public:
HeartBeat() : Node("heartbeat")
{
vehicle_control_mode_service_ = this->create_service<drone_services::srv::SetVehicleControl>("/drone/set_vehicle_control", std::bind(&HeartBeat::handle_vehicle_control_change, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
RCLCPP_INFO(this->get_logger(), "initialized service /drone/set_vehicle_control");
// create a publisher on the drone control mode topic
drone_control_mode_publisher_ = this->create_publisher<drone_services::msg::DroneControlMode>("/drone/control_mode", 10);
// create a publisher on the offboard control mode topic
offboard_control_mode_publisher_ = this->create_publisher<px4_msgs::msg::OffboardControlMode>("/fmu/in/offboard_control_mode", 10);
// create timer to send heartbeat messages (offboard control) every 100ms
timer_ = this->create_wall_timer(100ms, std::bind(&HeartBeat::send_heartbeat, this));
start_time = this->get_clock()->now().seconds();
RCLCPP_INFO(this->get_logger(), "done initializing at %d seconds. Sending heartbeat...", start_time);
}
private:
// publisher for offboard control mode messages
rclcpp::Publisher<px4_msgs::msg::OffboardControlMode>::SharedPtr offboard_control_mode_publisher_;
// publisher for the control mode of the drone
rclcpp::Publisher<drone_services::msg::DroneControlMode>::SharedPtr drone_control_mode_publisher_;
// timer for sending the heartbeat
rclcpp::TimerBase::SharedPtr timer_;
// service to change vehicle_mode
rclcpp::Service<drone_services::srv::SetVehicleControl>::SharedPtr vehicle_control_mode_service_;
// start time of node in seconds
double start_time;
// which level of control is needed, only attitude control by default
int control_mode = 1 << CONTROL_ATTITUDE_POS;
/**
* @brief Publish offboard control mode messages as a heartbeat.
* Only the attitude is enabled, because that is how the drone will be controlled.
*
*/
void send_heartbeat()
{
auto msg = px4_msgs::msg::OffboardControlMode();
msg.position = (this->control_mode >> CONTROL_POSITION_POS) & 1 ? true : false;
msg.velocity = (this->control_mode >> CONTROL_VELOCITY_POS) & 1 ? true : false;
msg.acceleration = (this->control_mode >> CONTROL_ACCELERATION_POS) & 1 ? true : false;
msg.attitude = (this->control_mode >> CONTROL_ATTITUDE_POS) & 1 ? true : false;
msg.body_rate = (this->control_mode >> CONTROL_BODY_RATE_POS) & 1 ? true : false;
msg.actuator = (this->control_mode >> CONTROL_ACTUATOR_POS) & 1 ? true : false;
/*
msg.position = false;
msg.velocity = false;
msg.acceleration = false;
msg.attitude = true;
msg.body_rate = false;
msg.actuator = false;
*/
// get timestamp and publish message
msg.timestamp = this->get_clock()->now().nanoseconds() / 1000;
offboard_control_mode_publisher_->publish(msg);
}
/**
* @brief Publish the current control mode of the drone onto the 'drone/control_mode' topic
*
*/
void publish_new_control_mode()
{
auto msg = drone_services::msg::DroneControlMode();
if (this->control_mode & (1 << CONTROL_ATTITUDE_POS))
{
msg.control_mode = CONTROL_MODE_ATTITUDE;
RCLCPP_INFO(this->get_logger(), "set control mode to attitude");
}
else if (this->control_mode & (1 << CONTROL_VELOCITY_POS))
{
msg.control_mode = CONTROL_MODE_VELOCITY;
RCLCPP_INFO(this->get_logger(), "set control mode to velocity");
}
else if (this->control_mode & (1 << CONTROL_POSITION_POS))
{
msg.control_mode = CONTROL_MODE_POSITION;
RCLCPP_INFO(this->get_logger(), "set control mode to position");
}
RCLCPP_INFO(this->get_logger(), "publishing new control mode %d", msg.control_mode);
drone_control_mode_publisher_->publish(msg);
}
/**
* @brief Handle a request to change the vehicle control mode
*
* @param request_header the header of the service request
* @param request the request that was sent to the service
* @param response the reponse that the service sends back to the client.
*/
void handle_vehicle_control_change(
const std::shared_ptr<rmw_request_id_t> request_header,
const std::shared_ptr<drone_services::srv::SetVehicleControl::Request> request,
const std::shared_ptr<drone_services::srv::SetVehicleControl::Response> response)
{
if (request->control < 0 || request->control > (1 << CONTROL_POSITION_POS))
{
response->success = false;
}
else
{
this->control_mode = request->control;
RCLCPP_INFO(this->get_logger(), "set control mode to %d", this->control_mode);
publish_new_control_mode();
response->success = true;
}
}
};
int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<HeartBeat>());
rclcpp::shutdown();
return 0;
}
+516
View File
@@ -0,0 +1,516 @@
/**
* @file px4_controller.cpp
* @author Sem van der Hoeven (sem.hoeven@gmail.com)
* @brief Controller node to contol the PX4 using attitude or trajectory setpoints.
* It subscribes to the /drone/set_attitude topic to receive control commands
*/
#include <chrono>
#include <math.h>
#include "rclcpp/rclcpp.hpp"
#include <px4_msgs/msg/vehicle_attitude_setpoint.hpp>
#include <px4_msgs/msg/trajectory_setpoint.hpp>
#include <px4_msgs/msg/vehicle_command.hpp>
#include <px4_msgs/msg/vehicle_control_mode.hpp>
#include <px4_msgs/msg/vehicle_attitude.hpp>
#include <drone_services/srv/set_attitude.hpp>
#include <drone_services/srv/set_trajectory.hpp>
#include <drone_services/srv/arm_drone.hpp>
#include <drone_services/srv/disarm_drone.hpp>
#include <drone_services/msg/drone_control_mode.hpp>
#include <std_srvs/srv/empty.hpp>
#include "drone_control_modes.h"
#define DEFAULT_YAW_SPEED 0.6 // default turning speed in radians per second
#define D_SPEED(x) -x - 9.81 // a speed up of x m/s has to be ajusted for the earths gravity
using namespace std::chrono_literals;
class PX4Controller : public rclcpp::Node
{
public:
PX4Controller() : Node("px4_controller")
{
rmw_qos_profile_t qos_profile = rmw_qos_profile_sensor_data;
auto qos = rclcpp::QoS(rclcpp::QoSInitialization(qos_profile.history, 5), qos_profile);
// create a publisher on the vehicle attitude setpoint topic
vehicle_setpoint_publisher_ = this->create_publisher<px4_msgs::msg::VehicleAttitudeSetpoint>("/fmu/in/vehicle_attitude_setpoint", 10);
vehicle_command_publisher_ = this->create_publisher<px4_msgs::msg::VehicleCommand>("/fmu/in/vehicle_command", 10);
trajectory_setpoint_publisher = this->create_publisher<px4_msgs::msg::TrajectorySetpoint>("/fmu/in/trajectory_setpoint", 10);
// offboard_control_mode_publisher_ = this->create_publisher<px4_msgs::msg::OffboardControlMode>("/fmu/in/offboard_control_mode", 10);
vehicle_attitude_subscription_ = this->create_subscription<px4_msgs::msg::VehicleAttitude>("/fmu/out/vehicle_attitude", qos, std::bind(&PX4Controller::on_attitude_receive, this, std::placeholders::_1));
control_mode_subscription_ = this->create_subscription<drone_services::msg::DroneControlMode>("/drone/control_mode", qos, std::bind(&PX4Controller::on_control_mode_receive, this, std::placeholders::_1));
set_attitude_service_ = this->create_service<drone_services::srv::SetAttitude>("/drone/set_attitude", std::bind(&PX4Controller::handle_attitude_setpoint, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
set_trajectory_service_ = this->create_service<drone_services::srv::SetTrajectory>("/drone/set_trajectory", std::bind(&PX4Controller::handle_trajectory_setpoint, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
disarm_service_ = this->create_service<drone_services::srv::DisarmDrone>("/drone/disarm", std::bind(&PX4Controller::handle_disarm_request, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
arm_service_ = this->create_service<drone_services::srv::ArmDrone>("/drone/arm", std::bind(&PX4Controller::handle_arm_request, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
// create timer to send vehicle attitude setpoints every second
timer_ = this->create_wall_timer(100ms, std::bind(&PX4Controller::send_setpoint, this));
start_time_ = this->get_clock()->now().seconds();
RCLCPP_INFO(this->get_logger(), "finished initializing at %f seconds.", start_time_);
}
private:
rclcpp::Publisher<px4_msgs::msg::VehicleAttitudeSetpoint>::SharedPtr vehicle_setpoint_publisher_;
rclcpp::Publisher<px4_msgs::msg::TrajectorySetpoint>::SharedPtr trajectory_setpoint_publisher;
rclcpp::Publisher<px4_msgs::msg::VehicleCommand>::SharedPtr vehicle_command_publisher_;
rclcpp::Subscription<px4_msgs::msg::VehicleAttitude>::SharedPtr vehicle_attitude_subscription_;
rclcpp::Subscription<drone_services::msg::DroneControlMode>::SharedPtr control_mode_subscription_;
rclcpp::Service<drone_services::srv::SetAttitude>::SharedPtr set_attitude_service_;
rclcpp::Service<drone_services::srv::SetTrajectory>::SharedPtr set_trajectory_service_;
rclcpp::Service<drone_services::srv::DisarmDrone>::SharedPtr disarm_service_;
rclcpp::Service<drone_services::srv::ArmDrone>::SharedPtr arm_service_;
// rclcpp::Publisher<px4_msgs::msg::OffboardControlMode>::SharedPtr offboard_control_mode_publisher_;
rclcpp::TimerBase::SharedPtr timer_;
double start_time_;
bool has_sent_status = false;
bool user_in_control = false; // if user has taken over control
bool armed = false;
bool has_swithed = false;
int setpoint_count = 0;
float thrust = 0.0;
bool ready_to_fly = false;
float cur_yaw = 0;
bool new_setpoint = false; // for printing new q_d when a new setpoint has been received
float last_setpoint[3] = {0, 0, 0};
float last_angle = 0; // angle in radians (-PI .. PI)
float last_thrust = 0; // default 10% thrust for when the drone gets armed
float velocity[3] = {0, 0, 0};
float position[3] = {0, 0, 0};
float base_q[4] = {0, 0, 0, 0};
int base_q_amount = 0;
bool trajectory_valid_x = false;
bool trajectory_valid_y = false;
bool trajectory_valid_z = false;
bool trajectory_valid_yaw = false;
char current_control_mode = CONTROL_MODE_ATTITUDE; // start with attitude control
// result quaternion
std::array<float, 4> q = {0, 0, 0, 0};
void handle_attitude_setpoint(
const std::shared_ptr<rmw_request_id_t> request_header,
const std::shared_ptr<drone_services::srv::SetAttitude::Request> request,
const std::shared_ptr<drone_services::srv::SetAttitude::Response> response)
{
if (armed)
{
if (request->yaw == 0 && request->pitch == 0 && request->roll == 0 && request->thrust == 0)
{
last_setpoint[0] = degrees_to_radians(request->yaw);
last_setpoint[1] = degrees_to_radians(request->pitch);
last_setpoint[2] = degrees_to_radians(request->roll);
last_thrust = request->thrust;
RCLCPP_INFO(this->get_logger(), "STOPPING MOTORS");
}
else
{
last_setpoint[0] += degrees_to_radians(request->yaw);
last_setpoint[1] += degrees_to_radians(request->pitch);
last_setpoint[2] += degrees_to_radians(request->roll);
last_thrust += request->thrust;
if (last_thrust > 1)
last_thrust = 1;
else if (last_thrust < 0)
last_thrust = 0;
}
RCLCPP_INFO(this->get_logger(), "got values: yaw:%f pitch:%f roll:%f thrust:%f", request->yaw, request->pitch, request->roll, request->thrust);
RCLCPP_INFO(this->get_logger(), "New setpoint: yaw:%f pitch:%f roll:%f thrust:%f", last_setpoint[0], last_setpoint[1], last_setpoint[2], last_thrust);
response->success = true;
}
else
{
last_thrust = 0;
last_setpoint[0] = 0;
last_setpoint[1] = 0;
last_setpoint[2] = 0;
response->success = false;
}
}
void handle_trajectory_setpoint(
const std::shared_ptr<rmw_request_id_t> request_header,
const std::shared_ptr<drone_services::srv::SetTrajectory::Request> request,
const std::shared_ptr<drone_services::srv::SetTrajectory::Response> response)
{
if (!(request->control_mode == CONTROL_MODE_VELOCITY || request->control_mode == CONTROL_MODE_POSITION))
{
RCLCPP_INFO(this->get_logger(), "Got invalid trajectory control mode: %d", request->control_mode);
response->success = false;
}
else
{
RCLCPP_INFO(this->get_logger(), "Got new trajectory setpoint with control mode: %d", request->control_mode);
// trajectory_valid_x = request->x != NAN;
// trajectory_valid_y = request->y != NAN;
// trajectory_valid_z = request->z != NAN;
// trajectory_valid_yaw = request->yaw != NAN;
if (request->control_mode == CONTROL_MODE_VELOCITY)
{
RCLCPP_INFO(this->get_logger(), "Got new velocity setpoint. %f %f %f", request->x, request->y, request->z);
// if (trajectory_valid_x)
velocity[0] += request->x;
// if (trajectory_valid_y)
velocity[1] += request->y;
// if (trajectory_valid_z)
velocity[2] += request->z;
RCLCPP_INFO(this->get_logger(), "Set new velocity setpoint. %f %f %f", velocity[0], velocity[1], velocity[2]);
}
else if (request->control_mode == CONTROL_MODE_POSITION)
{
RCLCPP_INFO(this->get_logger(), "Got new position setpoint. %f %f %f", request->x, request->y, request->z);
// if (trajectory_valid_x)
position[0] = request->x;
// if (trajectory_valid_y)
position[1] = request->y;
// if (trajectory_valid_z)
position[2] = request->z;
RCLCPP_INFO(this->get_logger(), "Set new position setpoint: %f %f %f", position[0], position[1], position[2]);
}
if (trajectory_valid_yaw)
last_angle = request->yaw;
new_setpoint = true;
RCLCPP_INFO(this->get_logger(), "Yaw: %f", last_angle);
response->success = true;
}
}
/**
* @brief disarms the drone when a call to the disarm service is made
*
* @param request_header the header for the service request
* @param request the request (empty)
* @param response the response (empty)
*/
void handle_disarm_request(
const std::shared_ptr<rmw_request_id_t> request_header,
const std::shared_ptr<drone_services::srv::DisarmDrone::Request> request,
const std::shared_ptr<drone_services::srv::DisarmDrone::Response> response)
{
RCLCPP_INFO(this->get_logger(), "Got disarm request...");
if (armed)
{
armed = false;
user_in_control = false;
publish_vehicle_command(px4_msgs::msg::VehicleCommand::VEHICLE_CMD_COMPONENT_ARM_DISARM, 0.0, 0);
response->success = true;
}
else
{
RCLCPP_ERROR(this->get_logger(), "Got disarm request but drone was not armed!");
response->success = false;
}
}
/**
* @brief arms the drone when a call to the arm service is made
*
* @param request_header the header for the service request
* @param request the request (empty)
* @param response the response (empty)
*/
void handle_arm_request(
const std::shared_ptr<rmw_request_id_t> request_header,
const std::shared_ptr<drone_services::srv::ArmDrone::Request> request,
const std::shared_ptr<drone_services::srv::ArmDrone::Response> response)
{
RCLCPP_INFO(this->get_logger(), "Got arm request...");
if (!armed)
{
this->publish_vehicle_command(px4_msgs::msg::VehicleCommand::VEHICLE_CMD_DO_SET_MODE, 1, 6);
RCLCPP_INFO(this->get_logger(), "Set to offboard mode");
// arm the drone
this->publish_vehicle_command(px4_msgs::msg::VehicleCommand::VEHICLE_CMD_COMPONENT_ARM_DISARM, 1.0, 0);
RCLCPP_INFO(this->get_logger(), "Arm command sent");
this->last_thrust = -0.1; // spin motors at 10% thrust
armed = true;
response->success = true;
}
else
{
RCLCPP_ERROR(this->get_logger(), "Arm request received but the drone is already armed!");
response->success = false;
}
}
void send_attitude_setpoint()
{
// set message to enable attitude
auto msg = px4_msgs::msg::VehicleAttitudeSetpoint();
// move up?
msg.thrust_body[0] = 0; // north
msg.thrust_body[1] = 0; // east
msg.thrust_body[2] = -last_thrust;
calculate_quaternion(q, last_setpoint[0], last_setpoint[1], last_setpoint[2]);
// set quaternion
msg.q_d[0] = q.at(0);
msg.q_d[1] = base_q[1] + q.at(1);
msg.q_d[2] = base_q[2] + q.at(2);
msg.q_d[3] = base_q[3] + q.at(3);
msg.yaw_sp_move_rate = 0;
msg.reset_integral = false;
msg.fw_control_yaw_wheel = false;
msg.timestamp = this->get_clock()->now().nanoseconds() / 1000;
vehicle_setpoint_publisher_->publish(msg);
}
void send_velocity_setpoint()
{
auto msg = px4_msgs::msg::TrajectorySetpoint();
// if (trajectory_valid_x)
// {
msg.velocity[0] = velocity[0];
trajectory_valid_x = false;
// }
// if (trajectory_valid_y)
// {
msg.velocity[1] = velocity[1];
trajectory_valid_y = false;
// }
// if (trajectory_valid_z)
// {
msg.velocity[2] = D_SPEED(velocity[2]);
trajectory_valid_z = false;
// }
publish_trajectory_setpoint(msg);
}
void send_position_setpoint()
{
auto msg = px4_msgs::msg::TrajectorySetpoint();
// if (trajectory_valid_x)
// {
msg.position[0] = position[0];
trajectory_valid_x = false;
// }
// if (trajectory_valid_y)
// {
msg.position[1] = position[1];
trajectory_valid_y = false;
// }
// if (trajectory_valid_z)
// {
msg.position[2] = position[2];
trajectory_valid_z = false;
// }
publish_trajectory_setpoint(msg);
}
void publish_trajectory_setpoint(px4_msgs::msg::TrajectorySetpoint msg)
{
// if (trajectory_valid_yaw)
// {
msg.yaw = last_angle;
trajectory_valid_yaw = false;
// }
msg.yawspeed = DEFAULT_YAW_SPEED;
msg.timestamp = this->get_clock()->now().nanoseconds() / 1000;
trajectory_setpoint_publisher->publish(msg);
}
/**
* @brief Send setpoints to PX4. First, 20 setpoints will be sent before offboard mode will be engaged and the drone will be armed.
*
*/
void send_setpoint()
{
/*
setpoint_count++;
if (setpoint_count == 20)
{
this->publish_vehicle_command(px4_msgs::msg::VehicleCommand::VEHICLE_CMD_DO_SET_MODE, 1, 6);
RCLCPP_INFO(this->get_logger(), "Set to offboard mode");
// arm the drone
this->publish_vehicle_command(px4_msgs::msg::VehicleCommand::VEHICLE_CMD_COMPONENT_ARM_DISARM, 1.0, 0);
RCLCPP_INFO(this->get_logger(), "Arm command sent");
this->last_thrust = -0.1; // spin motors at 10% thrust
armed = true;
}
send_attitude_setpoint();
*/
// RCLCPP_INFO(this->get_logger(), "current values: %f %f %f %f", last_setpoint[0], last_setpoint[1], last_setpoint[2], last_thrust);
if (!user_in_control)
{
// RCLCPP_INFO(this->get_logger(), "Sending idle attitude setpoint");
send_attitude_setpoint();
}
else
{
if (current_control_mode == CONTROL_MODE_ATTITUDE)
{
// RCLCPP_INFO(this->get_logger(), "Sending attitude setpoint");
send_attitude_setpoint();
}
else
{
if (!new_setpoint)
{
return;
}
if (current_control_mode == CONTROL_MODE_VELOCITY)
{
RCLCPP_INFO(this->get_logger(), "velocity %f %f %f", velocity[0], velocity[1], velocity[2]);
send_velocity_setpoint();
}
else if (current_control_mode == CONTROL_MODE_POSITION)
{
RCLCPP_INFO(this->get_logger(), "position %f %f %f", position[0], position[1], position[2]);
send_position_setpoint();
}
new_setpoint = false;
}
}
}
void on_attitude_receive(const px4_msgs::msg::VehicleAttitude::SharedPtr msg)
{
/*
average q:
- 0.7313786745071411
- 0.005042835604399443
- 0.0002370707516092807
- 0.6819528937339783
*/
if (!armed)
{
if (base_q_amount > 2)
{
base_q[1] = (base_q[1] + msg->q[1]) / 2;
base_q[2] = (base_q[2] + msg->q[2]) / 2;
base_q[3] = (base_q[3] + msg->q[3]) / 2;
}
else
{
base_q[1] = msg->q[1];
base_q[2] = msg->q[2];
base_q[3] = msg->q[3];
base_q_amount++;
}
RCLCPP_INFO(this->get_logger(), "base_q: %f %f %f %f", base_q[0], base_q[1], base_q[2], base_q[3]);
}
}
void on_control_mode_receive(const drone_services::msg::DroneControlMode::SharedPtr msg)
{
if (msg->control_mode >= CONTROL_MODE_MIN && msg->control_mode <= CONTROL_MODE_MAX)
{
current_control_mode = msg->control_mode;
RCLCPP_INFO(this->get_logger(), "Got valid control mode");
user_in_control = true; // user has taken over control
}
else
{
RCLCPP_ERROR(this->get_logger(), "Received invalid control mode %d", msg->control_mode);
}
RCLCPP_INFO(this->get_logger(), "Control mode set to %d", current_control_mode);
}
/**
* @brief Publish vehicle commands
* @param command Command code (matches VehicleCommand and MAVLink MAV_CMD codes)
* @param param1 Command parameter 1
* @param param2 Command parameter 2
*/
void publish_vehicle_command(uint16_t command, float param1, float param2)
{
px4_msgs::msg::VehicleCommand msg{};
msg.param1 = param1;
msg.param2 = param2;
msg.command = command;
msg.target_system = 1;
msg.target_component = 1;
msg.source_system = 1;
msg.source_component = 1;
msg.from_external = true;
msg.timestamp = this->get_clock()->now().nanoseconds() / 1000;
vehicle_command_publisher_->publish(msg);
}
/**
* @brief calculates a quaternion based on the given input values
*
* @param ptr array of result quaternion. Must be of size 4.
* @param heading desired heading (yaw) in radians.
* @param attitude desired attitude (pitch) in radians.
* @param bank desired bank (roll) in radians.
*/
static void calculate_quaternion(std::array<float, 4> &ptr, float heading, float attitude, float bank)
{
float c1 = cos(heading / 2);
float c2 = cos(attitude / 2);
float c3 = cos(bank / 2);
float s1 = sin(heading / 2);
float s2 = sin(attitude / 2);
float s3 = sin(bank / 2);
float c1c2 = c1 * c2;
float s1s2 = s1 * s2;
ptr.at(0) = c1c2 * c3 - s1s2 * s3; // w
ptr.at(1) = c1c2 * s3 + s1s2 * c3; // x
ptr.at(2) = s1 * c2 * c3 + c1 * s2 * s3; // y
ptr.at(3) = c1 * s2 * c3 - s1 * c2 * s3; // z
}
/**
* @brief converts degrees to radians
*
* @param deg angle in degrees
* @return float new angle in radians
*/
static float degrees_to_radians(float deg)
{
return deg * (M_PI / 180.0);
}
};
int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
rclcpp::Node::SharedPtr node = std::make_shared<PX4Controller>();
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>test_controls</name>
<version>0.0.0</version>
<description>test controls</description>
<maintainer email="semmer99@gmail.com">ubuntu</maintainer>
<license>Apache License 2.0</license>
<exec_depend>rclpy</exec_depend>
<exec_depend>drone_services</exec_depend>
<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>
+4
View File
@@ -0,0 +1,4 @@
[develop]
script-dir=$base/lib/test_controls
[install]
install-scripts=$base/lib/test_controls
+26
View File
@@ -0,0 +1,26 @@
from setuptools import setup
package_name = 'test_controls'
setup(
name=package_name,
version='0.0.0',
packages=[package_name],
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='ubuntu',
maintainer_email='semmer99@gmail.com',
description='test controls',
license='Apache License 2.0',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'test_controller = test_controls.test_controller:main'
],
},
)
+23
View File
@@ -0,0 +1,23 @@
# Copyright 2015 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ament_copyright.main import main
import pytest
@pytest.mark.copyright
@pytest.mark.linter
def test_copyright():
rc = main(argv=['.', 'test'])
assert rc == 0, 'Found errors'
+25
View File
@@ -0,0 +1,25 @@
# Copyright 2017 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ament_flake8.main import main_with_errors
import pytest
@pytest.mark.flake8
@pytest.mark.linter
def test_flake8():
rc, errors = main_with_errors(argv=[])
assert rc == 0, \
'Found %d code style errors / warnings:\n' % len(errors) + \
'\n'.join(errors)
+23
View File
@@ -0,0 +1,23 @@
# Copyright 2015 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ament_pep257.main import main
import pytest
@pytest.mark.linter
@pytest.mark.pep257
def test_pep257():
rc = main(argv=['.', 'test'])
assert rc == 0, 'Found code style errors / warnings'
@@ -0,0 +1,298 @@
import rclpy
from rclpy.node import Node
from sshkeyboard import listen_keyboard_manual
import asyncio
from numpy import NAN
from drone_services.srv import SetAttitude
from drone_services.srv import SetTrajectory
from drone_services.srv import SetVehicleControl
from drone_services.srv import ArmDrone
CONTROL_MODE_ATTITUDE = 4
CONTROL_MODE_VELOCITY = 16
CONTROL_MODE_POSITION = 32
class TestController(Node):
def __init__(self):
super().__init__('test_controller')
self.cli = self.create_client(SetAttitude, 'drone/set_attitude')
while not self.cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('set attitude service not available, waiting again...')
self.get_logger().info('successfully connected to set attitude service')
self.vehicle_control_cli = self.create_client(
SetVehicleControl, '/drone/set_vehicle_control')
while not self.vehicle_control_cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('set vehicle control service not available, waiting again...')
self.get_logger().info('successfully connected to set vehicle control service')
self.traj_cli = self.create_client(SetTrajectory, '/drone/set_trajectory')
while not self.traj_cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('set trajectory service not available, waiting again...')
self.get_logger().info('successfully connected to set trajectory service')
self.arm_cli = self.create_client(ArmDrone, '/drone/arm')
while not self.arm_cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('arm service not available, waiting again...')
self.get_logger().info('successfully connected to arm service')
self.get_logger().info('all services available')
self.control_mode = 1
self.attitude_req = SetAttitude.Request()
self.vehicle_control_req = SetVehicleControl.Request()
self.traj_req = SetTrajectory.Request()
self.arm_req = ArmDrone.Request()
self.get_logger().info("\nControls:\n1 - Attitude control\n2 - Velocity control\n3 - Position control\n/ - Arm drone\nW - forward\nS - backward\nA - left\nD - right\nQ - rotate left\nE - rotate right\nSpace - up\nZ - down\nV - Down nudge\nF - Up nudge\nN - emergency stop\nCTRL-C - exit")
def spin(self):
while rclpy.ok():
asyncio.run(listen_keyboard_manual(on_press=self.on_press))
rclpy.spin_once(self, timeout_sec=0.1)
def send_arm(self):
self.future = self.arm_cli.call_async(self.arm_req)
rclpy.spin_until_future_complete(self, self.future)
self.get_logger().info('publishing message arm msg on service')
return self.future.result()
def send_control_mode(self):
self.vehicle_control_req.control = self.control_mode
self.future = self.vehicle_control_cli.call_async(self.vehicle_control_req)
rclpy.spin_until_future_complete(self, self.future)
self.get_logger().info('publishing message vehicle control msg on service')
return self.future.result()
def send_attitude_request(self, yaw, pitch, roll, thrust):
self.attitude_req.yaw = yaw
self.attitude_req.pitch = pitch
self.attitude_req.roll = roll
self.attitude_req.thrust = thrust
self.get_logger().info('set request to %f %f %f %f' % (yaw, pitch, roll, thrust))
self.future = self.cli.call_async(self.attitude_req)
rclpy.spin_until_future_complete(self, self.future)
self.get_logger().info('publishing attitude message on service')
return self.future.result()
def send_velocity_request(self, x, y, z, angle):
self.traj_req.control_mode = 2
if (angle != NAN):
self.traj_req.yaw = angle
if (x != NAN):
self.traj_req.x = x
else:
self.traj_req.x = 0.0
if (y != NAN):
self.traj_req.y = y
else:
self.traj_req.y = 0.0
if (z != NAN):
self.traj_req.z = z
else:
self.traj_req.z = 0.0
self.get_logger().info('set request to %f %f %f %f' % (x, y, z, angle))
self.future = self.traj_cli.call_async(self.traj_req)
rclpy.spin_until_future_complete(self, self.future)
self.get_logger().info('publishing velocity message on service')
return self.future.result()
def send_position_request(self, x, y, z, angle):
self.traj_req.control_mode = 3
if (angle != NAN):
self.traj_req.yaw = angle
if (x != NAN):
self.traj_req.x = x
else:
self.traj_req.x = 0.0
if (y != NAN):
self.traj_req.y = y
else:
self.traj_req.y = 0.0
if (z != NAN):
self.traj_req.z = z
else:
self.traj_req.z = 0.0
self.get_logger().info('set request to %f %f %f %f' % (x, y, z, angle))
self.future = self.traj_cli.call_async(self.traj_req)
rclpy.spin_until_future_complete(self, self.future)
self.get_logger().info('publishing position message on service')
return self.future.result()
def on_release(self, key):
# self.get_logger().info('released ' + str(key))
pass
def move_up(self):
pass
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=0.0, yaw=0.0,
roll=0.0, thrust=0.05)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=NAN, y=NAN, z=1.0, angle=NAN)
else:
self.send_position_request(x=NAN, y=NAN, z=1.0, angle=NAN)
def move_right(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=0.0, yaw=0.0,
roll=1.0, thrust=0.0)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=1.0, y=NAN, z=NAN, angle=NAN)
else:
self.send_position_request(x=1.0, y=NAN, z=NAN, angle=NAN)
def move_down(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=0.0, yaw=0.0,
roll=0.0, thrust=-0.05)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=NAN, y=NAN, z=-1.0, angle=NAN)
else:
self.send_position_request(x=NAN, y=NAN, z=-1.0, angle=NAN)
def move_left(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=0.0, yaw=0.0,
roll=-1.0, thrust=0.0)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=-1.0, y=NAN, z=NAN, angle=NAN)
else:
self.send_position_request(x=-1.0, y=NAN, z=NAN, angle=NAN)
def rotate_right(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=0.0, yaw=1.0,
roll=0.0, thrust=0.0)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=NAN, y=NAN, z=NAN, angle=1.0)
else:
self.send_position_request(x=NAN, y=NAN, z=NAN, angle=1.0)
def rotate_left(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=0.0, yaw=-1.0,
roll=0.0, thrust=0.0)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=NAN, y=NAN, z=NAN, angle=-1.0)
else:
self.send_position_request(x=NAN, y=NAN, z=NAN, angle=-1.0)
def move_forward(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=-1.0, yaw=0.0,
roll=0.0, thrust=0.0)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=NAN, y=1.0, z=NAN, angle=NAN)
else:
self.send_position_request(x=NAN, y=1.0, z=NAN, angle=NAN)
def move_backward(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=1.0, yaw=0.0,
roll=0.0, thrust=0.0)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=NAN, y=-1.0, z=NAN, angle=NAN)
else:
self.send_position_request(x=NAN, y=-1.0, z=NAN, angle=NAN)
def stop(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=0.0, yaw=0.0,
roll=0.0, thrust=0.0)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=0.0, y=0.0, z=0.0, angle=NAN)
else:
self.send_position_request(x=0.0, y=0.0, z=0.0, angle=NAN)
def move_up_little(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=0.0, yaw=0.0,
roll=0.0, thrust=0.01)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=NAN, y=NAN, z=0.5, angle=NAN)
else:
self.send_position_request(x=NAN, y=NAN, z=1.0, angle=NAN)
def move_down_little(self):
if (self.control_mode == CONTROL_MODE_ATTITUDE):
self.send_attitude_request(pitch=0.0, yaw=0.0,
roll=0.0, thrust=-0.01)
elif (self.control_mode == CONTROL_MODE_VELOCITY):
self.send_velocity_request(x=NAN, y=NAN, z=-0.5, angle=NAN)
else:
self.send_position_request(x=NAN, y=NAN, z=-1.0, angle=NAN)
def on_press(self, key):
try:
# self.get_logger().info('pressed ' + char)
if key == 'w':
self.get_logger().info('forward')
self.move_forward()
if key == 's':
self.get_logger().info('backward')
self.move_backward()
if key == 'a':
self.get_logger().info('left')
self.move_left()
if key == 'd':
self.get_logger().info('right')
self.move_right()
if key == 'q':
self.get_logger().info('rotate left')
self.rotate_left()
if key == 'e':
self.get_logger().info('rotate right')
self.rotate_right()
if key == 'z':
self.get_logger().info('down')
self.move_down()
if key == 'space':
self.get_logger().info('up')
self.move_up()
if key == 'v':
self.get_logger().info('down a little')
self.move_down_little()
if key == 'f':
self.get_logger().info('up a little')
self.move_up_little()
if key == 'n':
self.get_logger().info('stop')
self.stop()
if key == '1':
self.get_logger().info('attitude control')
self.control_mode = CONTROL_MODE_ATTITUDE
self.send_control_mode()
if key == '2':
self.get_logger().info('velocity control')
self.control_mode = CONTROL_MODE_VELOCITY
self.send_control_mode()
if key == '3':
self.get_logger().info('position control')
self.control_mode = CONTROL_MODE_POSITION
self.send_control_mode()
if key == '/':
self.get_logger().info('arming')
self.send_arm()
except Exception as e:
self.get_logger().error(str(e))
raise e
def main(args=None):
rclpy.init(args=args)
test_controller = TestController()
test_controller.spin()
# Destroy the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
test_controller.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()