1 00:00:00,480 --> 00:00:03,480 foreign 2 00:00:08,460 --> 00:00:12,840 good morning again everyone welcome back 3 00:00:10,320 --> 00:00:15,179 to the last session before lunch 4 00:00:12,840 --> 00:00:17,820 um we're going to continue linking 5 00:00:15,179 --> 00:00:20,820 python with other kinds of language with 6 00:00:17,820 --> 00:00:22,199 a talk by David Bowe and David's a 7 00:00:20,820 --> 00:00:23,820 software engineer and former University 8 00:00:22,199 --> 00:00:26,039 tutor 9 00:00:23,820 --> 00:00:30,920 um in his spare time David mentors the 10 00:00:26,039 --> 00:00:33,480 drop bears a first first first 11 00:00:30,920 --> 00:00:35,880 robotics competition team and helps to 12 00:00:33,480 --> 00:00:39,000 maintain robot pie a project to bring 13 00:00:35,880 --> 00:00:40,800 python to the FRC and I'm a little bit 14 00:00:39,000 --> 00:00:43,079 worried about robotic drop bears so 15 00:00:40,800 --> 00:00:44,820 we'll see if you've got them covered 16 00:00:43,079 --> 00:00:45,550 um thanks very much David give him a 17 00:00:44,820 --> 00:00:50,520 welcome 18 00:00:45,550 --> 00:00:50,520 [Applause] 19 00:00:51,180 --> 00:00:56,219 I feel like this is a bit of an 20 00:00:53,280 --> 00:00:58,260 interesting duel to the the previous 21 00:00:56,219 --> 00:01:01,079 talk because I'm about to do basically 22 00:00:58,260 --> 00:01:03,239 the exact opposite sort of 23 00:01:01,079 --> 00:01:07,979 um but let me set the scene a little bit 24 00:01:03,239 --> 00:01:10,320 so perhaps you have a somewhat large C 25 00:01:07,979 --> 00:01:12,900 plus library that you want to ship to 26 00:01:10,320 --> 00:01:15,840 python users but you don't 27 00:01:12,900 --> 00:01:17,520 want to put in a lot of work into doing 28 00:01:15,840 --> 00:01:20,700 that 29 00:01:17,520 --> 00:01:22,619 um or maybe you've written a a c plus 30 00:01:20,700 --> 00:01:24,840 library for 31 00:01:22,619 --> 00:01:27,180 perhaps for performance reasons and you 32 00:01:24,840 --> 00:01:28,920 want an easy way to be able to use it 33 00:01:27,180 --> 00:01:31,799 from python 34 00:01:28,920 --> 00:01:35,820 um so this is the sort of problem that 35 00:01:31,799 --> 00:01:39,540 we had uh it's robot Pi which is a 36 00:01:35,820 --> 00:01:42,960 project to bring python to the first 37 00:01:39,540 --> 00:01:46,680 robotics competition we have to deal 38 00:01:42,960 --> 00:01:51,360 with some reasonably large libraries and 39 00:01:46,680 --> 00:01:54,420 both open and closed source and this is 40 00:01:51,360 --> 00:01:57,540 because they do actually have to 41 00:01:54,420 --> 00:02:00,659 communicate with Hardware so it needs to 42 00:01:57,540 --> 00:02:04,560 be able to call native code at some 43 00:02:00,659 --> 00:02:08,099 point and to give you an idea of what 44 00:02:04,560 --> 00:02:10,920 the first robotic competition is this is 45 00:02:08,099 --> 00:02:14,580 teams of high school students with adult 46 00:02:10,920 --> 00:02:18,900 mentors building 56 kilo robots to play 47 00:02:14,580 --> 00:02:21,319 a sporty kind of game 48 00:02:18,900 --> 00:02:24,599 um so you can see an example there 49 00:02:21,319 --> 00:02:27,860 they get a new challenge each year to 50 00:02:24,599 --> 00:02:27,860 try to keep it interesting 51 00:02:28,440 --> 00:02:34,379 um so yeah let's get into it uh so 52 00:02:31,440 --> 00:02:37,620 one option that you might have is Swig 53 00:02:34,379 --> 00:02:39,360 or the simplified wrapper and interface 54 00:02:37,620 --> 00:02:40,379 generator 55 00:02:39,360 --> 00:02:43,980 um 56 00:02:40,379 --> 00:02:49,080 this lets you uh 57 00:02:43,980 --> 00:02:51,840 take some C or C plus plus and output a 58 00:02:49,080 --> 00:02:53,940 bunch of bindings for 59 00:02:51,840 --> 00:02:55,680 multiple different languages and this is 60 00:02:53,940 --> 00:02:56,940 one of the the oldest ones that I could 61 00:02:55,680 --> 00:02:57,780 find 62 00:02:56,940 --> 00:03:01,980 um 63 00:02:57,780 --> 00:03:03,840 and the fact that it works across so 64 00:03:01,980 --> 00:03:06,180 many different languages is probably a 65 00:03:03,840 --> 00:03:08,400 testament to how mature it is 66 00:03:06,180 --> 00:03:11,159 and 67 00:03:08,400 --> 00:03:14,159 they do intentionally try to keep it as 68 00:03:11,159 --> 00:03:20,220 simple as possible so this is a very 69 00:03:14,159 --> 00:03:22,340 simple example uh where you can take a 70 00:03:20,220 --> 00:03:27,659 take your header file for your library 71 00:03:22,340 --> 00:03:30,659 and you just you can just include it 72 00:03:27,659 --> 00:03:31,980 um and you might want to ignore some 73 00:03:30,659 --> 00:03:34,620 things maybe 74 00:03:31,980 --> 00:03:37,980 um because they're convenient for 75 00:03:34,620 --> 00:03:40,819 C C plus plus but it doesn't really make 76 00:03:37,980 --> 00:03:40,819 sense for python 77 00:03:41,159 --> 00:03:46,940 um 78 00:03:41,940 --> 00:03:51,480 one of the other uh popular open source 79 00:03:46,940 --> 00:03:54,180 projects is sheboken which is one of the 80 00:03:51,480 --> 00:03:56,879 underlying libraries used by QT for 81 00:03:54,180 --> 00:03:59,340 python or you if you've been around for 82 00:03:56,879 --> 00:04:02,700 a while you've been using QT you might 83 00:03:59,340 --> 00:04:05,760 know it as Pi side that 84 00:04:02,700 --> 00:04:09,599 Pi side projects uh eventually became 85 00:04:05,760 --> 00:04:13,159 adopted by the QT project and is now 86 00:04:09,599 --> 00:04:15,680 like the quote-unquote official bindings 87 00:04:13,159 --> 00:04:20,100 for QT 88 00:04:15,680 --> 00:04:22,400 and they use some XML to configure 89 00:04:20,100 --> 00:04:25,800 which kind of looks like this 90 00:04:22,400 --> 00:04:28,919 uh which this is this is an example I 91 00:04:25,800 --> 00:04:30,419 pulled straight from their docs it is a 92 00:04:28,919 --> 00:04:32,960 little bit intimidating though so I'm 93 00:04:30,419 --> 00:04:36,960 going to break it down a little bit and 94 00:04:32,960 --> 00:04:38,460 so here we have our first class that 95 00:04:36,960 --> 00:04:41,759 that we're binding to on the left hand 96 00:04:38,460 --> 00:04:44,940 side is the XML the right hand side is 97 00:04:41,759 --> 00:04:46,979 the C plus definition it's a declaration 98 00:04:44,940 --> 00:04:51,419 for it sorry 99 00:04:46,979 --> 00:04:53,160 um you can see we have two methods in 100 00:04:51,419 --> 00:04:56,100 there 101 00:04:53,160 --> 00:05:00,720 um but the XML only talks about one of 102 00:04:56,100 --> 00:05:03,199 them so by default uh all methods are 103 00:05:00,720 --> 00:05:05,040 exposed to python 104 00:05:03,199 --> 00:05:09,120 and 105 00:05:05,040 --> 00:05:11,699 here we have to if we say that we want 106 00:05:09,120 --> 00:05:16,740 some special handling for this clone 107 00:05:11,699 --> 00:05:20,040 method uh particularly we modify what it 108 00:05:16,740 --> 00:05:22,680 calls argument index zero that's the 109 00:05:20,040 --> 00:05:27,780 return value of of that method 110 00:05:22,680 --> 00:05:33,840 and here we're actually saying that uh 111 00:05:27,780 --> 00:05:36,360 the bindings should not uh destroy the 112 00:05:33,840 --> 00:05:40,320 object and it should instead let C plus 113 00:05:36,360 --> 00:05:42,479 plus deal with the memory management 114 00:05:40,320 --> 00:05:43,919 because we get a pointer so so it 115 00:05:42,479 --> 00:05:47,639 doesn't actually know 116 00:05:43,919 --> 00:05:51,720 necessarily how to handle that 117 00:05:47,639 --> 00:05:54,660 and then we have this other class 118 00:05:51,720 --> 00:05:58,380 there's a whole bunch of more methods 119 00:05:54,660 --> 00:06:03,300 but what's interesting in the the the 120 00:05:58,380 --> 00:06:05,400 bindings here is that we also have a 121 00:06:03,300 --> 00:06:08,520 property that we can Define so you can 122 00:06:05,400 --> 00:06:11,160 just you know do truck dot arrival 123 00:06:08,520 --> 00:06:15,060 message and instead of having to call 124 00:06:11,160 --> 00:06:17,400 get a rival message and and set a rival 125 00:06:15,060 --> 00:06:20,880 message to set it 126 00:06:17,400 --> 00:06:22,979 um and and then we have a similar thing 127 00:06:20,880 --> 00:06:24,720 with memory management 128 00:06:22,979 --> 00:06:27,900 we 129 00:06:24,720 --> 00:06:31,819 and argument index one actually refers 130 00:06:27,900 --> 00:06:31,819 to the argument this time so 131 00:06:32,280 --> 00:06:39,860 um 132 00:06:34,280 --> 00:06:44,100 uh and this takes us to the 133 00:06:39,860 --> 00:06:47,220 underlying library that we use uh we 134 00:06:44,100 --> 00:06:50,220 chose to use which is pi bind 11. it's a 135 00:06:47,220 --> 00:06:53,280 c plus header only Library so it's 136 00:06:50,220 --> 00:06:54,539 pretty easy to pull into a c plus 137 00:06:53,280 --> 00:07:00,240 project 138 00:06:54,539 --> 00:07:02,880 and it lets you build a module uh and 139 00:07:00,240 --> 00:07:07,680 you declare everything that you want to 140 00:07:02,880 --> 00:07:12,319 expose to python in a c plus file 141 00:07:07,680 --> 00:07:17,880 um and it does let you also 142 00:07:12,319 --> 00:07:20,280 depend on classes from different Pi bind 143 00:07:17,880 --> 00:07:21,599 11 modules that you've and that have 144 00:07:20,280 --> 00:07:24,300 been built 145 00:07:21,599 --> 00:07:26,880 um I believe shaboken does support this 146 00:07:24,300 --> 00:07:30,780 as well but I haven't actually 147 00:07:26,880 --> 00:07:34,199 use that all that much uh let me know if 148 00:07:30,780 --> 00:07:36,840 if that's wrong but we'll see why this 149 00:07:34,199 --> 00:07:41,160 is important a little bit later 150 00:07:36,840 --> 00:07:43,199 um here is an example of Pi bindle of 151 00:07:41,160 --> 00:07:46,500 what pi by 11 looks like 152 00:07:43,199 --> 00:07:51,780 so on the left hand side I have my C 153 00:07:46,500 --> 00:07:53,520 plus code to to generate to have these 154 00:07:51,780 --> 00:07:56,699 bindings 155 00:07:53,520 --> 00:08:00,300 um first we say that we're building an 156 00:07:56,699 --> 00:08:04,919 a511 module and then next here is our 157 00:08:00,300 --> 00:08:08,520 module name so so to import this module 158 00:08:04,919 --> 00:08:12,000 from my python code I would you know say 159 00:08:08,520 --> 00:08:15,000 import python EU example 160 00:08:12,000 --> 00:08:18,060 and then M here is a variable name in 161 00:08:15,000 --> 00:08:20,940 the C plus code to say this is the 162 00:08:18,060 --> 00:08:24,599 module that I'm putting together so the 163 00:08:20,940 --> 00:08:30,319 first thing that we have here is we 164 00:08:24,599 --> 00:08:33,860 Define and add thing specifically the 165 00:08:30,319 --> 00:08:37,260 where putting the ad 166 00:08:33,860 --> 00:08:39,839 function that you can see on the right 167 00:08:37,260 --> 00:08:42,659 hand side that declaration and we're 168 00:08:39,839 --> 00:08:47,240 exposing that to python 169 00:08:42,659 --> 00:08:52,019 and then we have this pet class 170 00:08:47,240 --> 00:08:54,839 so we say I want a class called pet 171 00:08:52,019 --> 00:08:58,080 we put that on the module and it 172 00:08:54,839 --> 00:09:00,420 corresponds to the C plus plus pet class 173 00:08:58,080 --> 00:09:03,540 that you can see 174 00:09:00,420 --> 00:09:08,640 so you so we 175 00:09:03,540 --> 00:09:10,459 this first line here with the the pi 176 00:09:08,640 --> 00:09:15,839 pack in it 177 00:09:10,459 --> 00:09:17,779 that corresponds to the Constructor here 178 00:09:15,839 --> 00:09:20,720 and then we 179 00:09:17,779 --> 00:09:22,980 bind the set name get name methods 180 00:09:20,720 --> 00:09:27,720 fairly straightforward 181 00:09:22,980 --> 00:09:31,560 and then we can also declare a property 182 00:09:27,720 --> 00:09:33,360 just like you could in chibokin 183 00:09:31,560 --> 00:09:35,220 so 184 00:09:33,360 --> 00:09:39,420 this 185 00:09:35,220 --> 00:09:42,839 kind of takes us into a journey that we 186 00:09:39,420 --> 00:09:46,760 went through with a couple of our 187 00:09:42,839 --> 00:09:51,740 earlier approaches to 188 00:09:46,760 --> 00:09:56,040 to generate All That C plus plus code 189 00:09:51,740 --> 00:09:56,580 that we would have to write otherwise 190 00:09:56,040 --> 00:09:58,339 um 191 00:09:56,580 --> 00:10:02,339 because 192 00:09:58,339 --> 00:10:04,320 we have some fairly large libraries 193 00:10:02,339 --> 00:10:05,820 right 194 00:10:04,320 --> 00:10:09,420 um so the 195 00:10:05,820 --> 00:10:13,320 first example that I I'll show here 196 00:10:09,420 --> 00:10:16,700 is a involves a vendor library that 197 00:10:13,320 --> 00:10:21,720 provides a c interface 198 00:10:16,700 --> 00:10:27,480 so we ended up building a library that 199 00:10:21,720 --> 00:10:31,200 can take a c plus header file 200 00:10:27,480 --> 00:10:33,420 it pauses it using a pure python C plus 201 00:10:31,200 --> 00:10:37,560 plus parser 202 00:10:33,420 --> 00:10:39,060 there were good reasons for this 203 00:10:37,560 --> 00:10:43,100 um 204 00:10:39,060 --> 00:10:46,980 but this Library lets us 205 00:10:43,100 --> 00:10:50,519 generate lit literally whatever we want 206 00:10:46,980 --> 00:10:55,320 from a c plus header 207 00:10:50,519 --> 00:10:58,040 so it takes in some python code and a 208 00:10:55,320 --> 00:11:01,380 bit of yaml configuration 209 00:10:58,040 --> 00:11:05,040 that's provided to that python code and 210 00:11:01,380 --> 00:11:06,120 then puts it into a ginger to template 211 00:11:05,040 --> 00:11:08,760 um 212 00:11:06,120 --> 00:11:11,640 so 213 00:11:08,760 --> 00:11:16,019 here's an example of what that sort of 214 00:11:11,640 --> 00:11:16,800 looks like on the left I have some yaml 215 00:11:16,019 --> 00:11:20,760 um 216 00:11:16,800 --> 00:11:22,800 so each top level entry is each function 217 00:11:20,760 --> 00:11:24,779 that we want to bind to 218 00:11:22,800 --> 00:11:28,920 uh you'll you'll notice on the right 219 00:11:24,779 --> 00:11:31,500 hand side each of these take this handle 220 00:11:28,920 --> 00:11:36,779 pointer so we decide to abstract that 221 00:11:31,500 --> 00:11:39,420 away and put it in a c plus so that we 222 00:11:36,779 --> 00:11:43,079 don't have to deal with it 223 00:11:39,420 --> 00:11:44,300 um and then you can see here's something 224 00:11:43,079 --> 00:11:48,320 interesting 225 00:11:44,300 --> 00:11:52,500 we provide we can set 226 00:11:48,320 --> 00:11:54,720 some default values for for some of 227 00:11:52,500 --> 00:11:57,300 these parameters and 228 00:11:54,720 --> 00:12:00,360 you might notice that that's a default 229 00:11:57,300 --> 00:12:04,459 value in the middle here that's because 230 00:12:00,360 --> 00:12:08,339 in our python code we had set a 231 00:12:04,459 --> 00:12:12,440 global default for for parameters called 232 00:12:08,339 --> 00:12:12,440 timeout Ms to zero 233 00:12:13,200 --> 00:12:19,079 this is what the 234 00:12:15,560 --> 00:12:21,360 ginger 2 template looks like to generate 235 00:12:19,079 --> 00:12:23,519 the C plus plus classes 236 00:12:21,360 --> 00:12:25,279 um it's scary that if you actually want 237 00:12:23,519 --> 00:12:30,420 to read the code there's a link there 238 00:12:25,279 --> 00:12:32,100 but this is then the template for the pi 239 00:12:30,420 --> 00:12:32,880 bind 11 code 240 00:12:32,100 --> 00:12:35,339 um 241 00:12:32,880 --> 00:12:37,680 feel like you probably get the idea so I 242 00:12:35,339 --> 00:12:41,220 won't show you the pipe the python code 243 00:12:37,680 --> 00:12:44,760 and that that first that first 244 00:12:41,220 --> 00:12:46,980 preprocessors uh it so 245 00:12:44,760 --> 00:12:49,320 but yeah 246 00:12:46,980 --> 00:12:51,240 so 247 00:12:49,320 --> 00:12:55,700 next example 248 00:12:51,240 --> 00:13:00,839 uh we ended up getting a vendor Library 249 00:12:55,700 --> 00:13:04,820 uh that's only exposed a an 250 00:13:00,839 --> 00:13:10,639 object-oriented uh C plus plus interface 251 00:13:04,820 --> 00:13:13,620 uh so luckily we already had all this 252 00:13:10,639 --> 00:13:16,100 generation code from that previous 253 00:13:13,620 --> 00:13:20,220 library that that we built 254 00:13:16,100 --> 00:13:21,000 so we decided to reuse some of some of 255 00:13:20,220 --> 00:13:23,000 it 256 00:13:21,000 --> 00:13:23,000 um 257 00:13:23,519 --> 00:13:30,839 so yeah similar sort of setup uh with 258 00:13:27,480 --> 00:13:34,079 the same libraries but different python 259 00:13:30,839 --> 00:13:35,959 code and and the yaml looks a little bit 260 00:13:34,079 --> 00:13:40,860 different 261 00:13:35,959 --> 00:13:43,980 so here we have this 262 00:13:40,860 --> 00:13:46,800 uh C plus plus class at the top 263 00:13:43,980 --> 00:13:48,360 and then we declare a few different 264 00:13:46,800 --> 00:13:52,500 methods 265 00:13:48,360 --> 00:13:55,560 um you uh you might notice if you look 266 00:13:52,500 --> 00:13:58,800 at the right hand side there are two 267 00:13:55,560 --> 00:14:02,220 methods with the exact same name 268 00:13:58,800 --> 00:14:03,120 this is called overloading and C plus 269 00:14:02,220 --> 00:14:07,579 plus 270 00:14:03,120 --> 00:14:07,579 where you can 271 00:14:08,000 --> 00:14:14,579 essentially uh 272 00:14:11,220 --> 00:14:17,839 end up calling a different function 273 00:14:14,579 --> 00:14:20,700 depending on what 274 00:14:17,839 --> 00:14:25,440 parameters you pass in 275 00:14:20,700 --> 00:14:29,120 um but in Python this kind of ends up 276 00:14:25,440 --> 00:14:32,459 looking a little bit ugly so what we did 277 00:14:29,120 --> 00:14:37,579 was we actually ignored this first 278 00:14:32,459 --> 00:14:41,880 method and then we set the a default for 279 00:14:37,579 --> 00:14:44,579 the second overload because 280 00:14:41,880 --> 00:14:46,139 we dug into it and it turns out that the 281 00:14:44,579 --> 00:14:48,620 first overload actually just delegates 282 00:14:46,139 --> 00:14:48,620 to the second 283 00:14:49,040 --> 00:14:55,519 I'll also note here you might notice 284 00:14:51,839 --> 00:14:59,639 that these method names are Pascal case 285 00:14:55,519 --> 00:15:02,339 so we turn them into camel case this is 286 00:14:59,639 --> 00:15:05,880 because we already had a whole bunch of 287 00:15:02,339 --> 00:15:07,560 existing libraries in robot Pi that were 288 00:15:05,880 --> 00:15:13,220 all camel case 289 00:15:07,560 --> 00:15:17,579 uh but this also lets students uh 290 00:15:13,220 --> 00:15:21,420 easily copy stuff from java code because 291 00:15:17,579 --> 00:15:25,500 there's a pretty healthy uh culture of 292 00:15:21,420 --> 00:15:26,760 sharing code uh within FRC 293 00:15:25,500 --> 00:15:29,519 um 294 00:15:26,760 --> 00:15:31,740 I think you I don't think I need to show 295 00:15:29,519 --> 00:15:33,480 any more code for for this hopefully you 296 00:15:31,740 --> 00:15:34,860 get the idea now 297 00:15:33,480 --> 00:15:37,680 um 298 00:15:34,860 --> 00:15:40,680 so that takes us to what we have today 299 00:15:37,680 --> 00:15:42,480 which is this sort of generalized build 300 00:15:40,680 --> 00:15:46,500 system for 301 00:15:42,480 --> 00:15:50,120 for generating these uh python these 302 00:15:46,500 --> 00:15:50,120 these C plus plus bindings 303 00:15:50,639 --> 00:15:57,899 so robot Pi build is a 304 00:15:55,139 --> 00:16:01,560 fairly opinionated build system for a 305 00:15:57,899 --> 00:16:04,079 python package so you use it to clear it 306 00:16:01,560 --> 00:16:04,740 in your Pi Project tunnel 307 00:16:04,079 --> 00:16:07,880 um 308 00:16:04,740 --> 00:16:11,220 reads reads your C plus plus headers 309 00:16:07,880 --> 00:16:12,240 generates some Pi by 11 code in the 310 00:16:11,220 --> 00:16:16,500 background 311 00:16:12,240 --> 00:16:19,260 and it will also package up your shared 312 00:16:16,500 --> 00:16:21,839 libraries or dlls in Windows parlance 313 00:16:19,260 --> 00:16:24,600 together with your python package when 314 00:16:21,839 --> 00:16:29,220 you upload it to IPI 315 00:16:24,600 --> 00:16:33,120 uh we use C types to load it at runtime 316 00:16:29,220 --> 00:16:36,480 so it's it works cross-platform but 317 00:16:33,120 --> 00:16:39,959 a consequence of us packaging them 318 00:16:36,480 --> 00:16:42,720 together is this is that we explicitly 319 00:16:39,959 --> 00:16:45,360 don't support binding to system 320 00:16:42,720 --> 00:16:47,279 libraries so if you need to use 321 00:16:45,360 --> 00:16:48,959 libraries that you have installed in 322 00:16:47,279 --> 00:16:53,120 your system you 323 00:16:48,959 --> 00:16:55,199 might be better to use Swig or shavokin 324 00:16:53,120 --> 00:16:59,459 or right 325 00:16:55,199 --> 00:17:00,300 Pi by an 11 code yourself I guess sorry 326 00:16:59,459 --> 00:17:02,600 um 327 00:17:00,300 --> 00:17:05,040 but yeah so so 328 00:17:02,600 --> 00:17:08,100 we end up with 329 00:17:05,040 --> 00:17:13,199 these data files that 330 00:17:08,100 --> 00:17:16,439 uh describe what headers to look at in 331 00:17:13,199 --> 00:17:22,860 this library that you're building 332 00:17:16,439 --> 00:17:25,980 um for what names you expect so both 333 00:17:22,860 --> 00:17:29,520 functions classes in arms things like 334 00:17:25,980 --> 00:17:33,059 that and also any particular special 335 00:17:29,520 --> 00:17:35,039 handling that you might need of 336 00:17:33,059 --> 00:17:38,660 so 337 00:17:35,039 --> 00:17:41,480 give you an overview of 338 00:17:38,660 --> 00:17:45,419 what our dependency graph looks like 339 00:17:41,480 --> 00:17:49,380 this is just the dependency graph for 340 00:17:45,419 --> 00:17:51,600 the same Library as our previous example 341 00:17:49,380 --> 00:17:54,179 just now 342 00:17:51,600 --> 00:17:57,980 um you might notice there's 343 00:17:54,179 --> 00:17:57,980 there's a whole bunch of different 344 00:17:58,380 --> 00:18:06,539 yeah we've got diamond dependencies and 345 00:18:02,280 --> 00:18:10,039 and there's also subclassing of 346 00:18:06,539 --> 00:18:12,799 of classes from each of these different 347 00:18:10,039 --> 00:18:17,340 uh libraries as well 348 00:18:12,799 --> 00:18:20,280 so this is where the pi bind 11 support 349 00:18:17,340 --> 00:18:21,600 for cross module class usage comes in 350 00:18:20,280 --> 00:18:22,919 because 351 00:18:21,600 --> 00:18:25,200 we've got 352 00:18:22,919 --> 00:18:28,140 there's been a library that has to be 353 00:18:25,200 --> 00:18:32,039 able to subclass a 354 00:18:28,140 --> 00:18:35,700 an interface that that's uh on one of 355 00:18:32,039 --> 00:18:39,360 our other libraries provides 356 00:18:35,700 --> 00:18:45,539 so this is what the pi project.tamil 357 00:18:39,360 --> 00:18:49,020 looks like so at the top uh we say that 358 00:18:45,539 --> 00:18:51,120 we want to to download 359 00:18:49,020 --> 00:18:56,220 uh 360 00:18:51,120 --> 00:18:59,760 uh our vendor Library uh and there's and 361 00:18:56,220 --> 00:19:02,280 yeah in FRC we've set up this uh 362 00:18:59,760 --> 00:19:06,600 standard convention uh that's 363 00:19:02,280 --> 00:19:09,720 maven-based uh for where to find 364 00:19:06,600 --> 00:19:13,080 uh find libraries 365 00:19:09,720 --> 00:19:18,240 and then we and then we start talking 366 00:19:13,080 --> 00:19:21,080 about our actual C our actual Pi bind 11 367 00:19:18,240 --> 00:19:21,080 wrapper 368 00:19:21,539 --> 00:19:26,720 um and you can see there we have this 369 00:19:24,299 --> 00:19:30,840 depends list 370 00:19:26,720 --> 00:19:36,059 s uh other packages that we've built 371 00:19:30,840 --> 00:19:40,559 using robot Pi build and this lets us 372 00:19:36,059 --> 00:19:42,179 actually link bitten to those other 373 00:19:40,559 --> 00:19:46,080 packages 374 00:19:42,179 --> 00:19:47,280 and then at the bottom uh we have a list 375 00:19:46,080 --> 00:19:51,059 of 376 00:19:47,280 --> 00:19:54,120 of headers that we want to look at this 377 00:19:51,059 --> 00:19:57,660 is just an excerpt so uh we're just 378 00:19:54,120 --> 00:20:00,020 going to be focusing on on this example 379 00:19:57,660 --> 00:20:00,020 here 380 00:20:00,720 --> 00:20:05,160 this is the same class from the previous 381 00:20:02,820 --> 00:20:07,280 example as well 382 00:20:05,160 --> 00:20:07,280 um 383 00:20:07,940 --> 00:20:15,320 so there is a little bit of new things 384 00:20:11,580 --> 00:20:19,860 in here where we have this keep alive 385 00:20:15,320 --> 00:20:23,400 thing so what this does is it's part of 386 00:20:19,860 --> 00:20:25,500 hiveine 11 and it lets you bind the 387 00:20:23,400 --> 00:20:28,620 lifetime of 388 00:20:25,500 --> 00:20:30,000 of one object to another 389 00:20:28,620 --> 00:20:32,940 so 390 00:20:30,000 --> 00:20:37,620 in this case so so here we have 391 00:20:32,940 --> 00:20:41,280 zero which is our return value and one 392 00:20:37,620 --> 00:20:45,059 which is self so this is saying that 393 00:20:41,280 --> 00:20:49,980 this PID controller thing that's 394 00:20:45,059 --> 00:20:53,580 returned by this method make sure that 395 00:20:49,980 --> 00:20:56,280 it doesn't outlive this 396 00:20:53,580 --> 00:21:00,059 can Spark Max 397 00:20:56,280 --> 00:21:01,760 so why else do you still have this PID 398 00:21:00,059 --> 00:21:06,200 controller object 399 00:21:01,760 --> 00:21:09,059 the cansbach max object would not be 400 00:21:06,200 --> 00:21:11,940 garbage collected 401 00:21:09,059 --> 00:21:16,080 and then at the bottom here we have a 402 00:21:11,940 --> 00:21:17,760 bit of inline code so this lets you uh 403 00:21:16,080 --> 00:21:22,020 shove 404 00:21:17,760 --> 00:21:25,200 some C plus plus code into the pi Vine 405 00:21:22,020 --> 00:21:27,900 11 module that's eventually generated 406 00:21:25,200 --> 00:21:31,799 and this allows us for infinite 407 00:21:27,900 --> 00:21:34,679 customization so here we actually add a 408 00:21:31,799 --> 00:21:39,120 method to the python class that doesn't 409 00:21:34,679 --> 00:21:39,780 exist on the C plus class 410 00:21:39,120 --> 00:21:42,080 um 411 00:21:39,780 --> 00:21:45,059 specifically here where 412 00:21:42,080 --> 00:21:49,559 adding a Dunder wrapper method 413 00:21:45,059 --> 00:21:52,380 just so that our users which are high 414 00:21:49,559 --> 00:21:54,780 school students can more easily debug 415 00:21:52,380 --> 00:21:57,659 their robot code right they don't care 416 00:21:54,780 --> 00:22:00,740 about the memory address which is what 417 00:21:57,659 --> 00:22:00,740 the default wrapper is 418 00:22:01,980 --> 00:22:07,860 there are other 419 00:22:04,500 --> 00:22:09,299 Pi bind 11 Auto generators out there 420 00:22:07,860 --> 00:22:11,940 um 421 00:22:09,299 --> 00:22:14,400 some of them are listed from the pi by 422 00:22:11,940 --> 00:22:17,940 11 documentation which I have also 423 00:22:14,400 --> 00:22:20,820 listed here I haven't had an opportunity 424 00:22:17,940 --> 00:22:25,440 to try them out but 425 00:22:20,820 --> 00:22:28,320 they do actually use clang and actual C 426 00:22:25,440 --> 00:22:29,880 plus plus compiler rather than a C plus 427 00:22:28,320 --> 00:22:31,919 plus parser that's been written in 428 00:22:29,880 --> 00:22:36,000 Python uh 429 00:22:31,919 --> 00:22:37,020 which does solve a lot of the edge cases 430 00:22:36,000 --> 00:22:40,440 in 431 00:22:37,020 --> 00:22:43,559 having to pass C plus plus because 432 00:22:40,440 --> 00:22:46,380 there because 433 00:22:43,559 --> 00:22:49,760 it's it's a lot harder to parse C plus 434 00:22:46,380 --> 00:22:49,760 plus than you might think 435 00:22:51,299 --> 00:22:53,720 okay 436 00:22:54,539 --> 00:23:02,100 so you might be wondering then how do we 437 00:22:58,320 --> 00:23:06,000 ship all these libraries to our users 438 00:23:02,100 --> 00:23:09,900 right we basically just want them to be 439 00:23:06,000 --> 00:23:12,179 able to pip install robot pi and things 440 00:23:09,900 --> 00:23:16,380 work 441 00:23:12,179 --> 00:23:18,320 so what we do is we build a bunch of 442 00:23:16,380 --> 00:23:22,020 wheels in CI 443 00:23:18,320 --> 00:23:24,780 we have a lot of repos so we created 444 00:23:22,020 --> 00:23:27,919 this reusable workflow which is a GitHub 445 00:23:24,780 --> 00:23:30,559 actions feature where you can say hey 446 00:23:27,919 --> 00:23:34,200 this this CI pipeline 447 00:23:30,559 --> 00:23:38,299 should just run this CI pipeline that's 448 00:23:34,200 --> 00:23:38,299 that's defined in this other repo 449 00:23:38,760 --> 00:23:45,299 you know we build for the three 450 00:23:42,120 --> 00:23:47,700 big operating systems for all the 451 00:23:45,299 --> 00:23:50,520 currently supported C python versions 452 00:23:47,700 --> 00:23:53,460 so 453 00:23:50,520 --> 00:23:59,400 that ends up being 15 wheels that we 454 00:23:53,460 --> 00:24:02,700 upload to Pipi and we deploy these 455 00:23:59,400 --> 00:24:05,760 whenever we push a git tag so that 456 00:24:02,700 --> 00:24:07,380 that's part of the CI pipeline as well 457 00:24:05,760 --> 00:24:09,559 is that 458 00:24:07,380 --> 00:24:13,640 it checks whether 459 00:24:09,559 --> 00:24:13,640 we've just pushed the git tag 460 00:24:13,919 --> 00:24:19,679 and we also build a bunch of arm Wheels 461 00:24:17,820 --> 00:24:22,100 as well and we have a private repo for 462 00:24:19,679 --> 00:24:28,080 those this is because 463 00:24:22,100 --> 00:24:29,700 the uh the main controller that's used 464 00:24:28,080 --> 00:24:34,860 in 465 00:24:29,700 --> 00:24:37,200 FRC is a bit of an unusual Linux 466 00:24:34,860 --> 00:24:38,760 um platform 467 00:24:37,200 --> 00:24:42,179 but 468 00:24:38,760 --> 00:24:45,900 we also but yeah we do also Target 469 00:24:42,179 --> 00:24:49,620 raspbian but because arm is so diverse 470 00:24:45,900 --> 00:24:51,720 right like what uh like as general said 471 00:24:49,620 --> 00:24:53,520 like what arm are you are you talking 472 00:24:51,720 --> 00:24:57,480 about right 473 00:24:53,520 --> 00:25:01,320 so we decide that we don't want to deal 474 00:24:57,480 --> 00:25:04,260 with that uh when uploading to Pi Pi and 475 00:25:01,320 --> 00:25:08,580 users have to explicitly opt in to 476 00:25:04,260 --> 00:25:09,840 actually using our our Wheels 477 00:25:08,580 --> 00:25:12,900 now 478 00:25:09,840 --> 00:25:16,740 our Wheels do technically fail audit 479 00:25:12,900 --> 00:25:18,840 wheel which is the the many Linux 480 00:25:16,740 --> 00:25:19,799 auditor 481 00:25:18,840 --> 00:25:23,779 um 482 00:25:19,799 --> 00:25:26,360 and this is because of our cross package 483 00:25:23,779 --> 00:25:30,779 Library dependencies 484 00:25:26,360 --> 00:25:33,960 they do otherwise satisfy many Linux 485 00:25:30,779 --> 00:25:38,159 as last time I checked 486 00:25:33,960 --> 00:25:41,700 so and we just end up renaming the 487 00:25:38,159 --> 00:25:44,580 wheels NCI just before we upload to Pi 488 00:25:41,700 --> 00:25:48,900 Pi and 489 00:25:44,580 --> 00:25:52,940 we haven't had complaints so 490 00:25:48,900 --> 00:25:52,940 I I'm pretty sure it works 491 00:25:53,100 --> 00:25:56,820 that's all I have 492 00:25:54,960 --> 00:25:59,820 um 493 00:25:56,820 --> 00:26:02,039 if you want to check out check this out 494 00:25:59,820 --> 00:26:06,059 there's a link to the tower repo and our 495 00:26:02,039 --> 00:26:08,159 docs we also have a matrix Channel 496 00:26:06,059 --> 00:26:10,559 and 497 00:26:08,159 --> 00:26:12,900 yeah 498 00:26:10,559 --> 00:26:16,580 thank you 499 00:26:12,900 --> 00:26:16,580 thank you very much David 500 00:26:17,340 --> 00:26:20,840 we've got a little bit of time for 501 00:26:18,600 --> 00:26:20,840 questions 502 00:26:22,260 --> 00:26:27,539 I'm curious about how 503 00:26:24,419 --> 00:26:30,059 um how many other 504 00:26:27,539 --> 00:26:31,080 is it using other robot platforms or on 505 00:26:30,059 --> 00:26:35,100 other 506 00:26:31,080 --> 00:26:40,100 um uh C plus plus projects yet 507 00:26:35,100 --> 00:26:42,299 so I do believe that one of our 508 00:26:40,100 --> 00:26:47,279 co-maintainers the main maintainer 509 00:26:42,299 --> 00:26:49,740 actually uh has used it at work 510 00:26:47,279 --> 00:26:52,980 um I'm not entirely sure on the details 511 00:26:49,740 --> 00:26:55,799 because work stuff I guess but yeah yeah 512 00:26:52,980 --> 00:26:58,500 cool there's a question at the front uh 513 00:26:55,799 --> 00:26:59,880 question I had was why you went down the 514 00:26:58,500 --> 00:27:03,539 route of Auto 515 00:26:59,880 --> 00:27:05,700 generating the pi bind uh code rather 516 00:27:03,539 --> 00:27:08,159 than handwriting it that's a good 517 00:27:05,700 --> 00:27:13,020 question yeah so 518 00:27:08,159 --> 00:27:17,340 the libraries that we had to to uh 519 00:27:13,020 --> 00:27:18,840 package are actually very large like 520 00:27:17,340 --> 00:27:22,260 um 521 00:27:18,840 --> 00:27:25,260 like we like in one of our libraries we 522 00:27:22,260 --> 00:27:28,140 have like uh 523 00:27:25,260 --> 00:27:30,419 I want to say like at least 50 different 524 00:27:28,140 --> 00:27:31,260 classes 525 00:27:30,419 --> 00:27:35,279 um 526 00:27:31,260 --> 00:27:37,020 there's also the one of our 527 00:27:35,279 --> 00:27:40,740 our packages is 528 00:27:37,020 --> 00:27:43,020 um some maths very maths heavy 529 00:27:40,740 --> 00:27:44,820 um and so there's a bunch of classes in 530 00:27:43,020 --> 00:27:46,679 there and 531 00:27:44,820 --> 00:27:48,419 we want to use C plus for performance 532 00:27:46,679 --> 00:27:51,559 reasons there 533 00:27:48,419 --> 00:27:51,559 um but then 534 00:27:52,080 --> 00:27:58,760 actually yeah yeah that's a lot happened 535 00:27:54,960 --> 00:27:58,760 cool any other questions 536 00:28:01,320 --> 00:28:05,820 so I was just curious if you'd looked at 537 00:28:02,940 --> 00:28:07,860 using uh CI build will to solve some of 538 00:28:05,820 --> 00:28:09,299 those like Auto wheel compatibility 539 00:28:07,860 --> 00:28:11,220 issues 540 00:28:09,299 --> 00:28:12,720 it's a good question 541 00:28:11,220 --> 00:28:15,240 um 542 00:28:12,720 --> 00:28:17,340 I did have a brief look at it 543 00:28:15,240 --> 00:28:23,480 um but 544 00:28:17,340 --> 00:28:25,679 I'm not sure that CI build will support 545 00:28:23,480 --> 00:28:29,100 uh the 546 00:28:25,679 --> 00:28:31,080 uh Ubuntu versions that we have to 547 00:28:29,100 --> 00:28:32,520 actually Target 548 00:28:31,080 --> 00:28:33,960 um 549 00:28:32,520 --> 00:28:36,000 this is a good question I'll have to 550 00:28:33,960 --> 00:28:37,500 double check on that 551 00:28:36,000 --> 00:28:39,840 cool 552 00:28:37,500 --> 00:28:42,140 anyone else I'll just walk yep time for 553 00:28:39,840 --> 00:28:42,140 one more 554 00:28:45,000 --> 00:28:48,240 hello 555 00:28:45,960 --> 00:28:51,240 um just wondering if your approach works 556 00:28:48,240 --> 00:28:54,179 with very heavily templated libraries or 557 00:28:51,240 --> 00:28:55,679 header only libraries yes excellent 558 00:28:54,179 --> 00:28:59,640 question yes 559 00:28:55,679 --> 00:29:02,520 um so uh a few of our libraries are 560 00:28:59,640 --> 00:29:04,500 actually pretty template heavy and so we 561 00:29:02,520 --> 00:29:07,200 do have explicit support for that in 562 00:29:04,500 --> 00:29:10,440 robot pie build as well you do have to 563 00:29:07,200 --> 00:29:15,360 manually list out all the the template 564 00:29:10,440 --> 00:29:18,120 instantiations that you want but yes 565 00:29:15,360 --> 00:29:18,870 very cool and please join me in thanking 566 00:29:18,120 --> 00:29:20,480 David once again 567 00:29:18,870 --> 00:29:22,430 [Applause] 568 00:29:20,480 --> 00:29:25,359 thank you so much 569 00:29:22,430 --> 00:29:25,359 [Applause]