ActivityBot -- SIRC control + whiskers
twm47099
Posts: 867
There are sometimes questions about how to combine different lessons in the C-Learning Tutorials. The program below combines ActivityBot using the Sony IR remote control with Navigating by touch.
The hardware setup is the same as in the 2 tutorials. My wiring using the overlay board is here:
http://forums.parallax.com/discussion/comment/1337873/#Comment_1337873
There are 2 potentially tricky changes.
1. Since there is up to 1 second delay if no remote control button is pushed, and we want the response to hitting an object to be immediate, I run the whisker function in its own cog.
.
2. The SIRC command codes are based on my remote control (Sony RMT-DSLR1). If you are using a different remote, use the program in the SIRC tutorial
http://learn.parallax.com/propeller-c-simple-devices/ir-receiver-and-remote
to determine the codes your remote uses for the keys you want to use for each command. Then change the number in the remote control aliases define statements.
Note: that I've added a new version a few posts down that changes the codes to those used in a standard Sony TV remote.
Here's the code:
I hope you enjoy it.
Tom
The hardware setup is the same as in the 2 tutorials. My wiring using the overlay board is here:
http://forums.parallax.com/discussion/comment/1337873/#Comment_1337873
There are 2 potentially tricky changes.
1. Since there is up to 1 second delay if no remote control button is pushed, and we want the response to hitting an object to be immediate, I run the whisker function in its own cog.
.
2. The SIRC command codes are based on my remote control (Sony RMT-DSLR1). If you are using a different remote, use the program in the SIRC tutorial
http://learn.parallax.com/propeller-c-simple-devices/ir-receiver-and-remote
to determine the codes your remote uses for the keys you want to use for each command. Then change the number in the remote control aliases define statements.
Note: that I've added a new version a few posts down that changes the codes to those used in a standard Sony TV remote.
Here's the code:
/* SIRC Remote control new a.c for overlay board This worked - There is no delay between whisker touching and bot stopping. Before using separate cog for whiskers, there was a noticible delay, and whisker fully compressed before bot would stop. This version stops, backs up, turns 90 deg from obstacle and stops. Must press remote key to restart motion. Consider changes to allow continuing motion wo need to press remote key. Use multiple cogs - new cog to handle whiskers Connect 38 kHz IR receiver to Propeller P10 Decodes button presses on Sony-compatible IR remote Commands Activitybot to move straight, pivot 45 deg, move in a curve, increase or decrease speed and curve radius, and stop. Also has whisker code for obstacle avoidance. This has ramping to speed. Increment = 4 ticks per 1/50 sec (4/0.020 sec). To get from 0 to 100 takes 25 increments = 0.5 sec Future: add code for autonomous movement selectable from remote, Load EEProm and Run */ #include "simpletools.h" // Libraries included #include "sirc.h" #include "abdrive.h" // abdrive library // ***** Remote control aliases -- uses Sony camera remote RMT-DSLR1 ***** #define fwd 58 // up arrow -- forward #define stp 57 // center -- stop #define rvs 59 // down arrow -- reverse #define pl 62 // left arrow -- pivot left #define pr 63 // right arrow -- pivot right #define cvl 56 // menu -- curve left #define cvr 61 // trash can -- curve right #define ispd 74 // plus rocker -- increase speed #define dspd 75 // minus rocker -- decrease speed // ***** Pin Defines ***** #define spkrpin 3 // speaker pin for overlay board #define SIRCpin 10 // SIRC input pin #define Rwpin 8 // Right whisker pin #define Lwpin 7 // Left whisker pin int *cogwhisker; // pointers to cog IDs void whisker(); // monitors whiskers, if hit: stops, backs away, turns away, runs in separate cog volatile int bumpflg; int Lspd, Rspd = 0; // Left and Right command wheel speeds int main() // **** main function **** { int spd = 50; // initial speed once fwd command given int dflg = 0; // flag: -1=fwd or rev, 0=stopped, 1=curve left, 2=curve right, 3=pivot L or R drive_speed(0, 0); sirc_setTimeout(1000); // -1 if no remote code in 1 sec bumpflg = 0; // Gives control to remote cogwhisker = cog_run(whisker, 100); // start monitoring whiskers freqout(spkrpin,1000, 3000); // Speaker tone: 1 s, 3 kHz while(1) // Repeat indefinitely { int button = sirc_button(SIRCpin); // get code from SIRC remote switch(button) // decode signal from SIRC and calc drive command { case stp : // Center button - Q Lspd = 0; // stop Rspd = 0; dflg = 0; break; case fwd : // Top Arrow - M Lspd = spd; // forward Rspd = spd; dflg = -1; break; case rvs : // Down Arrow Lspd = -spd; // reverse Rspd = -spd; dflg = -1; break; case pr : // Right Arrow - N Lspd = 13; Rspd = -13; // Pivot Right 45 deg & stop dflg = 3; break; case pl : // Left Arrow - P Lspd = -13; Rspd = 13; // Pivot Left 45 deg & stop dflg = 3; break; case cvr : // Curve Right - L if (spd < 25) spd=25; Lspd = spd; Rspd = spd-20; dflg = 2; break; case cvl : // Curve Left - K if (spd < 25) spd=25; Lspd = spd-20; Rspd = spd; dflg = 1; break; case ispd : // Up-Rocker - H -- Increase speed if (dflg == 1) // curving left - increase spd and move in curve at new spd { spd=spd+5; if (spd > 100) spd = 100; Lspd = spd-20; Rspd = spd; } else if (dflg == 2) // curving right - increase spd and move in curve at new spd { spd=spd+5; if (spd > 100) spd = 100; Lspd = spd; Rspd = spd-20; } else if (dflg == -1) // straight ahead - increase spd and move at new spd { spd=spd+5; if (spd > 100) spd = 100; Lspd = spd; Rspd = spd; } else { spd=spd+5; if (spd > 100) spd = 100; } break; // Finish Up-Rocker case dspd : // Down-Rocker -- decrease spd if (dflg == 1) // curving left - decrease spd and move at new spd { spd=spd-5; if (spd < 25) spd = 25; Lspd = spd-20; Rspd = spd; } else if (dflg == 2) // curving right - decrease spd and move at new spd { spd=spd-5; if (spd < 25) spd = 25; Lspd = spd; Rspd = spd-20; } else if (dflg == -1) // straight ahead - decrease spd and move at new spd { spd=spd-5; if (spd < 0) spd = 0; Lspd = spd; Rspd = spd; } else // stopped { spd=spd-5; if (spd < 0) spd = 0; } break; // Finish Down-Rocker default : break; } // end switch if(dflg == 3) // execute pivot { if( ! bumpflg) drive_ramp(0,0); // stop for pivot, whiskers not controlling movement if( ! bumpflg) // whiskers not controlling movement { drive_ramp(Lspd, Rspd); // now pivot 45 deg pause(1000); Lspd = 0; // and stop, executed with other drive cmds below Rspd = 0; dflg = 0; } } if( ! bumpflg) drive_ramp(Lspd, Rspd); // execute drive comnd, whiskers not cntrling movement } // end while } // end main void whisker() // If whisker pressed, stop & move away from obstacle: // 1. disable SIRC control, 2. stop bot, 3. back up, 4. turn away from obstacle, // 5. stop, 6. restore SIRC control { while(1) { // If whisker pressed, avoid obstacle. // First just right whisker - input(8) is 0 if whisker is pressed if(! input(Rwpin)) { bumpflg = 1; // Set flag so main will not give conflicting drive commands drive_speed(0,0); drive_ramp(-60, -60); // Back up 0.5 seconds pause(500); drive_ramp(0,0); drive_speed(-26, 26); // Turn left 1 seconds -- 90 deg pause(1000); drive_ramp(0, 0); // stop } // Just left whisker - input(7) else if(! input(Lwpin)) { bumpflg = 1; drive_speed(0,0); drive_ramp(-60, -60); // Back up 0.5 seconds pause(500); drive_ramp(0,0); drive_speed(26, -26); // Turn right 1 seconds -- 90 deg pause(1000); drive_ramp(0,0); // stop } bumpflg = 0; // clear flag, allow main to have control } }
I hope you enjoy it.
Tom
Comments
Tom
I just noticed that in the program posted above all of the "<" and ">" operators had been changed to a combination of & lt and ; for < and similar for > probably during one of the forum upgrades.
I've fixed them in the program above.
Tom
1. It now uses a standard Sony TV remote. Previously I was using a Sony DSLR camera remote. The change was made by simply changing the values in the #DEFINE statements.
2. The "whisker" code now uses 'waitpne' instead of looping to check each whisker. waitpne halts the 'whisker' cog until there is a change in either pin that the whiskers are connected to.