Shop OBEX P1 Docs P2 Docs Learn Events
Blockly - ActivityBot with whiskers and SIRC TV remote — Parallax Forums

Blockly - ActivityBot with whiskers and SIRC TV remote

Since Blockly was announced, one thing I wanted to do was to compare it for writing a more complex program using C and SampleIDE. I decided to rewrite my C program for controlling the ActivityBot using a SIRC TV remote and whiskers for reacting to obstacles.

My SimpelIDE C program is here: forums.parallax.com/discussion/comment/1399840/#Comment_1399840

There were a few changes between the 2 versions, some due to some Prop C features not being included in Blockly and some to change the Bot user interface.

Blockly doesn’t have Switch/case (requiring a long sequence of “else-if”s), and it doesn’t have the Propeller.h features including “waitpne” that I use as part of the whisker detection function.

The change I made was to eliminate using the TV remotes volume +/- for changing the Bot’s speed, instead just using the numeric keypad. (the 2 key for increasing speed, 8 for decreasing).

All the changes were easy to make and the program was quickly developed using my procedure notes for the program that I had written when originally writing the C program (with new changes for the different remote commands for speed change.)

The Blockly code is shown in the attachments. Main() and the whisker detection function in “blockly-abot-tv-main-whisker.pdf” and the function to calculate the adbot drive_speed values in 2 files “blocky-abot-tv-calcmove2a.pdf” and “blocky-abot-tv-calcmove2b.pdf”.

The Blockly project itself is located at: http://blockly.parallax.com/blockly/editor/blocklyc.jsp?project=3931

You do have to login.

Having the Blockly editor/compiler on line was nice since I could access it from any of my computers.

Building the large Blockly program took some effort managing all the blocks. Because of the large number of similar blocks that I used, I had a lot of duplicated blocks and groups of blocks scattered over the worksheet, which required some care to make sure that I deleted all the unused ones.

Since the calcmove function was so long, and one of the conditional blocks in “whisker” was so wide, it took some effort to position the different sections so they didn’t interfere with each other.

The only problem I had was in figuring out how to use the “if-do” block to add “else-if”. The interactive “help” did say that the else or else-if conditionals can be added, but it took some searching in the “community” projects to find one that showed how to do it. A sentence should be added to the reference for if-do that explains that the else-if is added to the if-do image in the small box that opens when clicking on the “gear”.

Another issue is printing the blocks in a large program. Downloading the blocks file results in an SVG file. The file opens in a web browser, but doesn’t fully print out, which is why it took 2 files to hold the calcmove function listing.

I’m not sure if Blockly is intended for making large programs, but it does work.

