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
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.vscode/
build/
install/
log/

View File

@@ -10,7 +10,10 @@
"/home/ubuntu/ros2_ws/src/beacon_positioning/include/**",
"/usr/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",
"intelliSenseMode": "gcc-x64",

61
.vscode/settings.json vendored
View File

@@ -1,7 +1,66 @@
{
"ros.distro": "humble",
"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": [
"/home/ubuntu/ros2_ws/install/px4_msgs/lib/python3.8/site-packages",

0
TerabeeLog.log Normal file
View File

View File

32
drone_scripts/find_id.sh Executable file
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

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
drone_scripts/start_lidar.sh Executable file
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

7
get_build.sh Executable file
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
get_usb_device_port.sh Normal file
View File

@@ -0,0 +1 @@
/bin/udevadm info --name=/dev/ttyACM0 | grep SERIAL_SHORT | cut -d = -f 2

1051
mav.parm Normal file

File diff suppressed because it is too large Load Diff

BIN
mav.tlog Normal file

Binary file not shown.

BIN
mav.tlog.raw Normal 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

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

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

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

View File

@@ -31,7 +31,9 @@ rosidl_generate_interfaces(${PROJECT_NAME}
)
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
positioning_systems_api::serial_communication

View File

@@ -149,7 +149,7 @@ int main(int argc, char **argv)
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));
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);
}
@@ -160,7 +160,7 @@ int main(int argc, char **argv)
message.y_pos = tracker_msg.tracker_position_xyz.at(1);
message.z_pos = tracker_msg.tracker_position_xyz.at(2);
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;
}

View File

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
src/camera/package.xml Normal file
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
src/camera/setup.cfg Normal file
View File

@@ -0,0 +1,4 @@
[develop]
script-dir=$base/lib/camera
[install]
install-scripts=$base/lib/camera

26
src/camera/setup.py Normal file
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'
],
},
)

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'

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)

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'

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()

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>

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()

View File

@@ -0,0 +1,5 @@
# control mode of the drone
# 1: Attitude
# 2: Velocity
# 3: Position
int8 control_mode

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>

View File

@@ -0,0 +1,2 @@
---
bool success

View File

@@ -0,0 +1,2 @@
---
bool success

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

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

View File

@@ -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

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

View File

@@ -0,0 +1,3 @@
wstring input_name "default" # name of the input file
---
wstring filename # output file name

58
src/height/CMakeLists.txt Normal file
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()

View File

@@ -0,0 +1,2 @@
float32[4] heights
float32 min_height

27
src/height/package.xml Normal file
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>

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;
}

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()

View File

@@ -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
]
)
])

View File

@@ -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"}
]
)
])

View File

@@ -0,0 +1,6 @@
float32 sensor_1
float32 sensor_2
float32 sensor_3
float32 sensor_4
float32[] imu_data

View File

@@ -0,0 +1 @@
float32[6] distance_data

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>

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;
}

View File

@@ -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;
}

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()

View File

@@ -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

View File

@@ -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

View File

@@ -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"
)
])

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>

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;
}

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;
}

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>

View File

View File

@@ -0,0 +1,4 @@
[develop]
script-dir=$base/lib/test_controls
[install]
install-scripts=$base/lib/test_controls

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'
],
},
)

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'

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)

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'

View File

@@ -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()