Skip to content

Commit

Permalink
Merge pull request #195 from kipr/waitForLightRevert
Browse files Browse the repository at this point in the history
Reverting back to green bar with red dot for wait_for_light
  • Loading branch information
tcorbly authored Jun 11, 2024
2 parents 11343e7 + 63e34be commit 2e3c6a0
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 119 deletions.
2 changes: 1 addition & 1 deletion module/botball/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
option(with_botball "Enable botball API" ON)

if(with_botball)
add_module(botball core thread analog button console time)
add_module(botball core thread analog button console graphics time)
endif()
246 changes: 128 additions & 118 deletions module/botball/src/botball_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#include "kipr/button/button.h"
#include "kipr/analog/analog.h"
#include "kipr/console/console.h"

#include <kipr/console/display.h>
#include "kipr/graphics/graphics.h"
#include "kipr/graphics/graphics_characters.h"
#include <stdio.h>
#include <string.h>
#include <kipr/time/time.h>
Expand All @@ -23,150 +25,158 @@ class ShutDownIn : public kipr::thread::Thread
{
public:
ShutDownIn(double s)
: m_s(s)
: m_s(s)
{
}

~ShutDownIn()
{
}

virtual void run()
{
const double start = seconds();
msleep(m_s * 1000.0);
const double end = seconds();
std::cout << std::endl << "Shutdown after " << (end - start) << " seconds" << std::endl;
// Note: Might want to move this to botui in the future.
//Create::instance()->stop();
// Create::instance()->stop();
kipr::core::cleanup(true);
_exit(0);
}

private:
double m_s;
};

