{"id":437,"date":"2009-09-22T22:46:43","date_gmt":"2009-09-23T05:46:43","guid":{"rendered":"https:\/\/mathpirate.net\/log\/?p=437"},"modified":"2009-09-22T22:46:43","modified_gmt":"2009-09-23T05:46:43","slug":"stop-stand-there-where-you-are-before-you-go-too-far","status":"publish","type":"post","link":"https:\/\/mathpirate.net\/log\/2009\/09\/22\/stop-stand-there-where-you-are-before-you-go-too-far\/","title":{"rendered":"Stop!  Stand there where you are, before you go too far&#8230;"},"content":{"rendered":"<p>I spent some time last night diving back into the world of Lego Mindstorms, trying to solve one of the outstanding problems from the Pong Robot that I built a few weeks ago.\u00c2\u00a0 If you recall, one of the biggest problems I had was with precision movement of the servo that was rotating the paddle knob.\u00c2\u00a0 It would consistently overshoot the mark or simply not move at all.\u00c2\u00a0 This was very frustrating, and I tried several different movement techniques before coming across one that worked well enough&#8230;\u00c2\u00a0 Until I recharged the batteries.<\/p>\n<p>One of the problems I had was that I couldn&#8217;t tell the\u00c2\u00a0motor how far to rotate.\u00c2\u00a0 I had to tell it to turn on, then, sometime later, tell it to stop.\u00c2\u00a0 This meant that processing delay could have been the cause of most of the overshoots.\u00c2\u00a0 By the time the stop message had gotten to the motor, the paddle had gone too far, leading the movement processor to send a command telling the paddle to move the other direction, where it promptly overshot the mark heading in the other direction.\u00c2\u00a0 What I needed was to tell the motor exactly how many degrees to turn.<\/p>\n<p>Now, I tried the degree method before, sort of.\u00c2\u00a0 Unfortunately, I was limited to fixed angles that were set up in the Lego Graphical Program that I wrote (If you can call drag and drop programming &#8220;writing&#8221;&#8230;), so it didn&#8217;t end up working that well.\u00c2\u00a0 In general, it overshot worse using these angles.\u00c2\u00a0 And movements got stacked up in the queue, so it kept moving long after it should have stopped.\u00c2\u00a0 All in all, a failure.<\/p>\n<p>I eventually bypassed the program altogether and moved to using the Mindstorms Direct Command API, which lets you send commands to the NXT over Bluetooth.\u00c2\u00a0 Using Direct Commands, I had slightly more control over when to start and stop, although the primary benefit was turnaround time.\u00c2\u00a0 All of my logic was centralized in the same C# application, rather than being spread between C# and the Lego Graphical Program.\u00c2\u00a0 I could tweak a setting and run and see what it did, rather than drag a couple of program bricks around, redeploy, run the program on the NXT, then run the desktop app, only to find out it didn&#8217;t work at all.\u00c2\u00a0 However, what I didn&#8217;t find was any way to provide a movement angle at all.\u00c2\u00a0 There were all sorts of settings, like power, braking mode, even some used for twin motor locomotion.\u00c2\u00a0 But no &#8220;rotation angle&#8221;.\u00c2\u00a0 So, I made do with simply adjusting the power.\u00c2\u00a0 The &#8220;success&#8221; of the robot was less a factor of going where it was supposed to go than luck in having it correct from its mistakes fast enough to hit the ball.<\/p>\n<p>Obviously, luck wasn&#8217;t going to cut it.\u00c2\u00a0 The robot would perform reasonably at the standard speed, but as soon as you bumped up the speed a notch, it didn&#8217;t stand a chance.\u00c2\u00a0 I could tell that it would have problems if I wanted to expand to games like Breakout, where the speed is variable in normal play, and there was no way that the current movement\u00c2\u00a0would work for\u00c2\u00a0games like Kaboom!, where you have to have pinpoint movement control\u00c2\u00a0and\u00c2\u00a0be thinking\u00c2\u00a0five moves ahead to have any kind of hope of survival.<\/p>\n<p>Yesterday, I decided to look at the problem again.\u00c2\u00a0 In reading what other people had written about the Direct Command API, I discovered that the semi-obscurely named &#8220;Tacho Limit&#8221; parameter that I&#8217;d been ignoring was actually the number of degrees to rotate with the movement command.\u00c2\u00a0 Great!\u00c2\u00a0 That&#8217;s precisely what I needed.\u00c2\u00a0 Except for the minor fact that this Tacho Limit was obeyed like someone on a crotch rocket obeys the speed limit.\u00c2\u00a0 Somewhere around the Tacho Limit the motor would sort of decide to stop moving, but would then coast for another random length of time.\u00c2\u00a0 At full power, this random length of time tended to mean somewhere in the neighborhood of 720 degrees.<\/p>\n<p>Two full revolutions past the mark is not my idea of precise.<\/p>\n<p>And then, on top of that, there&#8217;s a counter in the motor that keeps track of how far you&#8217;ve wanted to go and how far it&#8217;s actually gone and won&#8217;t move again until you&#8217;ve told it to move past where it landed.\u00c2\u00a0 Which means, if you tell it to rotate 360 degrees, and it goes 1080, the motor won&#8217;t go anywhere at all until you&#8217;ve told it to move more than the difference of\u00c2\u00a0720 degrees.\u00c2\u00a0 And then, it only travels the difference over the error. \u00c2\u00a0So, needless to say, quite frequently, I was telling to move and it refused to go anywhere, and when it finally did decide to move, it didn&#8217;t move anywhere near the distance I wanted it to go.<\/p>\n<p>Basically, I would have gotten more precise movement if I&#8217;d handed the paddle to a three-year-old that I&#8217;d pre-loaded with PixyStix.<\/p>\n<p>I don&#8217;t understand it.\u00c2\u00a0 I&#8217;ve seen the motor move fast and stop with such force that the entire assembly shudders.\u00c2\u00a0 Why is it just gradually coasting to a stop now when it should be moving precisely 30 degrees.\u00c2\u00a0 Not 34, not 37.\u00c2\u00a0 30.<\/p>\n<p>I&#8217;m back in the graphical environment now, trying to drag and drop a program that&#8217;ll give me more control over the rotation, but which will hopefully cause the motor to actually stop when it&#8217;s supposed to stop.\u00c2\u00a0 I&#8217;m debugging using a happy face icon and a bunch of sleepy ZZzzzs.\u00c2\u00a0 This is all I will ever be able to think about the next time someone tries to show me a UML diagram.<\/p>\n<p>And speaking of stopping, I really need to stop now, given that I happen to have something that could be described as &#8220;work&#8221; in the morning.\u00c2\u00a0\u00c2\u00a0 Just like the motor overshoot, this could easily continue for another hour or two if I let it.\u00c2\u00a0 \u00c2\u00a0When I&#8217;m\u00c2\u00a0half asleep at the morning meeting, I don&#8217;t think the excuse &#8220;I was playing with Legos all night&#8221; is gonna fly&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I spent some time last night diving back into the world of Lego Mindstorms, trying to solve one of the outstanding problems from the Pong Robot that I built a few weeks ago.\u00c2\u00a0 If you recall, one of the biggest problems I had was with precision movement of the servo that was rotating the paddle [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7],"tags":[14,20,23,237,28],"_links":{"self":[{"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/posts\/437"}],"collection":[{"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/comments?post=437"}],"version-history":[{"count":2,"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/posts\/437\/revisions"}],"predecessor-version":[{"id":439,"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/posts\/437\/revisions\/439"}],"wp:attachment":[{"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/media?parent=437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/categories?post=437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mathpirate.net\/log\/wp-json\/wp\/v2\/tags?post=437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}