changeset 260:98dfb5a2c37a main

Latest code from Robothon.
author Bob Cook <bob@bobcookdev.com>
date Tue, 13 Oct 2015 19:17:17 -0700
parents 7124845bf907
children 71ff00c4bae6
files main/robots/odr-display/canmsgs.cpp main/robots/odr-display/display.cpp main/robots/odr-display/func.h main/robots/odr-display/menu.cpp
diffstat 4 files changed, 457 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/main/robots/odr-display/canmsgs.cpp	Sat Sep 26 12:39:42 2015 -0700
+++ b/main/robots/odr-display/canmsgs.cpp	Tue Oct 13 19:17:17 2015 -0700
@@ -103,6 +103,13 @@
 
 // ----------------------------------------------------------------------------------------
 
+bool canmsg_send_stop_pgm()
+{
+    return send_start_program( odr_pgm_stop );
+}
+
+// ----------------------------------------------------------------------------------------
+
 bool canmsg_send_start_wander_pgm()
 {
     return send_start_program( odr_pgm_wander );
@@ -124,6 +131,13 @@
 
 // ----------------------------------------------------------------------------------------
 
+bool canmsg_send_start_robothon_pgm()
+{
+    return send_start_program( odr_pgm_robothon );
+}
+
+// ----------------------------------------------------------------------------------------
+
 static void update_wheel_status( const can_data_wheel_status* data )
 {
     display_update_wheel_speed( data->actual_rpm_front, data->actual_rpm_rear );
@@ -166,20 +180,48 @@
 
 // ----------------------------------------------------------------------------------------
 
-static void update_latitude( const can_data_gps_data* data )
+static void update_current_lat( const can_data_gps_data* data )
 {
     display_update_latitude( data->degrees, data->min_thousandths );
 }
 
 // ----------------------------------------------------------------------------------------
 
-static void update_longitude( const can_data_gps_data* data )
+static void update_current_lon( const can_data_gps_data* data )
 {
     display_update_longitude( data->degrees, data->min_thousandths );
 }
 
 // ----------------------------------------------------------------------------------------
 
+static void update_origin_lat( const can_data_gps_data* data )
+{
+    display_update_origin_lat( data->degrees, data->min_thousandths );
+}
+
+// ----------------------------------------------------------------------------------------
+
+static void update_origin_lon( const can_data_gps_data* data )
+{
+    display_update_origin_lon( data->degrees, data->min_thousandths );
+}
+
+// ----------------------------------------------------------------------------------------
+
+static void update_target_lat( const can_data_gps_data* data )
+{
+    display_update_target_lat( data->degrees, data->min_thousandths );
+}
+
+// ----------------------------------------------------------------------------------------
+
+static void update_target_lon( const can_data_gps_data* data )
+{
+    display_update_target_lon( data->degrees, data->min_thousandths );
+}
+
+// ----------------------------------------------------------------------------------------
+
 static void update_gps_fix( const can_data_gps_fix* data )
 {
     status_got_gps_fix( data->satellites > 0 );
@@ -260,11 +302,11 @@
                 break;
 
             case can_dataid_gps_latitude:
-                update_latitude( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
+                update_current_lat( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
                 break;
 
             case can_dataid_gps_longitude:
-                update_longitude( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
+                update_current_lon( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
                 break;
 
             case can_dataid_gps_fix:
@@ -272,19 +314,19 @@
                 break;
 
             case can_dataid_origin_lat:
-                update_latitude( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
+                update_origin_lat( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
                 break;
 
             case can_dataid_origin_long:
-                update_longitude( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
+                update_origin_lon( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
                 break;
 
             case can_dataid_target_lat:
-                update_latitude( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
+                update_target_lat( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
                 break;
 
             case can_dataid_target_long:
-                update_longitude( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
+                update_target_lon( reinterpret_cast< can_data_gps_data* >( &recvdata ) );
                 break;
 
             case can_dataid_sonar_front_state_enabled:
--- a/main/robots/odr-display/display.cpp	Sat Sep 26 12:39:42 2015 -0700
+++ b/main/robots/odr-display/display.cpp	Tue Oct 13 19:17:17 2015 -0700
@@ -79,29 +79,6 @@
 //         012345678901234567890123456789
 //                   1         2
 //
-//
-//      0-|Outdoor Robot       H|-          H = heartbeat spinner
-//      1-|                     |-
-//      2-|      XXXXXXXX       |-          X = status message from mgr
-//      3-|                     |-
-//      4-|  motion controller  |-
-//      5-| f:+00/+00 r:+00/+00 |-
-//      6-|                     |-
-//      7-|  front rangefinder  |-
-//      8-|   000 000 000 000   |-
-//      9-|                     |-
-//     10-| lat: N 123 45.678 * |-
-//      1-| lon: W 123 45.678   |-
-//      2-|                     |-
-//      3-| Y+000 P+00.0 R+00.0 |-
-//      4-|                     |-
-//      5-|ESTOP -A- -B-        |-
-//         ||||||||||||||||||||| 
-//         012345678901234567890
-//                   1         2
-//
-//
-// GPS, BUMP F, BUMP R
 // ----------------------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------------------
@@ -665,7 +642,7 @@
         return;
     }
 
-    if ( satellites > 10 )
+    if ( satellites >= 10 )
     {
         str_write( '1', 18, 10 );
         satellites -= 10;
@@ -680,3 +657,79 @@
 
 // ----------------------------------------------------------------------------------------
 
+void display_update_origin_lat( int16_t degrees, int32_t min_thousandths )
+{
+    if ( degrees < 0 )
+    {
+        str_write( 'S', 1, 14 );
+        degrees *= -1;
+    }
+    else
+    {
+        str_write( 'N', 1, 14 );
+    }
+
+    char buf[ 12 ];
+    format_gps_value( degrees, min_thousandths, buf );
+    str_write( buf, 3, 14 );
+}
+
+// ----------------------------------------------------------------------------------------
+
+void display_update_origin_lon( int16_t degrees, int32_t min_thousandths )
+{
+    if ( degrees < 0 )
+    {
+        str_write( 'W', 1, 15 );
+        degrees *= -1;
+    }
+    else
+    {
+        str_write( 'E', 1, 15 );
+    }
+
+    char buf[ 12 ];
+    format_gps_value( degrees, min_thousandths, buf );
+    str_write( buf, 3, 15 );
+}
+
+// ----------------------------------------------------------------------------------------
+
+void display_update_target_lat( int16_t degrees, int32_t min_thousandths )
+{
+    if ( degrees < 0 )
+    {
+        str_write( 'S', 17, 14 );
+        degrees *= -1;
+    }
+    else
+    {
+        str_write( 'N', 17, 14 );
+    }
+
+    char buf[ 12 ];
+    format_gps_value( degrees, min_thousandths, buf );
+    str_write( buf, 19, 14 );
+}
+
+// ----------------------------------------------------------------------------------------
+
+void display_update_target_lon( int16_t degrees, int32_t min_thousandths )
+{
+    if ( degrees < 0 )
+    {
+        str_write( 'W', 17, 15 );
+        degrees *= -1;
+    }
+    else
+    {
+        str_write( 'E', 17, 15 );
+    }
+
+    char buf[ 12 ];
+    format_gps_value( degrees, min_thousandths, buf );
+    str_write( buf, 19, 15 );
+}
+
+// ----------------------------------------------------------------------------------------
+
--- a/main/robots/odr-display/func.h	Sat Sep 26 12:39:42 2015 -0700
+++ b/main/robots/odr-display/func.h	Tue Oct 13 19:17:17 2015 -0700
@@ -99,6 +99,12 @@
 void display_update_longitude( int16_t degrees, int32_t min_thousandths );
 void display_update_gps_fix( uint8_t satellites );
 
+void display_update_origin_lat( int16_t degrees, int32_t min_thousandths );
+void display_update_origin_lon( int16_t degrees, int32_t min_thousandths );
+
+void display_update_target_lat( int16_t degrees, int32_t min_thousandths );
+void display_update_target_lon( int16_t degrees, int32_t min_thousandths );
+
 // ----------------------------------------------------------------------------------------
 
 void menu_init();
@@ -111,9 +117,11 @@
 bool canmsg_send_emergency();
 bool canmsg_send_all_clear();
 bool canmsg_send_heartbeat();
+bool canmsg_send_stop_pgm();
 bool canmsg_send_start_wander_pgm();
 bool canmsg_send_start_line_pgm();
 bool canmsg_send_start_smbox_pgm();
+bool canmsg_send_start_robothon_pgm();
 bool canmsg_process_pending();
 
 // ----------------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/robots/odr-display/menu.cpp	Tue Oct 13 19:17:17 2015 -0700
@@ -0,0 +1,322 @@
+// ----------------------------------------------------------------------------------------
+//
+//  Copyright (C) 2014-2015 Bob Cook
+//    
+//  Bob Cook Development, Robotics Library
+//  http://www.bobcookdev.com/rl/
+// 
+//  User interface menu functions for the Outdoor Robot user interface board.
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+// 
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+// 
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------------------
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+
+#include "func.h"
+#include "leds.h"
+
+#include "packages/avr/device/spinwait.h"
+
+#include "packages/common/util/printutils.h"
+#include "packages/common/util/misc.h"
+
+#include "packages/avr/lcd/ili9340/ili9340.h"
+
+// always after other includes
+#include "packages/avr/device/workaround34734.h"
+
+// ----------------------------------------------------------------------------------------
+//
+//  The LCD display is 26 rows by 30 columns:
+//
+//                   1         2
+//         012345678901234567890123456789
+//         ||||||||||||||||||||||||||||||
+//      0-|Outdoor Robot                H|- H = heartbeat spinner
+//      1-|                              |-
+//      2-|                              |-
+//      3-|                              |-
+//      4-|      motion controller       |-
+//      5-|  f: +00 / +00  r: +00 / +00  |-
+//      6-|                              |-
+//      7-|       front obstacles        |-
+//      8-|    000   000   000   000     |-
+//      9-|                              |-
+//     10-|        location (00)         |-
+//      1-|  N 123 45.678  W 123 45.678  |-
+//      2-|                              |-
+//      3-|     origin (123.4) target    |-
+//      4-| N 123 45.678    N 123 45.678 |-
+//      5-| W 123 45.678    W 123 45.678 |-
+//      6-|                              |-
+//      7-|  inertial measurement unit   |-
+//      8-|   Y +000  P +00.0  R +00.0   |-
+//      9-|                              |-
+//     20-|  +++++++ MENU ROW 1 +++++++  |-
+//      1-|  +++++++ MENU ROW 2 ++++++>  |-
+//      2-|                              |-
+//      3-|                              |-
+//      4-|                              |-
+//      5-|       emergency active       |-
+//         ||||||||||||||||||||||||||||||
+//         012345678901234567890123456789
+//                   1         2
+//
+// ----------------------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------------------
+
+const static uint8_t menu_state_idle           = 0;
+const static uint8_t menu_state_button_pressed = 1;
+const static uint8_t menu_state_button_left    = 2;
+const static uint8_t menu_state_button_right   = 3;
+
+const static uint8_t menu_select_stop     = 0;
+const static uint8_t menu_select_wander   = 1;
+const static uint8_t menu_select_line     = 2;
+const static uint8_t menu_select_smbox    = 3;
+const static uint8_t menu_select_waypts   = 4;
+const static uint8_t menu_select_robothon = 5;
+const static uint8_t menu_num_items       = 6;
+
+const static uint8_t menu_select_animation_time = 3;
+
+static uint8_t g_menu_state = menu_state_idle;
+static uint8_t g_selection = menu_select_stop;
+static uint8_t g_menu_timer;
+
+// ----------------------------------------------------------------------------------------
+
+static void write_menu_title( const prog_char* str )
+{
+    ili9340_write_pgm( PSTR("                          "),
+                       2, 20, ili9340_color_white, ili9340_color_blue );
+
+    ili9340_write_pgm( str, 2, 20, ili9340_color_white, ili9340_color_blue );
+}
+
+// ----------------------------------------------------------------------------------------
+
+static void write_menu_entry( const prog_char* str, bool selected )
+{
+    if ( selected )
+    {
+        ili9340_write_pgm( PSTR("                        "),
+                           3, 21, ili9340_color_blue, ili9340_color_white );
+
+        ili9340_write_pgm( str, 4, 21, ili9340_color_blue, ili9340_color_white );
+    }
+    else
+    {
+        ili9340_write_pgm( PSTR("                        "),
+                           3, 21, ili9340_color_white, ili9340_color_blue );
+
+        ili9340_write_pgm( str, 4, 21, ili9340_color_white, ili9340_color_blue );
+    }
+}
+
+// ----------------------------------------------------------------------------------------
+
+static void write_arrow_left( bool selected )
+{
+    if ( selected )
+    {
+        ili9340_write( '<', 2, 21, ili9340_color_blue, ili9340_color_white );
+    }
+    else
+    {
+        ili9340_write( '<', 2, 21, ili9340_color_white, ili9340_color_blue );
+    }
+}
+
+static void write_arrow_right( bool selected )
+{
+    if ( selected )
+    {
+        ili9340_write( '>', 27, 21, ili9340_color_blue, ili9340_color_white );
+    }
+    else
+    {
+        ili9340_write( '>', 27, 21, ili9340_color_white, ili9340_color_blue );
+    }
+}
+
+// ----------------------------------------------------------------------------------------
+
+static void selection_forward()
+{
+    g_selection++;
+    g_selection %= menu_num_items;
+}
+
+static void selection_reverse()
+{
+    if ( g_selection == menu_select_stop )
+    {
+        g_selection = menu_num_items - 1;
+    }
+    else
+    {
+        --g_selection;
+    }
+}
+
+static void selection_draw( bool selected )
+{
+    switch ( g_selection )
+    {
+        case menu_select_stop:
+            write_menu_entry( PSTR("stop program"), selected );
+            break;
+
+        case menu_select_wander:
+            write_menu_entry( PSTR("start wander"), selected );
+            break;
+
+        case menu_select_line:
+            write_menu_entry( PSTR("straight line"), selected );
+            break;
+
+        case menu_select_smbox:
+            write_menu_entry( PSTR("small box"), selected );
+            break;
+
+        case menu_select_waypts:
+            write_menu_entry( PSTR("waypoints"), selected );
+            break;
+
+        case menu_select_robothon:
+            write_menu_entry( PSTR("robothon"), selected );
+            break;
+    }
+}
+
+static void selection_made()
+{
+    switch ( g_selection )
+    {
+        case menu_select_stop:
+            canmsg_send_stop_pgm();
+            break;
+
+        case menu_select_wander:
+            canmsg_send_start_wander_pgm();
+            break;
+
+        case menu_select_line:
+            canmsg_send_start_line_pgm();
+            break;
+
+        case menu_select_smbox:
+            canmsg_send_start_smbox_pgm();
+            break;
+
+        case menu_select_waypts:
+            break;
+
+        case menu_select_robothon:
+            canmsg_send_start_robothon_pgm();
+            break;
+    }
+}
+
+// ----------------------------------------------------------------------------------------
+
+void menu_init()
+{
+    g_menu_state = menu_state_idle;
+    g_selection  = menu_select_stop;
+
+    write_menu_title( PSTR("menu") );
+    write_arrow_left( false );
+    write_arrow_right( false );
+    selection_draw( false );
+}
+
+// ----------------------------------------------------------------------------------------
+
+void menu_refresh()
+{
+    if ( g_menu_state == menu_state_idle )
+    {
+        if ( button_state() == button_center_e )
+        {
+            selection_draw( true );
+            g_menu_state = menu_state_button_pressed;
+            g_menu_timer = menu_select_animation_time;
+        }
+        else if ( button_state() == button_left_e )
+        {
+            write_arrow_left( true );
+            g_menu_state = menu_state_button_left;
+            g_menu_timer = menu_select_animation_time;
+        }
+        else if ( button_state() == button_right_e )
+        {
+            write_arrow_right( true );
+            g_menu_state = menu_state_button_right;
+            g_menu_timer = menu_select_animation_time;
+        }
+    }
+    else if ( g_menu_state == menu_state_button_pressed )
+    {
+        if ( ! button_is_pressed() )
+        {
+            if ( --g_menu_timer == 0 )
+            {
+                selection_draw( false );
+                g_menu_state = menu_state_idle;
+                selection_made();
+                g_selection = menu_select_stop;
+                selection_draw( false );
+            }
+        }
+    }
+    else if ( g_menu_state == menu_state_button_left )
+    {
+        if ( ! button_is_pressed() )
+        {
+            if ( --g_menu_timer == 0 )
+            {
+                write_arrow_left( false );
+                g_menu_state = menu_state_idle;
+                selection_reverse();
+                selection_draw( false );
+            }
+        }
+    }
+    else if ( g_menu_state == menu_state_button_right )
+    {
+        if ( ! button_is_pressed() )
+        {
+            if ( --g_menu_timer == 0 )
+            {
+                write_arrow_right( false );
+                g_menu_state = menu_state_idle;
+                selection_forward();
+                selection_draw( false );
+            }
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------------------
+