Comments

  • Nicely done. Programs like this one will really help us make future decisions about the Blockly design.

    I see you put the "check whiskers" into a new processor block.

    I was wondering if it would also make a tidy, small program to put the robot drive blocks in their own processor and simply write to the variables at specific locations in the program. This may not reduce the code space. Perhaps if we had a multi-variable assignment block that could place the assignments on the same line?

    Not sure. Matt Matz or Andy Lindsay may see this post and have some valuable suggestions.

    In any case, nice work!
  • Oh, and gotcha on the gear icon for IF-ELSE. We'll improve the Help file with that suggestion.

    Thanks! Ken Gracey
  • David BetzDavid Betz Posts: 14,511
    edited 2017-02-28 12:01
    (deleted)
  • Ken,
    Originally, in my first SimpleIDE version, I had "whiskers" simply as a function in the same processor as "main". But even with a lot of calls to whiskers scattered in main, the delay from the whisker hitting an object to stopping the bot was too long. The bot would ride up on the object. So I learned how to use a new cog, which resulted in almost instantaneous reaction.
    The next step was using "bumpflg" to prevent contention between the drive commands issued by whiskers with those from using the remote while whisker was active.

    One thing that bothers me is the long chain of if-then-elses in the calcmove function. The use of switch/case in SimpleIDE cleans it up a little, but I wonder if there isn't a better way to define the wheel commands. I have to work on that.

    Something I forgot to clean up - in the 2b calcmove file, the second line tests if dflg is between 0 and 2, and a few lines below that tests for dflg between 1 and 3. I was having problems with the curve commands. If button 1 is pressed and the bot was running straight, it should start to curve left. If button 3 is then pressed, the bot should straighten out. If button 3 is again pressed, the bot should curve right. The program knows if the bot is curving in a certain direction by the value of dflg (1 is curving left, 2 = right, -1= straight.) The problem was that the actual response to the curve commands was inconsistent. Many times if the bot was curving, pressing the opposite curve button would not result in the bot going straight. It would just curve in the other direction. I thought (incorrectly) that using the > and < test would prevent the problem. It didn't. The problem was that if the button was pressed and released too slowly, that the program received multiple commands (the first straightened and the second curved in the opposite direction.) The solution was to add the pause at the end of "main". I should change the conditionals to "if dflg == 1" and "if dflg == 2". (But it doesn't affect the operation of the program.)

    Tom
  • I think using dflg as -1 for left, 0 for straight and +1 for right would make more sense to me, it allows for simple adding or subtracting 1 for each button. Could even range from -2 to +2 without much work then.

    That multiple commands come from a (to long) button press can be a feature. Maybe just add some delay when passing from left over straight to right or the other way around.

    Enjoy!

    Mike
  • msrobots wrote: »
    I think using dflg as -1 for left, 0 for straight and +1 for right would make more sense to me, it allows for simple adding or subtracting 1 for each button. Could even range from -2 to +2 without much work then.

    That multiple commands come from a (to long) button press can be a feature. Maybe just add some delay when passing from left over straight to right or the other way around.

    Enjoy!

    Mike

    The values I use for dflg are a holdover from the first version I wrote in C. (The blockly version is my 5th or 6th version of the program.) I was using a zero, positive, or negative test for some reason that I no longer recall.

    I was also using a camera remote rather than a TV remote, and that had codes that were not in a tight sequence like the TV remote number pad ones are.

    If I was starting over, since the codes I'm now using range from 1 to 8, I would probably try using the code number as the index to elements in arrays for DeltaLspd and DeltaRspd, with each element being the +/- value to add to the current Lspd and Rspd. That would need some different logic, but could be a lot more concise. I might give that a try.

    Regarding the use of multiple commands from a long button press. The delay at the end of the main() loop is only 50ms. That is long enough for me (others might need a longer delay) that I can get consistent curve command and pivot command operation. However, I can also hold the #2 button and get rapid speed increase or the #8 button and get rapid speed decrease as the fwd and rvs commands are repeated.

    Tom
  • twm47099 wrote: »
    One thing that bothers me is the long chain of if-then-elses in the calcmove function. The use of switch/case in SimpleIDE cleans it up a little, but I wonder if there isn't a better way to define the wheel commands. I have to work on that.
    Tom

    What if we had a CASE statement in Blockly? I'm working with a similar problem where I'll be evaluating a number of clarinet frequencies to match them with their note. In this project I'll have 30+ note possibilities to consider.

    Ken Gracey
  • I have mixed feelings about switch/case in Blockly. It would certainly be useful to replace a long string of else/if's, and since the syntax for switch/case (where to put curly brackets and ";") can be confusing, it would be a good addition. But would it be too advanced for the intend users? It does show another programming tool.

    The blocks representation wording would be important. I'm no good at naming these things, but should it be something like "choose" for switch with a variable and "choice" for case: with space for a constant, and "leave" for break?

    Even with case, 30+ choices is going to take a lot of blockly space.

    Tom


  • Yes, you're right Tom. These are the kinds of decisions we go through in considering block design and use. We've been using common programming terms where possible, often choosing C or BASIC types of names in our blocks. You might notice that we have a "new processor" block instead of "cognew" for example. I think CASE...SELECT would still make a nice Block.

    Matt Matz has been coding most of these blocks and Jim is working on the infrastructure improvements. A CASE block would be what's called a mutating block in Blockly. We're going to put it on our GitHub issue tracker just to stay aware of it as requests develop.

    Ken Gracey
  • Last night I tried doing a quick & dirty conversion of a C program I had written for the EMIC2 text -to- speech board to Blockly.

    The C version is here: forums.parallax.com/discussion/163425/emic2-text-to-speech-demo-in-c-for-the-propeller

    It didn't compile. There were a lot or errors. I'm still trying to figure them out but most had to do with text and character variables. In the SimpleIDE version, I can declare string variables to be a certain length (let's say 80 characters) and then store different text (of lengths less than that declared) in the variable as needed. I don't see a way to do that in Blockly except by actually using a text block containing an 80 character string.

    I've got to try a few things with text and serial Tx/Rx and see how Blockly translates them into C.

    Another "feature" to add to Blockly, although it may not be appropriate for the intended user, is numeric arrays.

    Tom
  • Good evening,

    First, thanks for working through both the whisker/SIRC example and the EMIC. I'll dive into the EMIC example and see if I can figure out what's going on. I was able to draft a SWITCH/CASE block and that should go into demo soon, and then once it's verified, it will go into the public site - in a week or two.

    It may also help to know that we will be supporting Arrays and binary pin reading/setting as well - those should both help your project, too.
  • Okay - I just checked your EMIC code. It should work fine, but there is a bug in the "integer to string" block. I submitted a fix, so that will go in on the next push.

    Thanks for catching it!
Sign In or Register to comment.