{"id":681,"date":"2017-02-06T22:24:42","date_gmt":"2017-02-07T03:24:42","guid":{"rendered":"http:\/\/sunapi386.ca\/wordpress\/?p=681"},"modified":"2017-02-06T22:24:42","modified_gmt":"2017-02-07T03:24:42","slug":"lessons-real-time-programming-class","status":"publish","type":"post","link":"https:\/\/sunapi386.ca\/wordpress\/lessons-real-time-programming-class\/","title":{"rendered":"Lessons from Real-Time Programming class"},"content":{"rendered":"<section class=\"section section--body section--first\">\n<div class=\"section-content\">\n<div class=\"section-inner sectionLayout--insetColumn\">\n<h1 id=\"f490\" class=\"graf graf--h3 graf--leading graf--title\">Lessons from Real-Time Programming class<\/h1>\n<p id=\"4005\" class=\"graf graf--p graf-after--h3\">This post is about lessons I learnt in <a class=\"markup--anchor markup--p-anchor\" href=\"http:\/\/www.cgl.uwaterloo.ca\/~wmcowan\/teaching\/cs452\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"http:\/\/www.cgl.uwaterloo.ca\/~wmcowan\/teaching\/cs452\">CS452 Real-Time Programming<\/a>, a 4th year undergraduate class at the University of Waterloo. Better known as \u201ctrains\u201d or \u201crealtime\u201d class.<\/p>\n<blockquote id=\"14d7\" class=\"graf graf--blockquote graf--startsWithDoubleQuote graf-after--p\"><p>\u201cEasy stuff! You play with trains all day (literally, maybe even night). All you need to do is write one simple program to control multiple trains so they don\u2019t crash!\u201d<\/p><\/blockquote>\n<blockquote id=\"e50b\" class=\"graf graf--blockquote graf-after--blockquote\"><p>\u2014 chko on <a class=\"markup--anchor markup--blockquote-anchor\" href=\"https:\/\/birdcourses.com\/course.php?courseid=144\" target=\"_blank\" rel=\"noopener nofollow\" data-href=\"https:\/\/birdcourses.com\/course.php?courseid=144\">BirdCourses.com<\/a><\/p><\/blockquote>\n<figure id=\"fe0a\" class=\"graf graf--figure graf-after--blockquote\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*gaxGu5bLYzy5u_4ZS4a2uw.jpeg\" data-width=\"1701\" data-height=\"1276\" data-action=\"zoom\" data-action-value=\"1*gaxGu5bLYzy5u_4ZS4a2uw.jpeg\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"56\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*gaxGu5bLYzy5u_4ZS4a2uw.jpeg\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*gaxGu5bLYzy5u_4ZS4a2uw.jpeg\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">The trains lab. Room 3018, 3rd floor Math &amp; Computer building.<\/figcaption><\/figure>\n<p id=\"8f8f\" class=\"graf graf--p graf-after--figure\">The class is a bit unconventional because it indirectly teaches other topics, like time management and teamwork, by providing a large amount of work\u200a\u2014\u200aso that you have to learn these skills. I\u2019ll talk about these lessons, hoping to address a more general audience.<\/p>\n<h3 id=\"8577\" class=\"graf graf--h3 graf-after--p\">History<\/h3>\n<p id=\"d94d\" class=\"graf graf--p graf-after--h3\">This class has been around since at least the 80\u2019s. Currently <a class=\"markup--anchor markup--p-anchor\" href=\"http:\/\/www.cgl.uwaterloo.ca\/wmcowan\/index.html\" target=\"_blank\" rel=\"noopener nofollow\" data-href=\"http:\/\/www.cgl.uwaterloo.ca\/wmcowan\/index.html\">Bill Cowan<\/a>teaches this class, and has been for over 20 years.<\/p>\n<p id=\"c504\" class=\"graf graf--p graf-after--p\"><em class=\"markup--em markup--p-em\">The equipment have evolved since then, but the underlying challenges have not.<\/em><\/p>\n<p id=\"c7d0\" class=\"graf graf--p graf-after--p\">For example, teamwork, setting priorities, and dealing with real (imperfect) systems.<\/p>\n<figure id=\"a509\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*Fxb_Ko7T3ilA4U2uVacVRw.jpeg\" data-width=\"1247\" data-height=\"654\" data-action=\"zoom\" data-action-value=\"1*Fxb_Ko7T3ilA4U2uVacVRw.jpeg\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"39\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*Fxb_Ko7T3ilA4U2uVacVRw.jpeg\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*Fxb_Ko7T3ilA4U2uVacVRw.jpeg\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">Prof. Bill Cowan explains the why sensor pickup sometimes have trouble detecting slow moving trains. The gap between the contact points may cause the pickup switch to flip\u00a0twice.<\/figcaption><\/figure>\n<p id=\"1523\" class=\"graf graf--p graf-after--figure\">The early version of the <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/en.wikipedia.org\/wiki\/QNX\" target=\"_blank\" rel=\"noopener nofollow\" data-href=\"https:\/\/en.wikipedia.org\/wiki\/QNX\">QNX real-time operating system<\/a> took off from a pair of students taking this class, Gordon Bell and Dan Dodge. They decided to <a class=\"markup--anchor markup--p-anchor\" href=\"http:\/\/www.qnx.com\/developers\/docs\/660\/index.jsp?topic=%2Fcom.qnx.doc.neutrino.getting_started%2Ftopic%2Fpreface_History.html\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"http:\/\/www.qnx.com\/developers\/docs\/660\/index.jsp?topic=%2Fcom.qnx.doc.neutrino.getting_started%2Ftopic%2Fpreface_History.html\">expand the class project into a full-fledged commercial RTOS<\/a> (real time operating system).<\/p>\n<blockquote id=\"ddc9\" class=\"graf graf--blockquote graf--startsWithDoubleQuote graf-after--p\"><p>\u201cYou should try to find a partner for this class, it\u2019ll be hard without one. Generally I\u2019ve seen two outcomes:<br \/>\n(1) you become friends with your partner, or<br \/>\n(2) you stop being friends and hate each other.<br \/>\nI recommend not starting with a partner who is your friend, because you are already friends. Don\u2019t risk it.\u201d<\/p><\/blockquote>\n<blockquote id=\"ab8a\" class=\"graf graf--blockquote graf-after--blockquote\"><p>\u2014 Prof. Bill Cowan<\/p><\/blockquote>\n<h4 id=\"da30\" class=\"graf graf--h4 graf-after--blockquote\">Curriculum<\/h4>\n<p id=\"689f\" class=\"graf graf--p graf-after--h4\">About 65% of the class involves building a small embedded kernel, with the other 35% working on the train management application.<\/p>\n<p id=\"7323\" class=\"graf graf--p graf-after--p\">You can choose to program in whatever language you want, because there aren\u2019t any standard libraries provided. People generally program in C, because it\u2019s known as a systems language, and the programming examples given in class. But there\u2019s no reason why you can\u2019t do it in Rust language, for example\u200a\u2014\u200aalthough godspeed, you\u2019re venturing into uncharted territory!<\/p>\n<p id=\"990d\" class=\"graf graf--p graf-after--p\">The kernel runs on a <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/www.embeddedarm.com\/products\/TS-7200\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"https:\/\/www.embeddedarm.com\/products\/TS-7200\">TS-7200 embedded system<\/a>, and it talks to a <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/www.student.cs.uwaterloo.ca\/~cs452\/manual\/trains.html\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"https:\/\/www.student.cs.uwaterloo.ca\/~cs452\/manual\/trains.html\">M\u00e4rklin Train System<\/a> over RS232 type serial. The firmware is loaded on via <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/sourceware.org\/redboot\/\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"https:\/\/sourceware.org\/redboot\/\">RedBoot<\/a>, a bootstrap environment for embedded systems.<\/p>\n<figure id=\"a0cd\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*YAnG6Y1Nzgabz3-xiEE3gQ.jpeg\" data-width=\"2309\" data-height=\"1732\" data-action=\"zoom\" data-action-value=\"1*YAnG6Y1Nzgabz3-xiEE3gQ.jpeg\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"56\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*YAnG6Y1Nzgabz3-xiEE3gQ.jpeg\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*YAnG6Y1Nzgabz3-xiEE3gQ.jpeg\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">The <a class=\"markup--anchor markup--figure-anchor\" href=\"https:\/\/www.student.cs.uwaterloo.ca\/~cs452\/manual\/trains.html\" target=\"_blank\" rel=\"noopener nofollow\" data-href=\"https:\/\/www.student.cs.uwaterloo.ca\/~cs452\/manual\/trains.html\">M\u00e4rklin Train System<\/a>. You can see the center console where the RS232 is attached. Off to the right is the grey box that houses the\u00a0TS-7200.<\/figcaption><\/figure>\n<p id=\"afdf\" class=\"graf graf--p graf-after--figure\">The final exam is a take home 24 hour long exam, where you can use any resources you want, and you only need to do 3 of the 5 questions. The assignments and kernel make up 70% of the grade.<\/p>\n<h4 id=\"f108\" class=\"graf graf--h4 graf-after--p\">Optional Technical Info<\/h4>\n<p id=\"12bc\" class=\"graf graf--p graf-after--h4\">The microkernel did very little; it<\/p>\n<ul class=\"postList\">\n<li id=\"77d7\" class=\"graf graf--li graf-after--p\">only kickstarts a couple of initial processes.<\/li>\n<li id=\"8633\" class=\"graf graf--li graf-after--li\">handled message passing between processes.<\/li>\n<li id=\"dff9\" class=\"graf graf--li graf-after--li\">provided very basic interrupt handler and clock.<\/li>\n<li id=\"1941\" class=\"graf graf--li graf-after--li\">supports realtime operations; the scheduler is predictable (through priorities, and pre-emption).<\/li>\n<li id=\"aada\" class=\"graf graf--li graf-after--li\">avoided disk IO by loading kernel and programs into RAM directly.<\/li>\n<li id=\"0b9b\" class=\"graf graf--li graf-after--li\">needed to provide serial output to a PC terminal, to display graphics relating to the real-time actions being controlled, such as displaying position of trains on the track showing movement.<\/li>\n<\/ul>\n<p id=\"f808\" class=\"graf graf--p graf-after--li graf--last\">The realtime program is probably more work than the kernel. Because initially there were many constraints, but later on, assignments were of more guidelines than objectives.<\/p>\n<\/div>\n<\/div>\n<\/section>\n<section class=\"section section--body section--last\">\n<div class=\"section-divider\">\n<hr class=\"section-divider\" \/>\n<\/div>\n<div class=\"section-content\">\n<div class=\"section-inner sectionLayout--insetColumn\">\n<h3 id=\"5712\" class=\"graf graf--h3 graf--leading\">Lessons<\/h3>\n<p id=\"0806\" class=\"graf graf--p graf-after--h3\">I\u2019ll talk about some of the lessons I learnt, and provide some reasoning or backstory to them.<\/p>\n<h4 id=\"7956\" class=\"graf graf--h4 graf-after--p\">Don\u2019t trust anything. Don\u2019t make any assumptions.<\/h4>\n<p id=\"cf4a\" class=\"graf graf--p graf-after--h4\">One assumption that was made was while building a acceleration and deceleration profile for the train\u200a\u2014\u200athat the train would stop where we expected to. Calibration was done by running the train at full speed around the tracks, and when it hits a sensor, tell it to stop.<\/p>\n<p id=\"fab1\" class=\"graf graf--p graf-after--p\">That assumption turned out false: at max speed, the train varies its stopping distance quite a bit, up to \u00b13 cm. Not only that, the train accelerates and decelerates non-linearly!<\/p>\n<figure id=\"c6ba\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*kVf9s0MoRdLr7rlr3YDkfQ.jpeg\" data-width=\"2309\" data-height=\"1732\" data-action=\"zoom\" data-action-value=\"1*kVf9s0MoRdLr7rlr3YDkfQ.jpeg\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"56\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*kVf9s0MoRdLr7rlr3YDkfQ.jpeg\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*kVf9s0MoRdLr7rlr3YDkfQ.jpeg\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">Real systems are often imprecise. For example, look at the stopping distance of a train. In our experiments, it never stops in the same place\u200a\u2014\u200afor a variety of reasons: such as buffering, interrupt handling, incorrect system\u00a0timing.<\/figcaption><\/figure>\n<p id=\"31d3\" class=\"graf graf--p graf-after--figure\">This meant that over the course of several start and stop move commands, there can accumulate quite a difference between where you <em class=\"markup--em markup--p-em\">think<\/em> the train is, and where it <em class=\"markup--em markup--p-em\">actually<\/em> is.<\/p>\n<p id=\"8747\" class=\"graf graf--p graf-after--p\">Consequently, our model couldn\u2019t be trusted. We\u2019d assume it was safe to perform a certain operation, and it of course, wouldn\u2019t be. And that causes accidents like multi-track drifting to occur.<\/p>\n<figure id=\"f82a\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*KqvqmDz_al4zmcAQ9sNXMA.jpeg\" data-width=\"2309\" data-height=\"1732\" data-action=\"zoom\" data-action-value=\"1*KqvqmDz_al4zmcAQ9sNXMA.jpeg\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"56\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*KqvqmDz_al4zmcAQ9sNXMA.jpeg\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*KqvqmDz_al4zmcAQ9sNXMA.jpeg\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">Multi-track drifting. Happens when a track switch flips direction while the train has yet to clear both\u00a0axles.<\/figcaption><\/figure>\n<p id=\"df56\" class=\"graf graf--p graf-after--figure\"><a class=\"markup--anchor markup--p-anchor\" href=\"http:\/\/knowyourmeme.com\/memes\/multi-track-drifting\" target=\"_blank\" rel=\"noopener nofollow\" data-href=\"http:\/\/knowyourmeme.com\/memes\/multi-track-drifting\">Multi-track<\/a> drifting is when you thought it was safe to flip a switch, and then it wasn\u2019t. The poor train comes to a sudden stop because the front axles and rear axles are going to different directions.<\/p>\n<p id=\"5d3a\" class=\"graf graf--p graf-after--p\">When your model of the world and the real world itself are different, you get problems. We couldn\u2019t trust our model. We\u2019d assume it was safe to perform a certain operation, thinking we knew where the train was, and it wasn\u2019t safe.<\/p>\n<p id=\"c9b9\" class=\"graf graf--p graf-after--p\">This explains the comic that is pasted on the walls beside the train set. Now I get it!<\/p>\n<figure id=\"eefa\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*iD5f7uqzhqCx_sED5B5G7A.png\" data-width=\"1353\" data-height=\"976\" data-action=\"zoom\" data-action-value=\"1*iD5f7uqzhqCx_sED5B5G7A.png\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"53\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*iD5f7uqzhqCx_sED5B5G7A.png\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*iD5f7uqzhqCx_sED5B5G7A.png\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">A printed out version of this comic was taped to the wall beside the train tracks. The original multi-track drifting.<\/figcaption><\/figure>\n<p id=\"4e38\" class=\"graf graf--p graf-after--figure\">If this was a real train, this would result it some serious accidents. A lesson we learnt after trying to figure out how this happened.<\/p>\n<p id=\"8737\" class=\"graf graf--p graf-after--p\"><em class=\"markup--em markup--p-em\">Assumptions are going to be wrong! So it\u2019s important to build in error correction and recovery.<\/em><\/p>\n<p id=\"87db\" class=\"graf graf--p graf-after--p\">Often assumptions are wrong, or become wrong during the course of real life usage. Real systems don\u2019t always run in your ideal situations. You can\u2019t always think of all the edge-cases. Errors are going to happen. Your best chance is to try to realize the error as early as possible and correct for it.<\/p>\n<p id=\"4dde\" class=\"graf graf--p graf-after--p\">Instead of eagerly switching tracks for the next train, we switched tracks only if the train had ownership of the track.<\/p>\n<figure id=\"1227\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*jWZ66KYCz7qox4P-2u-t4Q.jpeg\" data-width=\"2284\" data-height=\"1750\" data-action=\"zoom\" data-action-value=\"1*jWZ66KYCz7qox4P-2u-t4Q.jpeg\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"56\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*jWZ66KYCz7qox4P-2u-t4Q.jpeg\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*jWZ66KYCz7qox4P-2u-t4Q.jpeg\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">Map of the train switches and segments. We had two tracks, A and B, and they have different configurations. We hard coded the map to build the train track reservation system.<\/figcaption><\/figure>\n<p id=\"bdbe\" class=\"graf graf--p graf-after--figure\">To solve this, we ended up building in margin of error around where we think the train is, assigned the train to have ownership to tracks, and made sure when trains approach tracks that they didn\u2019t own, it would stop.<\/p>\n<h4 id=\"7a76\" class=\"graf graf--h4 graf-after--p\">You are as only good as your\u00a0tools.<\/h4>\n<p id=\"9bab\" class=\"graf graf--p graf-after--h4\">Building the path\/route finding portion of the project, we were manually reading a map and trying to reason about what the shortest ways were. This took a long time, and felt complicated.<\/p>\n<p id=\"c23a\" class=\"graf graf--p graf-after--p\">Route a train from point <em class=\"markup--em markup--p-em\">A<\/em> to point <em class=\"markup--em markup--p-em\">B <\/em>was not difficult, but factoring in what paths are currently, or will be, blocked by other trains made it harder. We often stared at the layout map for a long time, trying to figure out whether this was the quickest path through this or not.<\/p>\n<figure id=\"436d\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*nlK8hZTX3uooqq93h_5eeQ.png\" data-width=\"2350\" data-height=\"1640\" data-action=\"zoom\" data-action-value=\"1*nlK8hZTX3uooqq93h_5eeQ.png\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"51\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*nlK8hZTX3uooqq93h_5eeQ.png\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*nlK8hZTX3uooqq93h_5eeQ.png\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">This is the track layout map. It\u2019s easy to find the shortest path visually, for one train. Now try imagine putting more trains on here. After two trains, becomes pretty difficult. Trains probably need to negotiate with each other, and it\u2019s not enough to try to all take the shortest\u00a0path.<\/figcaption><\/figure>\n<p id=\"4853\" class=\"graf graf--p graf-after--figure\">After staring at this for a long time, and it was clear that reading a map like felt a lot of work. Time to make our life easier.<\/p>\n<figure id=\"f449\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*srm7EnePDo3YMjDz4ITisw.png\" data-width=\"2606\" data-height=\"1622\" data-action=\"zoom\" data-action-value=\"1*srm7EnePDo3YMjDz4ITisw.png\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"45\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*srm7EnePDo3YMjDz4ITisw.png\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*srm7EnePDo3YMjDz4ITisw.png\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">This map contains the same information as the track layout map, but represented as a tree. This way, we can easily figure out what were shortest paths by counting the least number of moves. This tree factored in backwards movements as well. Because point A and point B may be most easily reached by reversing direction.<\/figcaption><\/figure>\n<p id=\"e8bb\" class=\"graf graf--p graf-after--figure\">This tree map didn\u2019t take much more effort, it was generated by <a class=\"markup--anchor markup--p-anchor\" href=\"http:\/\/www.graphviz.org\/content\/dot-language\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"http:\/\/www.graphviz.org\/content\/dot-language\">GraphViz in the Dot language<\/a>.<\/p>\n<p id=\"2a62\" class=\"graf graf--p graf-after--p\">Tools empower you to be more productive. As a programmer, you\u2019re always thinking about how to make things automated, and easier. A commonly seen trait that programmers have is to be lazy, a desire to automate things and make their own lives easier. Determine how much time you spent doing some work, and see if you can build a tool to make it easier.<\/p>\n<p id=\"3b90\" class=\"graf graf--p graf-after--p\"><em class=\"markup--em markup--p-em\">Invest in building better tools when you find yourself repeating a task, as a rule of thumb, more than three times.<\/em><\/p>\n<h4 id=\"ce13\" class=\"graf graf--h4 graf-after--p\">It\u2019s ok to take on technical debt. Keep it simple,\u00a0stupid.\u2122<\/h4>\n<p id=\"d0e0\" class=\"graf graf--p graf-after--h4\">For example, having fancy colorful terminals. Ours was initially very pretty, but we noticed a lot of things had to be changed. Towards the end of the projects, we had avoided building fancy graphics because they took a lot of work and are likely to be changed later.<\/p>\n<p id=\"c1b8\" class=\"graf graf--p graf-after--p\">If you wanted to have pretty looking terminals, lot of time had to be dedicated for it. If you\u2019re really bored, and have time to kill, I suppose it\u2019s fine.<\/p>\n<figure id=\"ef79\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*c7eRIxb9AMiywKiAUCVUXA.jpeg\" data-width=\"2309\" data-height=\"1732\" data-action=\"zoom\" data-action-value=\"1*c7eRIxb9AMiywKiAUCVUXA.jpeg\" data-scroll=\"native\"><canvas class=\"progressiveMedia-canvas js-progressiveMedia-canvas\" width=\"75\" height=\"56\"><\/canvas><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*c7eRIxb9AMiywKiAUCVUXA.jpeg\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1280\/1*c7eRIxb9AMiywKiAUCVUXA.jpeg\" \/><\/div>\n<\/div><figcaption class=\"imageCaption\">Our colorful terminal. It was all pretty, initially. Later on, we couldn\u2019t afford much time to make things look\u00a0good.<\/figcaption><\/figure>\n<p id=\"c8d3\" class=\"graf graf--p graf-after--figure\">Later on, we took on more technical debts with screen drawing. It no longer looked as nice, but it worked.<\/p>\n<p id=\"c424\" class=\"graf graf--p graf-after--p\"><em class=\"markup--em markup--p-em\">If there are technical debts with higher priority, they should be addressed before diving into a lesser problem.<\/em><\/p>\n<p id=\"5779\" class=\"graf graf--p graf-after--p\">This sounds intuitive, but sometimes people become irrational and just spend time on low priority issues. Like making things look pretty.<\/p>\n<h4 id=\"e05d\" class=\"graf graf--h4 graf-after--p\">Pair programming is effective teamworking.<\/h4>\n<p id=\"9882\" class=\"graf graf--p graf-after--h4\">Initially we dividing up projects, and mostly worked separately. This was okay for well-defined problems, as it was the case for initial kernel implementation. But later on, the problems we needed to solve became so inter-dependent that it was no longer feasible to build something in the dark.<\/p>\n<p id=\"49f1\" class=\"graf graf--p graf-after--p\">Many quick idea iterations were needed, and we needed each other to bounce ideas around. Having a comfy couch is important!<\/p>\n<p id=\"48b7\" class=\"graf graf--p graf-after--p\">And towards the end, we were doing pair programming out of despair; we had to write working code, and we had to write it fast.<\/p>\n<p id=\"f350\" class=\"graf graf--p graf-after--p\"><em class=\"markup--em markup--p-em\">Pair programming produces quality code that is better thought out, and a rate that is comparable, if not faster, to separating out tasks and doing code reviews.<\/em><\/p>\n<h3 id=\"a325\" class=\"graf graf--h3 graf-after--p\">Summary<\/h3>\n<p id=\"a60a\" class=\"graf graf--p graf-after--h3\">I think taking this class was very valuable, and was a very nice way to wrap up my Computer Science undergrad.<\/p>\n<p id=\"57e4\" class=\"graf graf--p graf-after--p\">These lessons are ingrained in my memories, and helped shape my behavior.<\/p>\n<p id=\"373f\" class=\"graf graf--p graf-after--p\">For example, after pair programming, I subconsciously debate about solutions to problems and bounce ideas around. To an outsider, it may seem argumentative, but it\u2019s really an effective way to solve problems.<\/p>\n<p id=\"1d12\" class=\"graf graf--p graf-after--p graf--last\">Thank you for reading.<\/p>\n<\/div>\n<\/div>\n<\/section>\n","protected":false},"excerpt":{"rendered":"<p>Lessons from Real-Time Programming class This post is about lessons I learnt in CS452 Real-Time Programming, a 4th year undergraduate class at the University of Waterloo. Better known as \u201ctrains\u201d or \u201crealtime\u201d class. \u201cEasy stuff! You play with trains all day (literally, maybe even night). All you need to do is write one simple program &hellip; <a href=\"https:\/\/sunapi386.ca\/wordpress\/lessons-real-time-programming-class\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Lessons from Real-Time Programming class<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34],"tags":[],"class_list":["post-681","post","type-post","status-publish","format-standard","hentry","category-thoughts"],"_links":{"self":[{"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/posts\/681","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/comments?post=681"}],"version-history":[{"count":1,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/posts\/681\/revisions"}],"predecessor-version":[{"id":682,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/posts\/681\/revisions\/682"}],"wp:attachment":[{"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/media?parent=681"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/categories?post=681"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sunapi386.ca\/wordpress\/wp-json\/wp\/v2\/tags?post=681"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}