void shut_down_in(double s)
{
static ShutDownIn *s_instance;
if(s_instance) {
if (s_instance)
{
std::cout << "Warning: shut_down_in already called once. Ignoring." << std::endl;
return;
}
s_instance = new ShutDownIn(s);
s_instance->start();
}


//Waits for the light to shine on the light sensor.
//Ignores camera flashes
//Zachary Sasser - zsasser@kipr.org

void wait_for_light(int port)
// Waits for the light to shine on the light sensor.
// Ignores camera flashes
// Zachary Sasser - zsasser@kipr.org

// Rework of Wallaby version of wait_for_light to work with the Wombat KRC
// cnw: 8/15/2019
#define FLASHPAUSE 100 // msecs to pause to let a flash subside
/* Assumption is that if light is detected by consecutive readings FLASHPAUSE apart,
it's the start light, not a flash
NOTE: when tested with camera, the flash persisted < 0.1 sec
*/
#define THRESHOLD 60 // minimum discrimination between light and dark
#define RED 255, 0, 0
#define GREEN 0, 255, 0
#define WHITE 255, 255, 255
#define BLACK 0, 0, 0
#define CROWS 200 // Cylon window dimensions
#define CCOLS 500
#define INSET 100 // how much to inset Cylon eye
#define DJUMP 2 // how far to jump to next red circle - affects speed of red circle
void colorbar(int i, int range);
void wait_for_light(int light_port)
{
int badDifference = 100; //The standard for what is too close for the light values

while(1>0){

while(any_button()){} //Debounce

while(!any_button()){

printf("Turn on light and press button... \n");
printf("Light ON Value: %d <---- \n", analog(port));
printf(" |=| \n");
printf(" / \\ \n");
printf("--- ( ) --- \n");
printf(" , `-'. \n");
printf(" / | \\ \n");
printf(" ' | ` \n");

if(any_button()){ break; } //Makes the button more responsive

msleep(200);
console_clear(); //For refreshing the values

}

int initial = analog(port); //Set Light ON Value

while(any_button()){} //Debounce

while(!any_button()){
printf("Turn off light and press button... \n \n");
printf("Light ON Value: %d \n", initial);
printf("Light OFF Value: %d <---- \n", analog(port));
printf(" |=| \n");
printf(" / \\ \n");
printf(" ( ) \n");
printf(" `-' \n");

if(any_button()){ break; } //Makes the button more responsive

msleep(200);
console_clear(); //For refreshing the values

}

int final = analog(port); //Set the light off value

while(any_button()){} //Debounce

if((final-initial)>badDifference){ //Check to make sure the values are good.

//If the light is 10% of the way to the ON value, it is a light.
int threshold = (final-initial)*0.1+initial;

/*
This part keeps camera flashes from starting the robot. The 2 second wait is how long my cell phone flash takes. -Zach
*/
while(analog(port)>threshold){
while(analog(port)>threshold){
printf("Waiting for starting light...\n \n");
printf("Light ON Value: %d \n", initial);
printf("Light OFF Value: %d \n", final);
printf("---------------------- \n");
printf("Threshold Value: %d \n \n", threshold);
printf("Current Value: %d <---- \n", analog(port));
msleep(200);
console_clear();

}
printf("Waiting for starting light...\n \n");
printf("Light ON Value: %d \n", initial);
printf("Light OFF Value: %d \n", final);
printf("---------------------- \n");
printf("Threshold Value: %d \n \n", threshold);
printf("Current Value: %d <---- \n", analog(port));

unsigned long startTime = systime();
while ((systime() - startTime) < 2000) {
if (analog(port) > threshold) {
break;
}

msleep(10);
}

console_clear();
}
return;
}

//If the values were too close together
else{


console_clear();
printf("BAD CALIBRATION!!!");
if(final<1000){
printf(" -> Shield Light Sensor. \n");
}
else{
printf(" -> Values are too close.\n");
}
printf(" \n \n Press any button to restart calibration.");
while(!any_button()){} //Wait until they press the button.
}
}}
int OK = 0, onval, offval, reading, i = 0, range;
while (!OK)
{
display_printf(0, 0, "CALIBRATE: sensor port #%d", light_port);
display_printf(0, 1, " press 'B' button when light is on");
while (b_button() == 0)
{
msleep(100);
onval = analog(light_port); // sensor value when light is on
display_printf(0, 3, " light on value is = %4d ", onval);
}
display_printf(0, 3, " light on value is = %4d ", onval);
msleep(200);
while (b_button())
; // debounce B button
display_printf(0, 1, " press 'B' button when light is off");
display_printf(0, 2, " (OFF must exceed ON by at least %d)\n", THRESHOLD);
while (b_button() == 0)
{
offval = analog(light_port);
display_printf(0, 4, " light off value is = %4d ", offval);
display_printf(0, 5, " ---- ");
display_printf(0, 6, " OFF-ON = %4d ", offval - onval);
msleep(100);
}
offval = analog(light_port); // sensor value when light is off
display_printf(0, 4, " light off value is = %4d ", offval);
display_printf(0, 6, " OFF-ON = %4d ", offval - onval);
msleep(200);
if ((offval - onval) >= THRESHOLD)
{ // bright = small values
OK = 1;
display_printf(0, 8, "Good Calibration!");
msleep(1000);
graphics_open(CCOLS, CROWS);
graphics_fill(WHITE); // paint screen
range = CCOLS - 2 * INSET; // inset amount for green bar that follows
graphics_rectangle_fill(INSET, CROWS / 2 - 20, CCOLS - INSET, CROWS / 2 + 20, GREEN);
graphics_circle_fill(INSET, CROWS / 2, 20, GREEN);
graphics_circle_fill(CCOLS - INSET, CROWS / 2, 20, GREEN);
graphics_update();
graphics_print_string("READING - ON = ", INSET, 30, BLACK, 2);
while (1)
{ // loop until light verified on
colorbar(i++, range); // draw moving red circle
// msleep(20); // alternate for setting red circle speed to DJUMP
reading = analog(light_port);
graphics_rectangle_fill(INSET + 210, 30, INSET + 270, 60, WHITE); // erase text
graphics_print_int(reading - onval, 1, INSET + 210, 30, BLACK, 2);
if ((reading - onval) < THRESHOLD)
{ // reading is low enough for light on
msleep(FLASHPAUSE); // pause
reading = analog(light_port); // get second reading to rule out flash
if ((reading - onval) < THRESHOLD)
break; // if still low enough, light is on
}
}
graphics_close();
console_clear();
printf("Diagnostics:\n");
printf("OFF: %d, ON: %d, OFF-ON: %d\n", offval, onval, offval - onval);
printf("READ: %d, READ-ON=%d < THRESHOLD=%d\n", reading, reading - onval, THRESHOLD);
printf(" (good enough to recognize lights on)\n");
}
else
{
display_printf(0, 8, "BAD CALIBRATION");
if (offval < 256)
{
display_printf(15, 8, " - Add Shielding!!");
msleep(5000);
}
else
{
display_printf(15, 8, " - Aim sensor!!");
msleep(5000);
}
display_clear();
}
}
}
void colorbar(int i, int range)
{
int d, limit;
limit = range / DJUMP; // how far to traverse before reversing
d = i % (int)(2 * limit); // scale i to total number of jumps (half forward and half back)
if (d < limit)
graphics_circle_fill(INSET + DJUMP * d, CROWS / 2, 20, RED); // move to right
else
graphics_circle_fill(INSET + DJUMP * limit - DJUMP * (d - limit), CROWS / 2, 20, RED); // move to left
graphics_update();
if (d < limit)
graphics_circle_fill(INSET + DJUMP * d, CROWS / 2, 20, GREEN); // remove circle from next iteration
else
graphics_circle_fill(INSET + DJUMP * limit - DJUMP * (d - limit), CROWS / 2, 20, GREEN);
}

0 comments on commit 2e3c6a0

Please sign in to comment.