38. Appendix L: User Interface Program

38.1 L.1 Introduction:

This is not only the last appendix, but the most verbose. By nature this section must express a number of details important to the operation of the program. The most important concept to understand is that this program only defines functions for Sunview to call. Control is then passed to sunview, which interprets mouse and keyboard driven input, and calls my subroutines. This means that functions must be quite well structured.

There are two main data flows handled by Sunview; inputs and outputs. The inputs tend to be from buttons, toggles, menus and text. The buttons tend to trigger function calls. The text, menus and toggles call functions to register a change in value. As will be seen in the program listing, this results in a very elemental function structure to deal with. All outputs tend to be text or lines put into a graphics windows, or text output to the window the program was run from.

The first task the program performs is to set up the various graphics windows used by the user interface. This is done will calls to sunview to define positions of items, and indications of what action each item should trigger. This allows the construction of a sophisticated multi-part user interface. The interface is seen below for the main window. This window shows neural network controls at the top. In the middle the path endpoint buffer can be seen. The bottom shows the Robot display and controls toggles. After all of these were defined, a number of functions were devised to support sunview’s calls.

 

Figure 38.1 Figure L.1: Main Window for User Interface

38.2 L.2 Description of Functions in Neural Network Window:

A number of items are presented in the Neural Network window to empower the user to control the application of the neural network. The upper line reports whether a network is loaded, the number of the trajectories in the training set, and if the net has been trained since loading. Along the left hand side are controls for handling the neural network.

The first item on the left hand side is the neural network file name. This file name will be the target, or source, of a neural network file. There are three buttons below this which will load or save with the file name, or erase the entire neural network and training set. Below these, there are two more text inputs for setting the number of layers, and the width of the hidden layers. These may only be used before a network is created or loaded. Under this there are another four buttons. These buttons allow creation of a neural network, creation of a training set from all the endpoints in the buffer, addition of the current endpoint in the buffer, and clearing of the training set.

For training, the number of iterations, the smoothing rate, and the learning rate may be entered on the text lines on the bottom left hand side of the Neural Network window. The last two buttons on the left hand side allow training, and testing of the neural network with the settings. In the other regions of the screen there are miscellaneous items of varying importance.

The centre of the screen hosts locations for setting the neural network inputs and outputs. Note that the combination of inputs is not fixed, but there may only be one output type. Also, the only Network type made available to the user was the sigmoid. It is very easy to add other network paradigms to this list, but this was deemed unnecessary for current experimentation.

The time step may be entered on a text line at the bottom right of this window. This will update all time steps used by the program, for robot control. A file name input, and two buttons appear at the bottom right of the screen. These items are used for saving, and loading the training set from an arbitrary disk file. Finally, in the bottom right hand corner, a ‘Quit’ button appears. This button will cause the program to exit.

There are some general notes about operation of this window, in general. All of the inputs which affect the configuration of the network may not be changed when a neural network is loaded. These items are ‘Layer width’, ‘Total Layers’, ‘Network inputs’, Network Output’, and ‘Network Type’. This also means that these should all be preset before clicking on the ‘Make Neural Network’ button. The functions for the training set may be changed at any time.

Every item in this window is saved with the neural network, except the neural network file name.

38.3 L.3 Description of Functions in Path Endpoint Window:

The Path Endpoints are visible through the central windows, referred to as the ‘Buffer Control Window’. The first items in this window are the path endpoint file name, and two buttons for loading and saving to the file. The other buttons control actions on the path endpoint buffer. The buffer is visible on the right hand side, as a list. As can be seen in the figure, the list shows the start and stop joint angles for the robot paths. At the left side of the list a count number is assigned for reference. The highlighted line is the line currently pointed to for all operations.

The buttons allow various operations on the list. The ‘Up List’ and ‘Down List’ buttons allow movement of the pointer through the list. The ‘Swap Current’ button will swap the start and end joint angles in the robot window for the current buffer line. If the ‘Insert’ button is used the start and end in the robot window will be inserted into the current line, and the other elements moved down. ‘Delete’ will erase the current line, and move the other lines forward by one position.

The start or end points in the Robot window are updated to the current robot position when the ‘Choose a Start Point’, or ‘Choose a Stop Point’ buttons are used. To go even further, the path may be generated for the current endpoints by clicking on the ‘Show Path of Current’ button. The display will trace out the arm positions along the path, as directed by the current motion planner. The final button is the ‘Analysis of Path’ button. This button will call up the graphing window, which operates on the current path endpoints.

38.4 L.4 Description of Functions in Robot Window:

The robot window actually acts as a catch all for many functions not devoted to either the neural network, or path endpoint maintenance. Both options visibly present in the control window are the ‘Motion Planner’ menu, and the ‘Options’ toggles. A two link manipulator is shown in the graphics window to the right. This window allows the user to directly position the manipulator, see motions, and look at positions in joint and cartesian coordinates.

The motion planner choices are quite simple, any motion planner chosen is used as the default for all path planning operations. Most of the functions are self explanatory, but others require a description. The ‘From File’ motion planner will use the training trajectories stored in the training set file, described in the neural network window. This allows paths to be generated (which might have taken minutes to find), saved to a training file, and then recalled quickly for examination. If this function is not used, then the motion plan is regenerated for every graph or motion, which may be very slow in some cases.

The ‘NN Path Track’ will cause the robot to try and track a moving goal in the right hand side of the robot work space. This was done to evaluate the operation of the robot as a traditional control system. If any details are desired about the other path planning functions, the reader is referred to the thesis body, subroutine descriptions, and source code.

If the mouse pointer is moved into the robot window, the robot position will be refreshed on the screen. While the left mouse button is held down the robot arm may be moved in the work space. This motion will be cartesian, or joint based, depending upon toggle settings. The joint coordinates and cartesian coordinates are displayed on the upper part of the robot window. The start and end positions are also recorded in this window.

The ‘Options’ toggles on the left hand side are quite simple. If the ‘Joint Control’ toggle is set, then any mouse movement of the robot will be in joint coordinates, otherwise the motions will be cartesian. The ‘Elbow Down’ toggle is used to drive the elbow up/elbow down control when the robot is moved in cartesian coordinates. The ‘Point Training’ toggle was put here for convenience, but this toggle will select between point and set training for the neural network.

When constructing training sets, the ‘Path Reverse’ toggle will mean that paths are generated between start and stop positions, as well as stop and start. This allows generation of more complete training sets. The ‘Optimal’ toggle will cause some routines to use slower algorithms which come up with more optimal solutions. This also causes torque outputs to be scaled on the neural network. The ‘Sim. fin.’ toggle will cause kinematic motion plans to stop both joints simultaneously. This will not often be used.

The settings of the ‘Motion Planner’ menu, and the ‘Options’ toggles are saved with the neural network. This allows easy generation, or recall of training data when the user interface is not used.

 

Figure 38.2 Figure M.2: Auxiliary Window for Graphing Functions

38.5 L.5 Description of Functions in Graphing Window:

There are obviously two sections to this window. In the upper half, the controls are available. The bottom half displays the graphs. The graph windows on the bottom are quite self explanatory, but their use is not.

On the right hand side, the ‘Graph Area Choice’ menu is provided. This menu will direct the graph to appear in a particular window. This allows simultaneous displays of data, in a customized configuration. The joint joint(s) to be displayed may be selected in the ‘Graph Joints’ menu. The type of data to be plotted in the window may be selected in the ‘Plot Type’ menu. All of the choices in this menu will result in a line plots, except for ‘Mean Error’, which will give histograms. Graphs of both line plots and histograms may be seen in the Graph Window figure.

To actually produce a graph, the ‘Plot’ button is used. This button will generate a trajectory, then plot the required data, for the required joints, in the specified window. For the histogram, the training set is compared against the neural network output, and then may be drawn in any window (for one joint only).

In the event the graph data needs to be exported, the ‘File’ button may be used in place of ‘Plot’. This will direct the desired data to the file name which also appears in the graph control window. A ‘Quit’ button also appears in this window. When the user is done graphing, this button may be used to remove the graph window.

38.6 L.6 Windows and Applications Setup Subroutines:

main(): This serves as the main junction for the program. The dynamics routine is set up here. The Sunview graphics are also initialized here. If the graphics have been initialized without problem, control is passed to Sunview. Sunview handles all the calling of functions, as predefined in the setup routines.

screen_init(): acts as a terminal point for calling all setup subroutines, in particular the neural network window, the path endpoint window, the robot control window, the robot drawing window, and the pop-up graph window. A refresh of the screen is also done here before control goes to sunview.

nw_init(): The neural network control window is define here. This is the uppermost window. As can be seen in earlier figures, this window defines a number of neural network related toggles, buttons, and text items.

bw_init(): Path endpoints control is handled by this window. There are actually two windows here. One window controls buttons and text related to path endpoints. The other window is used for displaying part of the list of path endpoints. This list is controlled to do current displays of the path endpoint list in a clear and concise form.

rw_init(): A robot is drawn in the bottom window. Beside this window a list of toggles, and a menu are given. These are both defined in this subroutine. The robot will actually be drawn by another subroutine, which will be defined later.

gw_init(): A window has been set up separately from the main window. This is set up for the purposes of displaying graphs of results. This window has been set up with the idea of allowing a combination of user directed graphs of any attribute. Thus, the window has been defined as a combination of six small canvases, and one large one. By referring to the description above, the reader will achieve an appreciation for the power of this window.

38.7 L.7 Graphing Subroutines:

plot_on(): The Graph Window is commonly not visible. When this function is called, the window will become visible, and the user will be able to user the graphing utilities until the ‘plot_off()’ function is called.

plot_off(): This will hide the Graphing Window.

plot_current(): This routine will call an appropriate graphing function after setting up the options. These options include graph of position, velocity, acceleration, torque or error histograms, the graph window to draw in, the joints to use. This calls the line plots separately from the histograms. When the line plot is called, it is generated for a path based on the current path endpoints. When an error histogram is called, the neural network testing subroutine is called, for every point in the training trajectory array, and the error results are used.

file_data(): This function is set up to deposit the graph results in a file name specified. This function will choose the data, and joints of interest, and write these values to a data file. This function will allow any data used for a graph to be exported to another graphing package.

plot_line(): This function will produce a line graph of the specified parameters and joints in the specified window. The graphs are prescaled, and give approximations of the data scale. The joint number will be labelled on the graph, and the graph will be labelled appropriately. The axis are also given numbers to show the magnitude of the line graph. This program is only capable of graphing position, velocity, acceleration and torques.

plot_hist(): A histogram of errors may be plotted with this function. These graphs are also self scaling to fit the histogram. The reader should recognize that the only time an error histogram is of any use is when comparing a neural network output to the ideal. This plots a histogram of all errors, as placed in the training trajectory list be the neural network testing subroutine. All histograms are appropriately labelled.

38.8 L.8 Path Endpoint Maintenance Subroutines:

buf_load(): The path endpoint file name is obtained from the screen. it is then used to load the path endpoint files, and the list on the screen is updated.

buf_save(): Path endpoints are saved to the file named on the text item in the buffer window.

buf_down(): Move current pointer down path endpoint list (toward end of array), then refresh screen.

buf_up(): Move current pointer up path endpoint list (toward start of array), then refresh the screen.

buf_delete(): Delete the path endpoints indicated by the current pointer. The screen is then refreshed.

buf_insert(): Call the insert function to open a new spot at the current path endpoint position, insert the current start/end positions, and then refresh the screen.

buf_show(): Part of the path endpoint list is displayed, with the current path endpoints highlighted. This is done directly on the screen, in the buffer window.

38.9 L.9 Training Trajectory Array Subroutines:

buf_tload(): Training trajectories are loaded from disk. The file used is as named in the Training set text input, in the neural network window. After loading, the screen is refreshed.

buf_tsave(): The training trajectory file is saved to the file named specified in the neural network training set input.

redo_robot(): The current start and stop positions for the robot are swapped with the current path endpoints, in the path endpoint array. The two affected windows are then redrawn to reflect the change.

38.10 L.10 Robot Maintenance Subroutines:

stop_robot(): The current robot position will be stored in temporary variables which are used to directly input the stop position for a robot path. The robot window will be refreshed to reflect the change in this value.

start_robot(): The current robot position will be stored in temporary variables which may be used to update the start position for a robot path in the path endpoint array. The robot window will also be redrawn.

robot_move(): When the mouse moves into the robot window this routine will be called. This will only result in a refresh of the robot position. If the left mouse button is pushed the robot will track the mouse movements in cartesian, or joint space, depending upon which flag is set. The robot is continuously redrawn to display the cartesian and joint coordinates of the robot. The robot position is used to set the user selected start and stop points.

draw_robot(): A rendering of the two link manipulator will be made by this routine. The routine will also provide text which describes the robot joint coordinates, cartesian end effector coordinates, and current start and stop points. This function should allow easy, interactive updates by the user. The robot function can also be called with color. If the color is 0, then the previous drawings will be erased, if the color is 1, then they will be preserved.

draw_path(): Using a trajectory generated from the current path endpoints, the robot path will be drawn. Before this is done, the system time step is read from the text string on the screen. The path is made to appear as a number of arm configurations by drawing the arm at a number of positions, without erasing the previous drawing. This will remain until some event triggers a redraw. A flag which has been set will instruct the subroutine to erase the entire window before drawing.

38.11 L.11 Neural Network Maintenance Subroutines:

n_display(): A refresh of the neural network window is made by this routine. All of the test, menus, toggles and report strings are updated, based upon internal configurations.

n_load(): The neural network file name is retrieved from the screen, and is used to load the neural network file, the neural network screen is updated afterwards.

n_save(): The neural network file name is retrieved from the screen, and the neural network is saved with it.

n_add(): A set of path endpoints is taken from the path endpoint array, and used to generate a trajectory, which is then added to the training trajectory array. The neural network screen is then updated.

n_clear(): The neural network training trajectory array is erased, and the screen is refreshed.

n_new(): The neural network is erase, as well as the training trajectory array. The screen is then refreshed.

n_build(): All of the path endpoints in the array are used to construct a training trajectory set, with the current path generation algorithm. The time step of the system is retrieved from the screen before this function is executed. After the training set is updated, the neural network window is refreshed.

n_create(): Neural network width, and number of hidden layers are taken from the screen, and the routine to build a neural network is called. After this the screen is updated.

n_train(): The system time step, number of training iterations, learning rate, and smoothing factors are obtained from the screen. A message is sent to the screen to indicate training is occurring, and the training routine is called. When complete the message is replaced, and the neural network window is refreshed.

n_test(): The time step of the system is obtained, and the neural network testing subroutine is called. This routine will produce a comparison between the ideal data in the training trajectory array, and the neural network output. The results are returned through global variables, and are printed in the text window the application was started from.

38.12 L.12 Sunview Interface Subroutines:

texter(): This routine registers a notification that an updated text string has been received by Sunview. Otherwise it serves no purpose.

choice_log(): Sunview notifies this routine when any of the toggles or menus has been selected. The routine will select the input received and perform the appropriate update to any global flags and variables. In one case action is taken also. This action is in the form of redrawing the robot to reflect changes in joint configurations (i.e. elbow up to elbow down).

killer(): This routine terminates Sunview, which in turns returns control of the program to the main executive routine. This in turn ends execution of the program.

 

/*

* ROBOT TRAJECTORY TRAINING PROGRAM

*

* This program is intended to provide a user interface for neural network

* controllers for 2 link manipulators. The interface includes trajectory

* file maintenance tools, neural network maintenance tools, Graphing tools

* and general controls. This program uses Sunview, on Sun computers.

*

* Some general comments about this program are that it is heavily laden

* with sunview functions. It is not the intension to comment these to

* simplicity. Thus, for particular concerns the sunview manuals should be

* consulted.

*

* This program is intended to only pass data between the user and the

* subroutines. Thus, the routines are quite redundant, but essential for

* a complete user interface.

*

* This program is expected to be applied towards the M.E.Sc. thesis of

* Mr Hugh Jack, B.E.Sc. at the University of Western Ontario.

*

* March 26th, 1990.

*/

 

#include <suntool/sunview.h> /* Numerous header files */

#include <suntool/text.h>

#include <suntool/panel.h>

#include <suntool/seln.h>

#include <suntool/textsw.h>

#include <suntool/tty.h>

#include <suntool/canvas.h>

#include <sys/stat.h>

#include <string.h>

#include <suntool/icon.h>

 

#include "rt_def.c" /* Basic Defs. for all functions */

#include "rt_dyn.c" /* Dynamics of the manipulator */

#include "rt_net.c" /* Trajectory planning network func. */

#include "rt_fun.c" /* Robot specific functions */

 

#define PICWIN_X 500 /* Robot window dimensions */

#define PICWIN_Y 400

 

#define BUFWIN_X 300 /* Dimensions of buffer window */

#define BUFWIN_Y 155

 

#define PLOWIN_X 250 /* Plotting viewport dimensions */

#define PLOWIN_Y 130

 

#define PLOSET_X 60 /* boundary around graphs */

#define PLOSET_Y 30

 

#define HIST_RES 10 /* Resolution of Histogram */

#define BUF_1_COL 40 /* Width of first col. of buffer win.*/

 

static Frame main_window, /* The main program window */

gw_win; /* The graphing Window */

 

static Panel nw_win, /* Panel of neural control buttons */

pc_win, /* The panel for plot controls */

rc_win, /* The panel for robot controls */

cw_win; /* Window for buffer controls */

 

static Canvas bw_win, /* Window for buffer display */

rw_win, /* Window for robot display */

plot_1, /* Displays for smaller plots */

plot_2,

plot_3,

plot_4,

plot_5,

plot_6,

plot_big; /* Big Plotting window */

 

static Pixwin *rw_canvas, /* canvas for drawing robot */

*current_graph, /* holds the current plot window */

*bw_canvas, /* Canvas to draw the buffer */

*graph_1, /* Canvas’ for displays of plots */

*graph_2,

*graph_3,

*graph_4,

*graph_5,

*graph_6,

*graph_big; /* Canvas for display of large plot */

 

static Panel_item men_1, /* Menu for */

men_2, /* Menu for */

men_3, /* Menu for */

men_4, /* Menu for */

men_5, /* Menu for */

tog_1, /* Toggle for */

tog_2, /* Toggle for */

tog_3, /* Toggle for */

nw_mes1, /* Message for network and training set stat */

nw_mes2, /* Message for training status */

text_1, /* Text for */

text_2, /* Text for */

text_3, /* Text for */

text_4, /* Text for */

text_5, /* Text for */

text_6, /* Text for network file name */

text_7, /* Text for buffer file name */

text_8, /* Text for raw data file name */

text_9, /* Text for system time step */

text_10; /* Text for name of training set file */

 

/* An icon for the program (my own special creation) */

static short rt_icon[256] = {

0x0000,0x0000,0x0000,0x0000,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FE7,0xFF9F,0xFFFF,0xFFFE,0x7FC3,0xFF0F,0xFFFF,0xFFFE,

0x4081,0x0204,0x0FFF,0xFCFE,0x7F81,0xFE07,0xFFFF,0xF0FE,

0x7FC3,0x7F0F,0xFFFF,0xC27E,0x7FE7,0xBD9F,0xFFFF,0x0E7E,

0x7FFF,0xDBFF,0xFFFE,0x3F3E,0x7FFF,0xE7FF,0xFFFE,0x7F3E,

0x7FFF,0xE7FF,0xFFFE,0x7F9E,0x7FFF,0xDBFF,0xFFFC,0xFF0E,

0x7FE7,0xBD9F,0xFFFC,0xFF6E,0x7FC3,0x7F0F,0xFFFC,0xFF6E,

0x4081,0x0204,0x0FF9,0xFFFE,0x7F81,0xFE07,0xFFF9,0xFFFE,

0x7FC3,0x7F0F,0xFFF9,0xFFFE,0x7FE7,0xBD9F,0xFFF3,0xFFFE,

0x7FFF,0xDBFF,0xFFF3,0xFFFE,0x7FFF,0xE7FF,0xFFF3,0xFFFE,

0x7FFF,0xE7FF,0xFFE7,0xFFFE,0x7FFF,0xDBFF,0xFFE7,0xFFFE,

0x7FE7,0xBD9F,0xFFE7,0xFFFE,0x7FC3,0x7F0F,0xFF00,0x00FE,

0x4081,0x0204,0x0F00,0x00FE,0x7F81,0xFE07,0xFF00,0x00FE,

0x7FC3,0xFF0F,0xFF00,0x00FE,0x7FE7,0xFF9F,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x0000,0x0000,0x0000,0x0000,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x7FFF,0xF807,0xC00F,0xFFFE,

0x7FFF,0xFCF3,0xDCEF,0xFFFE,0x7FFF,0xFCF9,0xFCFF,0xFFFE,

0x7FFF,0xFCF9,0xFCFF,0xFFFE,0x7FFF,0xFCF9,0xFCFF,0xFFFE,

0x7FFF,0xFCFB,0xFCFF,0xFFFE,0x7FFF,0xFC07,0xFCFF,0xFFFE,

0x7FFF,0xFC1F,0xFCFF,0xFFFE,0x7FFF,0xFC8F,0xFCFF,0xFFFE,

0x7FFF,0xFCC7,0xFCFF,0xFFFE,0x7FFF,0xFCE3,0xFCFF,0xFFFE,

0x7FFF,0xFCF1,0xFCFF,0xFFFE,0x7FFF,0xFCF8,0xFCFF,0xFFFE,

0x7FFF,0xF87C,0x703F,0xFFFE,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x7FFF,0xFFFF,0xFFFF,0xFFFE,

0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x0000,0x0000,0x0000,0x0000

};

 

DEFINE_ICON_FROM_IMAGE(frame_icon, rt_icon); /* First function to define */

/* icon in sunview */

 

 

 

Panel_setting texter(); /* A text echo routine for text input */

 

void buf_delete(), /* Functions for Trajectory buffer control */

buf_down(),

buf_insert(),

buf_load(),

buf_save(),

buf_tload(),

buf_tsave(),

buf_toggle(),

buf_up(),

n_add(), /* Functions for Trajectory buffer control */

n_build(),

n_clear(),

n_create(),

n_display(),

n_load(),

n_new(),

n_save(),

n_test(),

n_train(),

plot_current(), /* Functions for plot control */

plot_hist(),

plot_line(),

plot_off(),

plot_on(),

file_data(),

choice_log(), /* aknowledge and update toggles or menus */

draw_path(), /* Draws a trajectory based upon buffer */

redo_robot(), /* Pulls line from trajectory buffer */

robot_move(), /* Lets mouse move robot on screen */

start_robot(), /* Picks the start point of the robot */

stop_robot(); /* Picks the stop point of robot traj. */

 

int nw_init(), /* Graphics initialization routines */

rw_init(),

bw_init(),

gw_init(),

buf_show(), /* draw lines of buffer on screen */

killer(), /* stops the graphics and uqits program */

draw_robot(), /* draws the robot in one configuration */

screen_init(); /* Does complete initialization */

 

static int plot_x = PLOWIN_X, /* Size of plot window */

plot_y = PLOWIN_Y;

 

 

 

 

 

 

main(argc, argv)

int argc; /* Window Environment variables */

int **argv;

/*

* EXECUTIVE CONTROL

*

* This is obviously the main juntion loop for major execution of the user

* interface. This will initialize the screen, and the sunview routnies,

* and then pass control to Sunview. Sunview will call the various routines

* written to support this application.

*

* Variables: argc = number of input pointers

* argv = dual pointer to input

*

* Returns: An error code if error has occured.

*

* March 26th, 1990.

*/

{

static int error;

 

init_inverse_dynamics();

error = screen_init(argc, argv); /* Initialize all */

if(error == NO_ERROR){

window_main_loop(main_window); /* Start window control */

} else {

printf("Setup Error: Sunview");

}

 

exit(error); /* Return error status to caller*/

}

 

 

 

 

 

int screen_init(argc, argv)

int argc; /* Window Environment variables */

int **argv;

/*

* INITIALIZE ALL GRAPHICS

*

* All of the graphics utilities are initialized in this section. This is

* done by making calls to other subroutines which initialize various

* parts of the user interface.

*

* Variables: argc = number of input pointers

* argv = dual pointer to input

*

* Returns: An error code if error has occured.

*

* March 26th, 1990.

*/

{

static int error;

error = NO_ERROR;

 

batch_mode = 1; /* Allow training Count Output */

 

/*

* Set up main window, and all sub windows.

*/

main_window = window_create(NULL, FRAME, FRAME_ARGS, argc, argv,

WIN_Y, 0, FRAME_LABEL, "Robot Trajectory (by Hugh Jack 1990)",

FRAME_ICON, &frame_icon, 0);

error = nw_init();

error = bw_init();

error = rw_init();

window_fit(main_window);

 

 

/*

* Set up graphing pop up window.

*/

gw_win = window_create(main_window, FRAME,

FRAME_LABEL, "Trajectory Graphs", 0);

error = gw_init();

window_fit(gw_win);

 

/*

* Draw current status on screen.

*/

draw_robot(theta1, theta2, 1);

buf_show();

n_display(UPDATE);

 

return(error);

}

 

 

 

 

int nw_init()

/*

* NEURAL NETWORK BUTTON SETUP

*

* All control buttons for the neural network, and program control, are

* setup and defined in this section.

*

* Returns: An error code if error has occured.

*

* March 26th, 1990.

*/

{

static int error;

error = NO_ERROR;

 

/*

* Create main window for control of Neural Network and other

* main control options.

*/

nw_win = window_create(main_window, PANEL, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(0), WIN_COLUMNS, 49, 0);

 

/*

* Create message locations for echo of status.

*/

nw_mes1 = panel_create_item(nw_win, PANEL_MESSAGE,

PANEL_LABEL_STRING, "Neural Net: Set Size = 0 : No Net\000",

PANEL_ITEM_X, ATTR_COL(0), PANEL_ITEM_Y, ATTR_ROW(0), 0);

nw_mes2 = panel_create_item(nw_win, PANEL_MESSAGE, PANEL_LABEL_STRING,

"Not Trained", PANEL_ITEM_X, ATTR_COL(50), PANEL_ITEM_Y,

ATTR_ROW(0), 0);

 

/*

* Create text inputs for network parameters, and training.

*/

text_6 = panel_create_item(nw_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(1), PANEL_VALUE_DISPLAY_LENGTH, 10,

PANEL_VALUE, file, PANEL_LABEL_STRING, "File Name :",

PANEL_NOTIFY_PROC, texter, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Load", 0, 0),

PANEL_NOTIFY_PROC, n_load, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(7),

PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Save", 0, 0),

PANEL_NOTIFY_PROC, n_save, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(14),

PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "New ", 0, 0),

PANEL_NOTIFY_PROC, n_new, 0);

text_1 = panel_create_item(nw_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(3), PANEL_VALUE_DISPLAY_LENGTH, 10,

PANEL_VALUE, str_1, PANEL_LABEL_STRING, "Layer Width :",

PANEL_NOTIFY_PROC, texter, 0);

text_2 = panel_create_item(nw_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(4), PANEL_VALUE_DISPLAY_LENGTH, 10,

PANEL_VALUE, str_2, PANEL_LABEL_STRING, "Total Layers:",

PANEL_NOTIFY_PROC, texter, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(5), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Make Neural Net ", 0, 0),

PANEL_NOTIFY_PROC, n_create, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(6), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Build Training Set", 0, 0),

PANEL_NOTIFY_PROC, n_build, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(7), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Add Current to Set", 0, 0),

PANEL_NOTIFY_PROC, n_add, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(8), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Clear Training Set", 0, 0),

PANEL_NOTIFY_PROC, n_clear, 0);

text_3 = panel_create_item(nw_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(9), PANEL_VALUE_DISPLAY_LENGTH, 10,

PANEL_VALUE, str_3, PANEL_LABEL_STRING, "Iterations :",

PANEL_NOTIFY_PROC, texter, 0);

text_4 = panel_create_item(nw_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(10), PANEL_VALUE_DISPLAY_LENGTH, 10,

PANEL_VALUE, str_4, PANEL_LABEL_STRING, "Smooth Rate :",

PANEL_NOTIFY_PROC, texter, 0);

text_5 = panel_create_item(nw_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(11), PANEL_VALUE_DISPLAY_LENGTH, 10,

PANEL_VALUE, str_5, PANEL_LABEL_STRING, "Learn Rate :",

PANEL_NOTIFY_PROC, texter, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(12), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Train with set ", 0, 0),

PANEL_NOTIFY_PROC, n_train, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(13), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Test with set ", 0, 0),

PANEL_NOTIFY_PROC, n_test, 0);

 

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(75),

PANEL_LABEL_Y, ATTR_ROW(13), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Quit", 0, 0),

PANEL_NOTIFY_PROC, killer, 0);

 

/*

* Create text input for system time step

*/

text_9 = panel_create_item(nw_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(45),

PANEL_LABEL_Y, ATTR_ROW(8), PANEL_VALUE_DISPLAY_LENGTH, 10,

PANEL_VALUE, str_7, PANEL_LABEL_STRING, "Time step (s) :",

PANEL_NOTIFY_PROC, texter, 0);

 

/*

* Create Buttons and text input for training set file

*/

text_10 = panel_create_item(nw_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(45),

PANEL_LABEL_Y, ATTR_ROW(10), PANEL_VALUE_DISPLAY_LENGTH, 10,

PANEL_VALUE, str_6, PANEL_LABEL_STRING, "Training Set File :",

PANEL_NOTIFY_PROC, texter, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(45),

PANEL_LABEL_Y, ATTR_ROW(11), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Load Set", 0, 0),

PANEL_NOTIFY_PROC, buf_tload, 0);

panel_create_item(nw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(55),

PANEL_LABEL_Y, ATTR_ROW(11), PANEL_LABEL_IMAGE,

panel_button_image(nw_win, "Save Set", 0, 0),

PANEL_NOTIFY_PROC, buf_tsave, 0);

 

/*

* Create toggles and menu choices.

*/

tog_2 = panel_create_item(nw_win, PANEL_TOGGLE,

PANEL_LABEL_X, ATTR_COL(27), PANEL_LABEL_Y, ATTR_ROW(1),

PANEL_LABEL_STRING, "Network Inputs:",

PANEL_LAYOUT, PANEL_VERTICAL, PANEL_DISPLAY_LEVEL,PANEL_CURRENT,

PANEL_CHOICE_STRINGS, "Bias Neuron", "Position", "Velocity",

"Acceleration", "Target", "Difference", "Torque", 0,

PANEL_NOTIFY_PROC, choice_log, 0);

men_2 = panel_create_item(nw_win, PANEL_CHOICE,

PANEL_LABEL_X, ATTR_COL(45), PANEL_LABEL_Y, ATTR_ROW(1),

PANEL_LAYOUT, PANEL_VERTICAL, PANEL_LABEL_STRING,

"Network Output:", PANEL_CHOICE_STRINGS, "Position", "Velocity",

"Acceleration", "Torque", 0, PANEL_NOTIFY_PROC, choice_log, 0);

men_1 = panel_create_item(nw_win, PANEL_CHOICE,

PANEL_LABEL_X, ATTR_COL(63), PANEL_LABEL_Y, ATTR_ROW(1),

PANEL_LAYOUT, PANEL_VERTICAL, PANEL_LABEL_STRING,

"Network Type:", PANEL_CHOICE_STRINGS, "Sigmoid",

0, PANEL_NOTIFY_PROC, choice_log, 0);

 

window_fit(nw_win);

 

return (error);

}

 

 

 

 

int bw_init()

/*

* SETUP TRAJECTORY BUFFER

*

* The trajectories are described in terms of endpoints. These are kept

* track of in this window. This window also allows control of the

* information by the use of buttons.

*

* Returns: An error code if error has occured.

*

* March 26th, 1990.

*/

{

static int error;

error = NO_ERROR;

/*

* Define a panel and title for buffer control.

*/

cw_win = window_create(main_window, PANEL, WIN_BELOW, nw_win,

WIN_X, 0, WIN_COLUMNS, 36, 0);

panel_create_item(cw_win, PANEL_MESSAGE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(0), PANEL_LABEL_STRING,

"Buffer Control Window", 0);

/*

* Define a text item for text input.

*/

text_7 = panel_create_item(cw_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(1), PANEL_VALUE_DISPLAY_LENGTH, 10,

PANEL_VALUE, b_file, PANEL_LABEL_STRING, "Buffer File:",

PANEL_NOTIFY_PROC, texter, 0);

window_set(cw_win, PANEL_CARET_ITEM, text_7, 0);

 

/*

* Buttons to load/save trajectory buffer.

*/

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Load", 0, 0),

PANEL_NOTIFY_PROC, buf_load, 0);

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(16),

PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Save", 0, 0),

PANEL_NOTIFY_PROC, buf_save, 0);

 

/*

* Define buttons for other forms of buffer related functions.

*/

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(3), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Choose a Start Point", 0, 0),

PANEL_NOTIFY_PROC, start_robot, 0);

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(4), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Choose a Stop Point ", 0, 0),

PANEL_NOTIFY_PROC, stop_robot, 0);

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(5), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Show Path of Current", 0, 0),

PANEL_NOTIFY_PROC, draw_path, 0);

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(6), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Analysis of Path ", 0, 0),

PANEL_NOTIFY_PROC, plot_on, 0);

/*

* Define buttons and messages for buffer control.

*/

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(28),

PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Up List ", 0, 0),

PANEL_NOTIFY_PROC, buf_up, 0);

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(28),

PANEL_LABEL_Y, ATTR_ROW(3), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Down List ", 0, 0),

PANEL_NOTIFY_PROC, buf_down, 0);

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(28),

PANEL_LABEL_Y, ATTR_ROW(4), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Swap Current", 0, 0),

PANEL_NOTIFY_PROC, redo_robot, 0);

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(28),

PANEL_LABEL_Y, ATTR_ROW(5), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Insert ", 0, 0),

PANEL_NOTIFY_PROC, buf_insert, 0);

panel_create_item(cw_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(28),

PANEL_LABEL_Y, ATTR_ROW(6), PANEL_LABEL_IMAGE,

panel_button_image(cw_win, "Delete ", 0, 0),

PANEL_NOTIFY_PROC, buf_delete, 0);

 

window_fit(cw_win);

 

/*

* Define a window for display of the buffer

*/

bw_win = window_create(main_window, CANVAS, WIN_BELOW, nw_win,

WIN_RIGHT_OF, cw_win, WIN_WIDTH, BUFWIN_X+1,

WIN_HEIGHT, BUFWIN_Y+1, 0);

window_fit(bw_win);

bw_canvas = canvas_pixwin(bw_win);

 

/*

* Draw lines and headers for buffer display box.

*/

pw_vector(bw_canvas, 0, 0, BUFWIN_X, 0, PIX_SRC, 1);

pw_vector(bw_canvas, BUFWIN_X, 0, BUFWIN_X, BUFWIN_Y, PIX_SRC, 1);

pw_vector(bw_canvas, BUFWIN_X, BUFWIN_Y, 0, BUFWIN_Y, PIX_SRC, 1);

pw_vector(bw_canvas, 0, BUFWIN_Y, 0, 0, PIX_SRC, 1);

 

pw_vector(bw_canvas, 0, 30, BUFWIN_X, 30, PIX_SRC, 1);

pw_vector(bw_canvas, BUF_1_COL, 0, BUF_1_COL, BUFWIN_Y, PIX_SRC, 1);

pw_vector(bw_canvas, (BUFWIN_X+BUF_1_COL)/2, 0,

(BUFWIN_X+BUF_1_COL)/2, BUFWIN_Y, PIX_SRC, 1);

pw_text(bw_canvas, 5, 15, PIX_SRC, NULL, " #");

pw_text(bw_canvas, BUF_1_COL+5, 15, PIX_SRC, NULL, " from (ang 1&2)");

pw_text(bw_canvas, (BUFWIN_X+BUF_1_COL)/2+5, 15,

PIX_SRC, NULL, " to (ang 1&2)");

 

return(error);

}

 

 

 

 

int rw_init()

/*

* ROBOT WINDOW SETUP

*

* The window for the display of the 2 link manipulator is set up here.

*

* Returns: An error code if error has occured.

*

* March 26th, 1990.

*/

{

static int error;

error = NO_ERROR;

 

rc_win = window_create(main_window, PANEL, WIN_BELOW, cw_win,

WIN_X, 0, WIN_COLUMNS, 19, 0);

panel_create_item(rc_win, PANEL_MESSAGE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(0), PANEL_LABEL_STRING,

"Robot Control", 0);

tog_3 = panel_create_item(rc_win, PANEL_CHOICE,

PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_Y, ATTR_ROW(1),

PANEL_LABEL_STRING, "Motion Planner:", PANEL_LAYOUT, PANEL_VERTICAL,

PANEL_CHOICE_STRINGS, "Max. Vel.", "Max. Acc.", "Coupled Path",

"Opt. Torque", "Simple path", "Network", "From File", "NN Path Track", 0,

PANEL_NOTIFY_PROC, choice_log, 0);

tog_1 = panel_create_item(rc_win, PANEL_TOGGLE,

PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_Y, ATTR_ROW(12),

PANEL_LABEL_STRING, "Options:", PANEL_LAYOUT, PANEL_VERTICAL,

PANEL_DISPLAY_LEVEL, PANEL_CURRENT, PANEL_CHOICE_STRINGS,

"Joint Control", "Elbow Down", "Point Training", "Joint Limits",

"Path Reverse", "Optimal", "Sim. fin.", 0,

PANEL_NOTIFY_PROC, choice_log, 0);

window_fit(rc_win);

/*

* Create main Robot Window and define it as a canvas.

*/

rw_win = window_create(main_window, CANVAS, WIN_BELOW, cw_win,

WIN_BELOW, bw_win, WIN_X, ATTR_COL(19), WIN_WIDTH, PICWIN_X+1,

WIN_HEIGHT, PICWIN_Y+1, WIN_EVENT_PROC, robot_move, 0);

window_set(rw_win, WIN_CONSUME_PICK_EVENT, LOC_DRAG, 0);

window_fit(rw_win);

rw_canvas = canvas_pixwin(rw_win);

 

/*

* Draw a box around the window.

*/

pw_vector(rw_canvas, 0, 0, PICWIN_X, 0, PIX_SRC, 1);

pw_vector(rw_canvas, PICWIN_X, 0, PICWIN_X, PICWIN_Y, PIX_SRC, 1);

pw_vector(rw_canvas, PICWIN_X, PICWIN_Y, 0, PICWIN_Y, PIX_SRC, 1);

pw_vector(rw_canvas, 0, PICWIN_Y, 0, 0, PIX_SRC, 1);

 

return(error);

}

 

 

 

 

int gw_init()

/*

* PLOT WINDOW SETUP

*

* The window for control of the plots, the windows for each plot, and the

* associated buttons and toggles are set up here.

*

* Returns: An error code if error has occured.

*

* March 26th, 1990.

*/

{

static int error;

error = NO_ERROR;

 

/*

* Initialize the plotting window control panel

*/

pc_win = window_create(gw_win, PANEL,

PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(0), WIN_COLUMNS, 49, 0);

/*

* Set up Buttons for control window panel

*/

panel_create_item(pc_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(0), PANEL_LABEL_IMAGE,

panel_button_image(pc_win, "Plot", 0, 0),

PANEL_NOTIFY_PROC, plot_current, 0);

panel_create_item(pc_win, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(1), PANEL_LABEL_IMAGE,

panel_button_image(pc_win, "File", 0, 0),

PANEL_NOTIFY_PROC, file_data, 0);

panel_create_item(pc_win,PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(8), PANEL_LABEL_IMAGE,

panel_button_image(pc_win, "Done", 0, 0),

PANEL_NOTIFY_PROC, plot_off, 0);

 

/*

* Set up toggles and menus for plotting window.

*/

men_3 = panel_create_item(pc_win, PANEL_CHOICE,

PANEL_LABEL_X, ATTR_COL(40), PANEL_LABEL_Y, ATTR_ROW(0),

PANEL_LAYOUT, PANEL_VERTICAL, PANEL_LABEL_STRING,

"Graph Area Choice", PANEL_CHOICE_STRINGS, "Top Left",

"Top Right", "Middle Left", "Middle Right", "Bottom Left",

"Bottom Right", "The Big One", 0,

PANEL_NOTIFY_PROC, choice_log, 0);

men_4 = panel_create_item(pc_win, PANEL_CHOICE,

PANEL_LABEL_X, ATTR_COL(10), PANEL_LABEL_Y, ATTR_ROW(0),

PANEL_LAYOUT, PANEL_VERTICAL, PANEL_LABEL_STRING,

"Plot Type", PANEL_CHOICE_STRINGS, "Position", "Velocity",

"Acceleration", "Mean Error", "Torque", 0,

PANEL_NOTIFY_PROC, choice_log, 0);

men_5 = panel_create_item(pc_win, PANEL_CHOICE,

PANEL_LABEL_X, ATTR_COL(25), PANEL_LABEL_Y, ATTR_ROW(0),

PANEL_LAYOUT, PANEL_VERTICAL, PANEL_LABEL_STRING, "Graph Joints",

PANEL_CHOICE_STRINGS, "Joint 1", "Joint 2", "Both", 0,

PANEL_NOTIFY_PROC, choice_log, 0);

text_8 = panel_create_item(pc_win, PANEL_TEXT,

PANEL_NOTIFY_LEVEL, PANEL_NONE, PANEL_LABEL_X, ATTR_COL(0),

PANEL_LABEL_Y, ATTR_ROW(7), PANEL_VALUE_DISPLAY_LENGTH, 15,

PANEL_VALUE, dater_file, PANEL_LABEL_STRING, "Data File Name :",

PANEL_NOTIFY_PROC, texter, 0);

window_fit(pc_win);

 

 

/*

* Set up windows for graphical display.

*/

plot_1 = window_create(gw_win, CANVAS, WIN_BELOW, pc_win, WIN_X, 0,

WIN_WIDTH, PLOWIN_X+1, WIN_HEIGHT, PLOWIN_Y+1, 0);

window_fit(plot_1);

current_graph = graph_1 = canvas_pixwin(plot_1);

 

plot_2 = window_create(gw_win, CANVAS, WIN_BELOW, pc_win, WIN_RIGHT_OF,

plot_1, WIN_WIDTH, PLOWIN_X+1, WIN_HEIGHT, PLOWIN_Y+1, 0);

window_fit(plot_2);

graph_2 = canvas_pixwin(plot_2);

 

plot_3 = window_create(gw_win, CANVAS, WIN_BELOW, plot_1, WIN_X, 0,

WIN_WIDTH, PLOWIN_X+1, WIN_HEIGHT, PLOWIN_Y+1, 0);

window_fit(plot_3);

graph_3 = canvas_pixwin(plot_3);

 

plot_4 = window_create(gw_win, CANVAS, WIN_BELOW, plot_2, WIN_RIGHT_OF,

plot_3, WIN_WIDTH, PLOWIN_X+1, WIN_HEIGHT, PLOWIN_Y+1, 0);

window_fit(plot_4);

graph_4 = canvas_pixwin(plot_4);

 

plot_5 = window_create(gw_win, CANVAS, WIN_BELOW, plot_3, WIN_X, 0,

WIN_WIDTH, PLOWIN_X+1, WIN_HEIGHT, PLOWIN_Y+1, 0);

window_fit(plot_5);

graph_5 = canvas_pixwin(plot_5);

 

plot_6 = window_create(gw_win, CANVAS, WIN_BELOW, plot_4, WIN_RIGHT_OF,

plot_5, WIN_WIDTH, PLOWIN_X+1, WIN_HEIGHT, PLOWIN_Y+1, 0);

window_fit(plot_6);

graph_6 = canvas_pixwin(plot_6);

 

plot_big = window_create(gw_win, CANVAS, WIN_BELOW, plot_4, WIN_BELOW,

plot_5, WIN_X, 0, WIN_WIDTH, 2*PLOWIN_X+1,

WIN_HEIGHT, 2*PLOWIN_Y+1, 0);

window_fit(plot_big);

graph_big = canvas_pixwin(plot_big);

 

return(error);

}

 

 

 

 

void plot_on()

/*

* MAKE PLOT WINDOW VISIBLE

*

* The plot window is normally off. This function will turn it on.

*

* March 8th, 1990.

*/

{

window_set(gw_win, WIN_SHOW, TRUE, 0);

}

 

 

 

 

void plot_off()

/*

* MAKE PLOT WINDOW INVISIBLE

*

* The visibility of the graphing window will be turned off when this routine

* is called by Sunview.

*

* March 8th, 1990.

*/

{

window_set(gw_win, WIN_SHOW, FALSE, 0);

}

 

 

 

 

 

void plot_current()

/*

* MAKE A GRAPH

*

* The Appropriate graphing routine will be called, and the appropriate

* setups will be done based upon the current state of the graph options.

*

* March 8th, 1990.

*/

{

static int n, p_type;

static char dummy[50];

 

char wrk[100];

strcpy(wrk, (char *)panel_get_value(text_9));

sscanf(wrk, "%lf", &T_STEP);

 

/*

* Determine graph type and graph title

*/

if((joints_plot == JOINT_1) && (data_plot == POSITION)){

p_type = T1_POSITION;

sprintf(dummy, "Joint 1 Position");

}

if((joints_plot == JOINT_1) && (data_plot == VELOCITY)){

p_type = T1_VELOCITY;

sprintf(dummy, "Joint 1 Velocity");

}

if((joints_plot == JOINT_1) && (data_plot == ACCELERATION)){

p_type = T1_ACCELERATION;

sprintf(dummy, "Joint 1 Acceleration");

}

if((joints_plot == JOINT_1) && (data_plot == TORQUE)){

p_type = T1_TORQUE;

sprintf(dummy, "Joint 1 Torque");

}

if((joints_plot == JOINT_1) && (data_plot == MEAN_ERROR)){

p_type = T1_ERROR;

sprintf(dummy, "Joint 1 Mean Error");

}

if((joints_plot == JOINT_2) && (data_plot == POSITION)){

p_type = T2_POSITION;

sprintf(dummy, "Joint 2 Position");

}

if((joints_plot == JOINT_2) && (data_plot == VELOCITY)){

p_type = T2_VELOCITY;

sprintf(dummy, "Joint 2 Velocity");

}

if((joints_plot == JOINT_2) && (data_plot == ACCELERATION)){

p_type = T2_ACCELERATION;

sprintf(dummy, "Joint 2 Acceleration");

}

if((joints_plot == JOINT_2) && (data_plot == TORQUE)){

p_type = T2_TORQUE;

sprintf(dummy, "Joint 2 Torque");

}

if((joints_plot == JOINT_2) && (data_plot == MEAN_ERROR)){

p_type = T2_ERROR;

sprintf(dummy, "Joint 2 Mean Error");

}

if((joints_plot == BOTH) && (data_plot == POSITION)){

p_type = T_POSITION;

sprintf(dummy, "Joint 1 & 2 Position");

}

if((joints_plot == BOTH) && (data_plot == VELOCITY)){

p_type = T_VELOCITY;

sprintf(dummy, "Joint 1 & 2 Velocity");

}

if((joints_plot == BOTH) && (data_plot == ACCELERATION)){

p_type = T_ACCELERATION;

sprintf(dummy, "Joint 1 & 2 Acceleration");

}

if((joints_plot == BOTH) && (data_plot == TORQUE)){

p_type = T_TORQUE;

sprintf(dummy, "Joint 1 & 2 Torque");

}

if((joints_plot == BOTH) && (data_plot == MEAN_ERROR)){

p_type = T_ERROR;

sprintf(dummy, "Joint 1 & 2 Mean Error");

}

 

/*

* Call for normal line graph if desired

*/

if((end_of_buffer > 0) && (data_plot != MEAN_ERROR)){

get_trajectory(t_number, buffer[buffer_point].t1_start,

buffer[buffer_point].t2_start,

buffer[buffer_point].t1_end,

buffer[buffer_point].t2_end, t_set, end_train, &n);

plot_line(p_type, dummy, current_graph, t_set, end_train, n);

}

 

/*

* Call for normal histogram of errors if desired.

*/

if((net_loaded_flag == 1) &&(end_train > 0) && (data_plot==MEAN_ERROR)){

nt_test();

plot_hist(p_type, dummy, current_graph, t_set, 0, end_train);

}

}

 

 

 

 

 

void file_data()

/*

* SAVE PATH NUMBERS TO FILE

*

* This function is intended to save the current path to disk, so that

* the information may be manipulated by a graphing package. Each

* point is written twice for line graphs. This will allow square

* (non-continuous) functions to be written, The information will just

* be redundant for linear graphs. The errors for a histogram will

* also be dumped.

*

* May 29th, 1990.

*/

{

static FILE *file_ptr;

static int n, i;

static double tt1, tt2, tt1_d, tt2_d, tt1_n, tt2_n;

 

strcpy(dater_file, (char *)panel_get_value(text_8));

file_ptr = fopen(dater_file, "w");

/*

* Write file for normal line graph if desired

*/

if((end_of_buffer > 0) && (data_plot != MEAN_ERROR)){

get_trajectory(t_number, buffer[buffer_point].t1_start,

buffer[buffer_point].t2_start,

buffer[buffer_point].t1_end,

buffer[buffer_point].t2_end, t_set, end_train, &n);

for(i = end_train; i < end_train+n; i++){

if(data_plot == POSITION){

tt1 = t_set[i].t1_position;

tt2 = t_set[i].t2_position;

tt1_n = t_set[i+1].t1_position;

tt2_n = t_set[i+1].t2_position;

tt1_d = t_set[i].t1_velocity;

tt2_d = t_set[i].t2_velocity;

if(tt1_d==0.0) tt1_d = t_set[i].t1_acceleration;

if(tt2_d==0.0) tt2_d = t_set[i].t2_acceleration;

}

if(data_plot == VELOCITY){

tt1 = t_set[i].t1_velocity;

tt2 = t_set[i].t2_velocity;

tt1_n = t_set[i+1].t1_velocity;

tt2_n = t_set[i+1].t2_velocity;

tt1_d = t_set[i].t1_acceleration;

tt2_d = t_set[i].t2_acceleration;

}

if(data_plot == ACCELERATION){

tt1 = t_set[i].t1_acceleration;

tt2 = t_set[i].t2_acceleration;

tt1_n = t_set[i+1].t1_acceleration;

tt2_n = t_set[i+1].t2_acceleration;

tt1_d = 0.0;

tt2_d = 0.0;

}

if(data_plot == TORQUE){

tt1 = t_set[i].t1_torque;

tt2 = t_set[i].t2_torque;

tt1_n = t_set[i+1].t1_torque;

tt2_n = t_set[i+1].t2_torque;

tt1_d = 0.0;

tt2_d = 0.0;

}

if(joints_plot == BOTH){

fprintf(file_ptr, "%f,%f,%f\n",

(double)(T_STEP*(i: end_train)), tt1, tt2);

if((tt1_d == 0.0) && (tt2_d == 0.0)){

fprintf(file_ptr, "%f,%f,%f\n",

(double)(T_STEP*(i + 1: end_train)),

tt1, tt2);

} else if((tt1_d == 0.0) && (tt2_d != 0.0)){

fprintf(file_ptr, "%f,%f,%f\n",

(double)(T_STEP*(i + 1: end_train)),

tt1, tt2_n);

} else if((tt1_d != 0.0) && (tt2_d == 0.0)){

fprintf(file_ptr, "%f,%f,%f\n",

(double)(T_STEP*(i + 1: end_train)),

tt1_n, tt2);

}

}

if(joints_plot == JOINT_1){

fprintf(file_ptr, "%f,%f\n",

(double)(T_STEP*(i: end_train)), tt1);

if(tt1_d == 0.0){

fprintf(file_ptr, "%f,%f\n",

(double)(T_STEP*(i+1-end_train)),tt1);

}

}

if(joints_plot == JOINT_2){

fprintf(file_ptr, "%f,%f\n",

(double)(T_STEP*(i: end_train)), tt2);

if(tt2_d == 0.0){

fprintf(file_ptr, "%f,%f\n",

(double)(T_STEP*(i+1-end_train)),tt2);

}

}

}

}

 

/*

* Write file for normal histogram of errors if desired.

*/

if((end_train > 0) && (data_plot == MEAN_ERROR)){

nt_test();

for(i = 0; i < end_train; i++){

if(joints_plot == BOTH) fprintf(file_ptr, "%f\n%f\n",

t_set[i].t1_error, t_set[i].t2_error);

if(joints_plot == JOINT_1) fprintf(file_ptr, "%f\n",

t_set[i].t1_error);

if(joints_plot == JOINT_2) fprintf(file_ptr, "%f\n",

t_set[i].t2_error);

}

}

 

fclose(file_ptr);

}

 

 

 

 

 

void plot_line(type, title, plotter, points, start, n)

char *title;

Pixwin *plotter;

train_data *points;

int n, start, type;

/*

* NORMAL GRAPH DRAWER

*

* The normal graphs for joint position, velocity, and acceleration are

* drawn here. This function will draw the graph to the window named

* in the variable "plotter".

*

* Variables: type = what the graph is to represent

* title = the title which is to appear on the graph

* plotter = the pixwin which will hold the graph

* points = the array of path data

* start = the start position in the path data

* n = the number of points to be plotted

*

* March 26th, 1990.

*/

{

static int i, /* a counter variable */

t_axis, /* The zero indicator line */

y1_1, /* Work variables for graph segments */

y2_1,

y1_2,

y2_2,

y_1,

y_2,

flag_1, /* indicate which joint is graphed */

flag_2;

static double maxy, /* max and min values for graph */

miny,

scale,

scale_x;

static char tex_1[50], /* work variables for text strings */

tex_2[50],

tex_3[50],

tex_4[50];

 

flag_1 = 0; /* Set flags to false */

flag_2 = 0;

y_1 = 0;

y_2 = 0;

maxy = -999999999.0; /* Set max and min to extremes */

miny = 999999999.0;

 

/*

* Find max and min ranges for graph data

*/

if((type == T_POSITION) || (type == T1_POSITION)){

for(i = start; i < start+n; i++){

if(points[i].t1_position > maxy) maxy = points[i].t1_position;

if(points[i].t1_position < miny) miny = points[i].t1_position;

}

flag_1 = 1;

}

if((type == T_POSITION) || (type == T2_POSITION)){

for(i = start; i < start+n; i++){

if(points[i].t2_position > maxy) maxy = points[i].t2_position;

if(points[i].t2_position < miny) miny = points[i].t2_position;

}

flag_2 = 1;

}

if((type == T_VELOCITY) || (type == T1_VELOCITY)){

for(i = start; i < start+n; i++){

if(points[i].t1_velocity > maxy) maxy = points[i].t1_velocity;

if(points[i].t1_velocity < miny) miny = points[i].t1_velocity;

}

flag_1 = 1;

}

if((type == T_VELOCITY) || (type == T2_VELOCITY)){

for(i = start; i < start+n; i++){

if(points[i].t2_velocity > maxy) maxy = points[i].t2_velocity;

if(points[i].t2_velocity < miny) miny = points[i].t2_velocity;

}

flag_2 = 1;

}

if((type == T_ACCELERATION) || (type == T1_ACCELERATION)){

for(i = start; i < start+n; i++){

if(points[i].t1_acceleration > maxy)

maxy = points[i].t1_acceleration;

if(points[i].t1_acceleration < miny)

miny = points[i].t1_acceleration;

}

flag_1 = 1;

}

if((type == T_ACCELERATION) || (type == T2_ACCELERATION)){

for(i = start; i < start+n; i++){

if(points[i].t2_acceleration > maxy)

maxy = points[i].t2_acceleration;

if(points[i].t2_acceleration < miny)

miny = points[i].t2_acceleration;

}

flag_2 = 1;

}

if((type == T_TORQUE) || (type == T1_TORQUE)){

for(i = start; i < start+n; i++){

if(points[i].t1_torque > maxy)

maxy = points[i].t1_torque;

if(points[i].t1_torque < miny)

miny = points[i].t1_torque;

}

flag_1 = 1;

}

if((type == T_TORQUE) || (type == T2_TORQUE)){

for(i = start; i < start+n; i++){

if(points[i].t2_torque > maxy)

maxy = points[i].t2_torque;

if(points[i].t2_torque < miny)

miny = points[i].t2_torque;

}

flag_2 = 1;

}

if((type == T_ERROR) || (type == T1_ERROR)){

for(i = start; i < start+n; i++){

if(points[i].t1_error > maxy) maxy = points[i].t1_error;

if(points[i].t1_error < miny) miny = points[i].t1_error;

}

flag_1 = 1;

}

if((type == T_ERROR) || (type == T2_ERROR)){

for(i = start; i < start+n; i++){

if(points[i].t2_error > maxy) maxy = points[i].t2_error;

if(points[i].t2_error < miny) miny = points[i].t2_error;

}

flag_2 = 1;

}

 

maxy += 1.0; /* expand range to loosen space */

miny -= 1.0;

 

/*

* Find data range scales.

*/

scale = (double)(plot_y: 2*PLOSET_Y)/(maxy: miny);

if(n < 2) n = 2;

scale_x = (double)(plot_x: 2*PLOSET_X)/(double)(n-1);

 

/*

* Clear screen

*/

pw_writebackground(plotter, 0, 0, plot_x, plot_y, PIX_SRC);

 

/*

* Draw on zero axis if in range

*/

if((maxy > 0.0) && (miny < 0.0)){

t_axis = plot_y: PLOSET_Y + miny*scale;

pw_vector(plotter, PLOSET_X, t_axis, plot_x-PLOSET_X,

t_axis, PIX_SRC, 1);

pw_vector(plotter, plot_x-PLOSET_X, t_axis+5,

plot_x-PLOSET_X, t_axis-5, PIX_SRC, 1);

pw_vector(plotter, plot_x/2, t_axis + 5,

plot_x/2, t_axis-5, PIX_SRC, 1);

pw_text(plotter, PLOSET_X-30, t_axis, PIX_SRC, NULL, "0.0");

}

/*

* Draw the rest of the graph axis

*/

pw_vector(plotter, PLOSET_X, plot_y-PLOSET_Y, plot_x-PLOSET_X,

plot_y-PLOSET_Y, PIX_SRC, 1);

pw_vector(plotter, plot_x-PLOSET_X, plot_y-PLOSET_Y,

plot_x-PLOSET_X, plot_y-PLOSET_Y-5, PIX_SRC, 1);

pw_vector(plotter, plot_x/2, plot_y-PLOSET_Y,

plot_x/2, plot_y-PLOSET_Y-5, PIX_SRC, 1);

 

pw_vector(plotter, PLOSET_X, PLOSET_Y, PLOSET_X, plot_y-PLOSET_Y,

PIX_SRC, 1);

pw_vector(plotter,PLOSET_X, PLOSET_Y, PLOSET_X+5, PLOSET_Y, PIX_SRC, 1);

pw_vector(plotter, PLOSET_X, plot_y/2, PLOSET_X+5,

plot_y/2, PIX_SRC, 1);

 

/*

* Put title and values on graphs.

*/

pw_text(plotter, PLOSET_X, 15, PIX_SRC, NULL, title);

sprintf(tex_1, "%7.2f\000", maxy);

sprintf(tex_2, "%7.2f\000", miny);

sprintf(tex_4, "0 seconds");

sprintf(tex_3, "%7.2f\000", (double)(n*T_STEP));

pw_text(plotter, 0, PLOSET_Y, PIX_SRC, NULL, tex_1);

pw_text(plotter, 0, plot_y-PLOSET_Y, PIX_SRC, NULL, tex_2);

pw_text(plotter, PLOSET_X, plot_y-5, PIX_SRC, NULL, tex_4);

pw_text(plotter, plot_x-2*PLOSET_X, plot_y-5, PIX_SRC, NULL, tex_3);

/*

* Draw the graph with line segments

*/

for(i = start; i < start+n-1; i++){

/*

* Find start and stop height of data line segment

*/

if((type == T_POSITION) || (type == T1_POSITION)){

y1_1 = (points[i].t1_position-miny)*scale;

y2_1 = (points[i+1].t1_position-miny)*scale;

if((points[i].t1_velocity == 0.0) &&

(points[i+1].t1_velocity == 0.0)) y2_1 = y1_1;

}

if((type == T_POSITION) || (type == T2_POSITION)){

y1_2 = (points[i].t2_position-miny)*scale;

y2_2 = (points[i+1].t2_position-miny)*scale;

if((points[i].t2_velocity == 0.0) &&

(points[i+1].t2_velocity == 0.0)) y2_2 = y1_2;

}

if((type == T_VELOCITY) || (type == T1_VELOCITY)){

y1_1 = (points[i].t1_velocity-miny)*scale;

y2_1 = (points[i+1].t1_velocity-miny)*scale;

if((points[i].t1_acceleration == 0.0) &&

(points[i+1].t1_acceleration == 0.0)) y2_1=y1_1;

}

if((type == T_VELOCITY) || (type == T2_VELOCITY)){

y1_2 = (points[i].t2_velocity-miny)*scale;

y2_2 = (points[i+1].t2_velocity-miny)*scale;

if((points[i].t2_acceleration == 0.0) &&

(points[i+1].t2_acceleration == 0.0)) y2_2=y1_2;

}

if((type == T_ACCELERATION) || (type == T1_ACCELERATION)){

y1_1 = (points[i].t1_acceleration-miny)*scale;

y2_1 = (points[i+1].t1_acceleration-miny)*scale;

y2_1 = y1_1;

}

if((type == T_ACCELERATION) || (type == T2_ACCELERATION)){

y1_2 = (points[i].t2_acceleration-miny)*scale;

y2_2 = (points[i+1].t2_acceleration-miny)*scale;

y2_2 = y1_2;

}

if((type == T_TORQUE) || (type == T1_TORQUE)){

y1_1 = (points[i].t1_torque-miny)*scale;

y2_1 = (points[i+1].t1_torque-miny)*scale;

y2_1 = y1_1;

}

if((type == T_TORQUE) || (type == T2_TORQUE)){

y1_2 = (points[i].t2_torque-miny)*scale;

y2_2 = (points[i+1].t2_torque-miny)*scale;

y2_2 = y1_2;

}

if((type == T_ERROR) || (type == T1_ERROR)){

y1_1 = (points[i].t1_error-miny)*scale;

y2_1 = (points[i+1].t1_error-miny)*scale;

}

if((type == T_ERROR) || (type == T2_ERROR)){

y1_2 = (points[i].t2_error-miny)*scale;

y2_2 = (points[i+1].t2_error-miny)*scale;

}

/*

* draw line segment

*/

if(flag_1==1){

pw_vector(plotter,(int)(scale_x*(i-start)+PLOSET_X),

plot_y-PLOSET_Y-y1_1,

(int)(scale_x*(i-start+1)+PLOSET_X),

plot_y-PLOSET_Y-y2_1, PIX_SRC, 1);

if(y1_1 == y2_1){

pw_vector(plotter,(int)(scale_x*(i-start)+PLOSET_X),

plot_y-PLOSET_Y-y1_1,

(int)(scale_x*(i-start)+PLOSET_X),

plot_y-PLOSET_Y-y_1, PIX_SRC, 1);

}

y_1 = y2_1;

}

if(flag_2==1){

pw_vector(plotter,(int)(scale_x*(i-start)+PLOSET_X),

plot_y-PLOSET_Y-y1_2,

(int)(scale_x*(i-start+1)+PLOSET_X),

plot_y-PLOSET_Y-y2_2, PIX_SRC, 1);

if(y1_2 == y2_2){

pw_vector(plotter,(int)(scale_x*(i-start)+PLOSET_X),

plot_y-PLOSET_Y-y1_2,

(int)(scale_x*(i-start)+PLOSET_X),

plot_y-PLOSET_Y-y_2, PIX_SRC, 1);

}

y_2 = y2_2;

}

}

/*

* Put title on line of graph

*/

if(flag_1 == 1) pw_text(plotter, plot_x-PLOSET_X+5,

plot_y-PLOSET_Y-y2_1, PIX_SRC, NULL, "joint 1");

 

if(flag_2 == 1) pw_text(plotter, plot_x-PLOSET_X+5,

plot_y-PLOSET_Y-y2_2, PIX_SRC, NULL, "joint 2");

}

 

 

 

 

void plot_hist(type, title, plotter, points, start, n)

char *title;

Pixwin *plotter;

train_data *points;

int n, start, type;

/*

* HISTOGRAM PLOT DRAWER

*

* The histogram of network errors are drawn in this section. This will

* also chanel the graph to the window named "plotter".

*

* Variables: type = what the histogram is to represent

* title = the title which is to appear on the histogram

* plotter = the pixwin which will hold the histogram

* points = the array of path errors

* start = the start position in the path array

* n = the number of errors to be plotted

*

* March 26th, 1990.

*/

{

static int i; /* a counter work variable */

static double maxy, /* variables for max and min errors */

miny,

scale, /* y scale value */

scale_x, /* x scale value */

division; /* range of errors in a histogram cnt*/

static char tex_1[50], /* Work strings for graph labels */

tex_2[50],

tex_3[50],

tex_4[50];

static int count[HIST_RES], /* counts of errors in a range */

height; /* maximum count of errors in a range */

 

maxy = -999999999.0; /* set max and min at extremes */

miny = 999999999.0;

 

/*

* find max and min of errors

*/

if(type == T1_ERROR){

for(i = start; i < start+n; i++){

if(points[i].t1_error > maxy) maxy = points[i].t1_error;

if(points[i].t1_error < miny) miny = points[i].t1_error;

}

}

if(type == T2_ERROR){

for(i = start; i < start+n; i++){

if(points[i].t2_error > maxy) maxy = points[i].t2_error;

if(points[i].t2_error < miny) miny = points[i].t2_error;

}

}

 

/*

* count errors in different ranges of histogram

*/

for(i = 0; i < HIST_RES; i++) count[i] = 0;

division = (maxy-miny)/HIST_RES*1.001;

if(type == T1_ERROR){

for(i = start; i < start+n; i++){

count[(int)((points[i].t1_error-miny)/division)]++;

}

}

if(type == T2_ERROR){

for(i = start; i < start+n; i++){

count[(int)((points[i].t2_error-miny)/division)]++;

}

}

 

/*

* Find maximum number of errors counted in one range

*/

height = 1;

for(i = 0; i < HIST_RES; i++){

if(count[i] > height) height = count[i];

}

 

/*

* find scale values for graphing

*/

scale = (double)(plot_y: 2*PLOSET_Y)/(double)(height);

scale_x = (double)(plot_x: 2*PLOSET_X)/(double)(HIST_RES: 1);

 

/*

* clear screen and draw axis

*/

pw_writebackground(plotter, 0, 0, plot_x, plot_y, PIX_SRC);

pw_vector(plotter, PLOSET_X, plot_y-PLOSET_Y, plot_x-PLOSET_X,

plot_y-PLOSET_Y, PIX_SRC, 1);

pw_vector(plotter, plot_x-PLOSET_X, plot_y-PLOSET_Y,

plot_x-PLOSET_X, plot_y-PLOSET_Y-5, PIX_SRC, 1);

pw_vector(plotter, PLOSET_X, plot_y-PLOSET_Y,

PLOSET_X, plot_y-PLOSET_Y-5, PIX_SRC, 1);

 

pw_vector(plotter, plot_x/2, PLOSET_Y, plot_x/2, plot_y-PLOSET_Y,

PIX_SRC, 1);

pw_vector(plotter, plot_x/2-5, PLOSET_Y, plot_x/2+5,PLOSET_Y,PIX_SRC,1);

pw_vector(plotter, plot_x/2-5, plot_y/2, plot_x/2+5,

plot_y/2, PIX_SRC, 1);

 

/*

* Put titles on graphs, including numbers on axis

*/

pw_text(plotter, PLOSET_X, 15, PIX_SRC, NULL, title);

sprintf(tex_1, "%d\000", height);

sprintf(tex_2, "%d\000", 0);

sprintf(tex_4, "%7.2f\000", miny);

sprintf(tex_3, "%7.2f\000", maxy);

pw_text(plotter, plot_x/2+9, PLOSET_Y, PIX_SRC, NULL, tex_1);

pw_text(plotter, plot_x/2+9, plot_y-PLOSET_Y, PIX_SRC, NULL, tex_2);

pw_text(plotter, PLOSET_X, plot_y-5, PIX_SRC, NULL, tex_4);

pw_text(plotter, plot_x-2*PLOSET_X, plot_y-5, PIX_SRC, NULL, tex_3);

 

/*

* Plot histogram bars.

*/

for(i = 0; i < HIST_RES; i++){

pw_vector(plotter, (int)(scale_x*i+PLOSET_X-8),

(int)(plot_y-PLOSET_Y-scale*count[i]),

(int)(scale_x*i+PLOSET_X+8),

(int)(plot_y-PLOSET_Y-scale*count[i]), PIX_SRC, 1);

pw_vector(plotter, (int)(scale_x*i+PLOSET_X-8),

(int)(plot_y-PLOSET_Y-scale*count[i]),

(int)(scale_x*i+PLOSET_X-8),

(int)(plot_y-PLOSET_Y), PIX_SRC, 1);

pw_vector(plotter, (int)(scale_x*i+PLOSET_X+8),

(int)(plot_y-PLOSET_Y-scale*count[i]),

(int)(scale_x*i+PLOSET_X+8),

(int)(plot_y-PLOSET_Y), PIX_SRC, 1);

}

}

 

 

 

 

void buf_load()

/*

* LOAD TRAJECTORIES FROM FILE

*

* The buffer for the set of test (or training) trajectories is loaded from

* a file.

*

* March 8th, 1990.

*/

{

strcpy(b_file, (char *)panel_get_value(text_7));

b_load(b_file);

buf_show();

}

 

 

 

 

 

void buf_save()

/*

* SAVE TRAJECTORY INFORMATION

*

* The trajectory endpoints will be save to a file with this subroutine.

*

* March 8th, 1990.

*/

{

strcpy(b_file, (char *)panel_get_value(text_7));

b_save(b_file);

}

 

 

 

 

void buf_tload()

/*

* LOAD TRAJECTORIES FROM FILE

*

* The buffer for the set of test (or training) trajectories is loaded from

* a file.

*

* March 8th, 1990.

*/

{

strcpy(t_file, (char *)panel_get_value(text_10));

b_tload(t_file, 0, &end_train);

n_display(UPDATE);

}

 

 

 

 

 

void buf_tsave()

/*

* SAVE TRAJECTORY INFORMATION

*

* The trajectory endpoints will be save to a file with this subroutine.

*

* March 8th, 1990.

*/

{

strcpy(t_file, (char *)panel_get_value(text_10));

b_tsave(t_file);

}

 

 

 

 

void buf_down()

/*

* MOVE DOWN TRAJECTORY LIST

*

* This moves the pointer to the trajectory buffer, down the list. It will

* cause the visible list to be updated to the new item.

*

* March 8th, 1990.

*/

{

b_down();

buf_show();

}

 

 

 

void buf_up()

/*

* MOVES POINTER UP TRAJECTORY LIST

*

* The pointer will be moved to the top of the list. The display will be

* updated before return.

*

* March 8th, 1990.

*/

{

b_up();

buf_show();

}

 

 

 

void buf_delete()

/*

* REMOVES TRAJECTORY AT CURRENT POINTER

*

* The trajectory in the buffer (at the current pointer) will be deleted

* from the list. This is irreversible.

*

* March 8th, 1990.

*/

{

b_delete();

buf_show();

}

 

 

 

 

void buf_insert()

/*

* INSERT DISPLAYED TRAJECTORY AT CURRENT LOCATION

*

* The points indicated as start and stop on the screen will be entered

* into the trajectory list, at the current pointer position. The other

* trajectories will be bumped down.

*

* March 8th, 1990.

*/

{

b_insert();

buf_show();

}

 

 

 

 

 

int buf_show()

/*

* SHOW TRAJECTORIES

*

* This routine will list trajectories in a structured box, on the screen.

* The current pointer will be indicated also.

*

* Returns: returns error indication

*

* March 8th, 1990.

*/

{

static int error,

i, /* work counter */

line; /* line work variable */

static char tex_1[20], /* work strings */

tex_2[20],

tex_3[20];

error = NO_ERROR;

 

/*

* loop to generate the buffer line display window contents

*/

for(i = buffer_point: 3; i < buffer_point +4; i++){

/*

* Find current line and assign text

*/

line = 110 + 20*(i-buffer_point);

if((i < 0) || (i >= end_of_buffer)){

sprintf(tex_1, " ---\000");

sprintf(tex_2, " ---, ---\000");

sprintf(tex_3, " ---, ---\000");

} else {

sprintf(tex_1, " %3d\000", i);

sprintf(tex_2, "%7.2f,%7.2f\000",

buffer[i].t1_start, buffer[i].t2_start);

sprintf(tex_3, "%7.2f,%7.2f\000",

buffer[i].t1_end, buffer[i].t2_end);

}

 

/*

* Fill in text for buffer display window

*/

pw_text(bw_canvas, 2, line, PIX_SRC, NULL, tex_1);

pw_text(bw_canvas, BUF_1_COL+5, line, PIX_SRC, NULL, tex_2);

pw_text(bw_canvas, (BUFWIN_X+BUF_1_COL)/2+5, line,

PIX_SRC, NULL, tex_3);

pw_vector(bw_canvas, 0, 95, BUFWIN_X, 95, PIX_SRC, 1);

pw_vector(bw_canvas, 0, 115, BUFWIN_X, 115, PIX_SRC, 1);

}

return(error);

}

 

 

 

 

void stop_robot()

/*

* GET END POINT FOR NEW TRAJECTORY

*

* When entering endpoints graphically, this routine will be called

* by Sunview, and will log the end point as the current robot config.

*

* March 8th, 1990.

*/

{

current.t1_end = theta1;

if(current.t1_end > 180.0) current.t1_end -= 360.0;

if(current.t1_end < -180.0) current.t1_end += 360.0;

current.t2_end = theta2;

if(current.t2_end > 180.0) current.t2_end -= 360.0;

if(current.t2_end < -180.0) current.t2_end += 360.0;

 

draw_robot(theta1, theta2, 1);

}

 

 

 

 

void start_robot()

/*

* Get Strart Point for New Trajectory

*

* When entering endpoints graphically, this routine will be called

* by Sunview, and will log the start point as the current robot config.

*

* March 8th, 1990.

*/

{

current.t1_start = theta1;

if(current.t1_start > 180.0) current.t1_start -= 360.0;

if(current.t1_start < -180.0) current.t1_start += 360.0;

current.t2_start = theta2;

if(current.t2_start > 180.0) current.t2_start -= 360.0;

if(current.t2_start < -180.0) current.t2_start += 360.0;

 

draw_robot(theta1, theta2, 1);

}

 

 

 

 

void redo_robot()

/*

* PULL CURRENT BUFFER TRAJECTORY INTO CURRENT BUFFER

*

* The line which is highlighted on the buffer window will be moved

* into the Start/Stop window, so that it may be manipulated.

*

* May 29th, 1990.

*/

{

static double v1, v2, v3, v4;

 

v1 = buffer[buffer_point].t1_start;

v2 = buffer[buffer_point].t2_start;

v3 = buffer[buffer_point].t1_end;

v4 = buffer[buffer_point].t2_end;

 

buffer[buffer_point].t1_start = current.t1_start;

buffer[buffer_point].t2_start = current.t2_start;

buffer[buffer_point].t1_end = current.t1_end;

buffer[buffer_point].t2_end = current.t2_end;

 

current.t1_start = v1;

current.t2_start = v2;

current.t1_end = v3;

current.t2_end = v4;

 

draw_robot(theta1, theta2, 1);

buf_show();

}

 

 

 

 

void robot_move(canvas, event)

Canvas canvas; /* Sunview variables */

Event *event;

/*

* ALLOW GRAPHIC UPDATE OF ROBOT POSITION

*

* The Robot appears visibly on the screen. To allow the user to move

* the robot with the mouse, and update the new position on the screen

* this routine will be called by sunview when the mouse is moved

* inside the robot window. The robot will only be moved when a button

* is depressed.

*

* March 26th, 1990.

*/

{

static int x_old = 0,

y_old = 0,

x_new = 0,

y_new = 0;

/*

* set old and find new values

*/

x_old = x_new;

y_old = y_new;

x_new = event_x(event);

y_new = event_y(event);

 

/*

* Update robot if mouse drag is detected

*/

if(event_id(event) == LOC_DRAG){

/*

* Move by end of gripper on screen

*/

if(x_y_flag == 0){

kin_forward(theta1, theta2, &x_global, &y_global);

draw_robot(theta1, theta2, 0);

x_global -= 1.0*(x_old: x_new);

y_global += 1.0*(y_old: y_new);

kin_inverse(&theta1, &theta2,

x_global, y_global, elbow_flag);

}

/*

* Move by joint coordinates

*/

if(x_y_flag == 1){

draw_robot(theta1, theta2, 0);

theta1 += 1.0*(x_old: x_new);

theta2 += 1.0*(y_old: y_new);

}

if(train_up != 0){

if(theta1 > 180.0) theta1 = theta1: 360.0;

if(theta2 > 180.0) theta2 = theta2: 360.0;

if(theta1 < -180.0) theta1 = theta1 + 360.0;

if(theta2 < -180.0) theta2 = theta2 + 360.0;

}

if(train_up == 0){

if(theta1 > 360.0) theta1 = theta1: 360.0;

if(theta2 > 360.0) theta2 = theta2: 360.0;

if(theta1 < -360.0) theta1 = theta1 + 360.0;

if(theta2 < -360.0) theta2 = theta2 + 360.0;

}

}

draw_robot(theta1, theta2, 1);

}

 

 

 

 

int draw_robot(t1, t2, COLOR)

double t1, t2; /* Angle in degrees */

int COLOR; /* allows robot to be drawn in back ground color. */

/*

* UPDATE ROBOT WINDOW

*

* The current robot window will be updated by this routine. This includes

* redrawing the robot, printing the current, and start and stop positions

* along with the current x, y, position of the robot.

*

* March 26th, 1990.

*/

{

static int error,

x0, /* Position of robot base */

y0,

x1, /* Position of elbow joint */

y1,

x2, /* Position of end effector */

y2,

pos_x, /* Text locations */

pos_y;

static char tex_1[50], /* Text work strings */

tex_2[50],

tex_3[50],

tex_4[50],

tex_5[50],

tex_6[50];

error = NO_ERROR;

 

pos_x = 5;

pos_y = 15;

 

/*

* Find locations of robot joints

*/

x0 = PICWIN_X/2;

y0 = PICWIN_Y/2;

x1 = x0 + (int)(LENGTH_1 * cos(-t1*PI/ 180.0));

y1 = y0 + (int)(LENGTH_1 * sin(-t1*PI/ 180.0));

x2 = x1 + (int)(LENGTH_2 * cos((-t1-t2)*PI/ 180.0));

y2 = y1 + (int)(LENGTH_2 * sin((-t1-t2)*PI/ 180.0));

/*

* Create text strings for robot position

*/

sprintf(tex_1, "theta 1 = %7.2f deg \000", t1);

sprintf(tex_2, "theta 2 = %7.2f deg \000", t2);

sprintf(tex_3, "x = %d \000", (x2: x0));

sprintf(tex_4, "y = %d \000", (y0: y2));

sprintf(tex_5, "start (%6.1f,%6.1f) \000",

current.t1_start, current.t2_start);

sprintf(tex_6, "end (%6.1f,%6.1f) \000",

current.t1_end, current.t2_end);

 

/*

* Clear robot window if not in path trace mode

*/

if(trace_flag == 1){

pw_writebackground(rw_canvas, 1, 1, PICWIN_X, PICWIN_Y,PIX_SRC);

trace_flag = 0;

}

 

/*

* Put text on screen and draw robot

*/

pw_text(rw_canvas, pos_x, pos_y, PIX_SRC, NULL, tex_1);

pw_text(rw_canvas, pos_x, pos_y + 15, PIX_SRC, NULL, tex_2);

pw_text(rw_canvas, pos_x, pos_y + 30, PIX_SRC, NULL, tex_3);

pw_text(rw_canvas, pos_x, pos_y + 45, PIX_SRC, NULL, tex_4);

pw_text(rw_canvas, pos_x+200, pos_y, PIX_SRC, NULL, tex_5);

pw_text(rw_canvas, pos_x+200, pos_y + 15, PIX_SRC, NULL, tex_6);

 

pw_vector(rw_canvas, x0, y0, x1, y1, PIX_SRC, COLOR);

pw_vector(rw_canvas, x1, y1, x2, y2, PIX_SRC, COLOR);

 

pw_vector(rw_canvas, x0-10, y0, x0+10, y0, PIX_SRC, COLOR);

pw_vector(rw_canvas, x0, y0-10, x0, y0+10, PIX_SRC, COLOR);

 

return(error);

}

 

 

 

 

 

void draw_path()

/*

* DRAW ROBOT PATH

*

* The path of the robot will be drawn with this subroutine. The robot will

* not be erased, but left as a record of the path trace.

*

* March 8th, 1990.

*/

{

static int i, /* work counter */

n; /* path length pointer */

 

char wrk[100];

strcpy(wrk, (char *)panel_get_value(text_9));

sscanf(wrk, "%lf", &T_STEP);

/*

* Draw path if there is a current trajectory

*/

if(end_of_buffer > 0){

/*

* Generate a path from a trajectory

*/

get_trajectory(t_number, buffer[buffer_point].t1_start,

buffer[buffer_point].t2_start,

buffer[buffer_point].t1_end,

buffer[buffer_point].t2_end, t_set, end_train, &n);

/*

* Erase the robot then draw all the arms on the path

*/

draw_robot(theta1, theta2, 0);

for(i = end_train; i < n+end_train; i++){

draw_robot(t_set[i].t1_position,t_set[i].t2_position,1);

}

/*

* Set flag to erase screen before next arm draw

*/

trace_flag = 1;

}

}

 

 

 

 

void n_display(type)

int type;

/*

* DISPLAY CURRENT N.N. SETTINGS

*

* The current setting of the Neural Network parameters are displayed by

* this routine. This routine may also recover some data from Sunview

* and fill the appropriate variables with their values.

*

* March 26th, 1990.

*/

{

static char tex[50];

char wrk[100];

 

/*

* If the net is newly loaded, this will update the display

*/

if(type == NEW){

sprintf(str_3, "%d", n_iterations);

panel_set(text_3, PANEL_VALUE, str_3, 0);

sprintf(str_4, "%f", n_smooth);

panel_set(text_4, PANEL_VALUE, str_4, 0);

sprintf(str_5, "%f", n_learn);

panel_set(text_5, PANEL_VALUE, str_5, 0);

sprintf(str_7, "%lf", T_STEP);

panel_set(text_9, PANEL_VALUE, str_7, 0);

sprintf(str_6, "%s", t_file);

panel_set(text_10, PANEL_VALUE, str_6, 0);

sprintf(wrk, "%lf", T_STEP);

panel_set(text_9, PANEL_VALUE, wrk, 0);

sprintf(wrk, "%s", t_file);

panel_set(text_10, PANEL_VALUE, wrk, 0);

}

/*

* Set net width and layers to original values if net is already made

*/

if(net_loaded_flag == 1){

sprintf(str_1, "%d", n_width);

panel_set(text_1, PANEL_VALUE, str_1, 0);

sprintf(str_2, "%d", n_layers);

panel_set(text_2, PANEL_VALUE, str_2, 0);

}

/*

* If the input is new, then get the input training parameters

*/

if(type == UPDATE){

strcpy(str_3, (char *)panel_get_value(text_3));

strcpy(str_4, (char *)panel_get_value(text_4));

strcpy(str_5, (char *)panel_get_value(text_5));

n_iterations = atoi(str_3);

n_smooth = atof(str_4);

n_learn = atof(str_5);

 

strcpy(wrk, (char *)panel_get_value(text_9));

sscanf(wrk, "%lf", &T_STEP);

sprintf(wrk, "%lf", T_STEP);

panel_set(text_9, PANEL_VALUE, wrk, 0);

strcpy(wrk, (char *)panel_get_value(text_10));

sscanf(wrk, "%s", t_file);

sprintf(wrk, "%s", t_file);

panel_set(text_10, PANEL_VALUE, wrk, 0);

}

/*

* Reformat the training parameters, and output them to the screen

*/

sprintf(str_3, "%d", n_iterations);

panel_set(text_3, PANEL_VALUE, str_3, 0);

sprintf(str_4, "%f", n_smooth);

panel_set(text_4, PANEL_VALUE, str_4, 0);

sprintf(str_5, "%f", n_learn);

panel_set(text_5, PANEL_VALUE, str_5, 0);

 

/*

* Set the toggles and menus to the current variable info

*/

panel_set_value(men_1, n_type-SIGMOID);

panel_set_value(men_2, n_output-POSITION);

 

panel_set(tog_2, PANEL_TOGGLE_VALUE, 0, n_bias, 0);

panel_set(tog_2, PANEL_TOGGLE_VALUE, 1, n_position, 0);

panel_set(tog_2, PANEL_TOGGLE_VALUE, 2, n_velocity, 0);

panel_set(tog_2, PANEL_TOGGLE_VALUE, 3, n_acceleration, 0);

panel_set(tog_2, PANEL_TOGGLE_VALUE, 4, n_target, 0);

panel_set(tog_2, PANEL_TOGGLE_VALUE, 5, n_difference, 0);

panel_set(tog_2, PANEL_TOGGLE_VALUE, 6, n_torque, 0);

 

panel_set(tog_1, PANEL_TOGGLE_VALUE, 1, elbow_flag, 0);

panel_set(tog_1, PANEL_TOGGLE_VALUE, 2, 0, 0);

panel_set(tog_1, PANEL_TOGGLE_VALUE, 3, train_up, 0);

panel_set(tog_1, PANEL_TOGGLE_VALUE, 4, train_alt, 0);

panel_set(tog_1, PANEL_TOGGLE_VALUE, 5, train_opt, 0);

panel_set(tog_1, PANEL_TOGGLE_VALUE, 6, train_sim, 0);

if(updater == POINT_TRAIN)

panel_set(tog_1, PANEL_TOGGLE_VALUE, 2, 1, 0);

panel_set_value(tog_3, t_number: CASE_1);

 

/*

* Put network and training set status on the screen

*/

if(net_loaded_flag == 0){

sprintf(tex, "Neural Net: Set Size = %d : No Net\000",

end_train);

} else {

sprintf(tex, "Neural Net: Set Size = %d : Net Loaded\000",

end_train);

}

panel_set(nw_mes1, PANEL_LABEL_STRING, tex, 0);

}

 

 

 

 

void n_load()

/*

* LOAD NEURAL NETWORK

*

* The named neural network is loaded with routine. The relevant data is

* also recovered from the ’extra string’ storage capability of the

* neural network subroutines.

*

* March 26th, 1990.

*/

{

/*

* get network file name

*/

strcpy(file, (char *)panel_get_value(text_6));

/*

* load file and set variables in sunview

*/

if(nt_load(file) != ERROR){

n_display(NEW);

} else {

n_display(UPDATE);

}

}

 

 

 

 

void n_save()

/*

* SAVE NEURAL NETWORK

*

* The neural network may be saved with these routines. The important data

* is also saved with the extra string functions of the neural network

* subroutines.

*

* March 8th, 1990.

*/

{

/*

* Get network file name and save file

*/

strcpy(file, (char *)panel_get_value(text_6));

n_display(UPDATE);

nt_save(file);

}

 

 

 

void n_add()

/*

* ADD A PATH TO THE TRAINING SET

*

* The training set will be appended by the current trajectory path.

* This is the only path which will be added.

*

* March 8th, 1990.

*/

{

char wrk[100];

strcpy(wrk, (char *)panel_get_value(text_9));

sscanf(wrk, "%lf", &T_STEP);

/*

* Add a trajectory to the path training set

*/

nt_add(buffer[buffer_point].t1_start, buffer[buffer_point].t2_start,

buffer[buffer_point].t1_end, buffer[buffer_point].t2_end);

n_display(UPDATE);

}

 

 

 

void n_clear()

/*

* WIPE OUT TRAINING SET

*

* The current Neural Network Training Set Will be wiped out.

*

* March 8th, 1990.

*/

{

/*

* Call function to wipe out path training set

*/

nt_clear();

n_display(UPDATE);

}

 

 

 

void n_new()

/*

* WIPE OUT NEURAL NETWORK

*

* The currently configured neural network will be wiped out. This

* will also wipe out the training set. This does not change the options

* which have been entered.

*

* March 8th, 1990.

*/

{

/*

* Call function to wipe neural net, then reset message

*/

nt_new();

panel_set(nw_mes2, PANEL_LABEL_STRING, "Not Trained", 0);

n_display(UPDATE);

}

 

 

 

 

void n_build()

/*

* BUILD A NEW TRAINING SET

*

* The old training set will be wiped out and replaced with a new one.

* This training set will consist of all trajectory paths described by

* contents of the current trajectory buffer.

*

* March 8th, 1990.

*/

{

char wrk[100];

strcpy(wrk, (char *)panel_get_value(text_9));

sscanf(wrk, "%lf", &T_STEP);

/*

* Call function to create path training set from entered parameters

*/

nt_build();

n_display(UPDATE);

}

 

 

 

 

void n_create()

/*

* BUILD NEW NEURAL NETWORK

*

* A new neural network will be built, based upon the current options entered.

*

* March 8th, 1990.

*/

{

/*

* Retrieve network parameters

*/

strcpy(str_1, (char *)panel_get_value(text_1));

strcpy(str_2, (char *)panel_get_value(text_2));

/*

* Create net with parameters and function

*/

if(net_loaded_flag == 0){

n_width = atoi(str_1);

n_layers = atoi(str_2);

nt_create();

}

n_display(UPDATE);

}

 

 

 

 

void n_train()

/*

* TRAIN THE NEURAL NETWORK

*

* The current training set is used to train the neural network.

*

* March 8th, 1990.

*/

{

char wrk[100];

strcpy(wrk, (char *)panel_get_value(text_9));

sscanf(wrk, "%lf", &T_STEP);

/*

* Get the training parameters, and update variables

*/

strcpy(str_3, (char *)panel_get_value(text_3));

strcpy(str_4, (char *)panel_get_value(text_4));

strcpy(str_5, (char *)panel_get_value(text_5));

n_iterations = atoi(str_3);

n_smooth = atof(str_4);

n_learn = atof(str_5);

/*

* Display messages and train network, if net loaded and set prepared

*/

if((end_train > 0) && (net_loaded_flag == 1)){

panel_set(nw_mes2, PANEL_LABEL_STRING, "Training", 0);

nt_train();

panel_set(nw_mes2, PANEL_LABEL_STRING, "Done Training", 0);

}

n_display(UPDATE);

}

 

 

 

 

 

void n_test()

/*

* TEST THE NETWORK FOR ERRORS

*

* The network is tested, using the current network configuration, and the

* current training set. This does not alter the network, but finds the

* error per reading.

*

* March 8th, 1990.

*/

{

char wrk[100];

strcpy(wrk, (char *)panel_get_value(text_9));

sscanf(wrk, "%lf", &T_STEP);

/*

* If error status available, print errors to screen

*/

if(end_train > 0){

nt_test();

printf("Joint 1 average error = %f \n", n1_error);

printf("Joint 1 deviation = %f \n", n1_deviation);

printf("Joint 2 average error = %f \n", n2_error);

printf("Joint 2 deviation = %f \n", n2_deviation);

printf("Both Joint average error = %f \n", net_average_error);

printf("Both Joint deviation = %f \n", net_deviation);

}

}

 

 

 

 

 

Panel_setting texter(item, event)

Panel_item item;

Event *event;

/*

* A TEXT VALUE RETURN ROUTINE FOR SUNVIEW

*

* Sunview requires a value returned when text is entered. This function

* serves this purpose.

*

* March 8th, 1990.

*/

{

return(panel_text_notify(item, event));

}

 

 

 

 

 

void choice_log(item, value, event)

Panel_item item;

int value;

Event *event;

/*

* GET OUTPUT OPTION

*

* Sunview will call this routine to deliver the output option. This option

* will determine what the network will use as output.

*

* March 26th, 1990.

*/

{

static double x, y;

static int v1, v2;

 

/*

* Update the value for network output

*/

if(item == men_2){

if(net_loaded_flag == 0){

if(value == 0) n_output = POSITION;

if(value == 1) n_output = VELOCITY;

if(value == 2) n_output = ACCELERATION;

if(value == 3) n_output = TORQUE;

panel_set_value(men_2, value);

}

}

/*

* Update the value for network activation function

*/

if(item == men_1){

if(net_loaded_flag == 0){

if(value == 0) n_type = SIGMOID;

panel_set_value(men_1, value);

}

}

/*

* Update the trajectory planning method

*/

if(item == tog_3){

if(value == 0) t_number = CASE_1;

if(value == 1) t_number = CASE_2;

if(value == 2) t_number = CASE_3;

if(value == 3) t_number = CASE_4;

if(value == 4) t_number = CASE_5;

if(value == 5) t_number = NETWORK;

if(value == 6) t_number = SET_FILE;

if(value == 7) t_number = NN_TRACK;

panel_set_value(tog_3, value);

}

/*

* Update the input types to the network

*/

if((item == tog_2) && (net_loaded_flag == 0)){

n_bias = (int)panel_get(tog_2, PANEL_TOGGLE_VALUE, 0);

n_position = (int)panel_get(tog_2,

PANEL_TOGGLE_VALUE, 1);

n_velocity = (int)panel_get(tog_2,

PANEL_TOGGLE_VALUE, 2);

n_acceleration = (int)panel_get(tog_2,

PANEL_TOGGLE_VALUE, 3);

n_target = (int)panel_get(tog_2, PANEL_TOGGLE_VALUE, 4);

n_difference = (int)panel_get(tog_2, PANEL_TOGGLE_VALUE, 5);

n_torque = (int)panel_get(tog_2, PANEL_TOGGLE_VALUE, 6);

}

/*

* Update the value for special flags

*/

if(item == tog_1){

x_y_flag = (int)panel_get(tog_1, PANEL_TOGGLE_VALUE, 0);

elbow_flag = (int)panel_get(tog_1, PANEL_TOGGLE_VALUE, 1);

train_alt = (int)panel_get(tog_1, PANEL_TOGGLE_VALUE, 4);

train_sim = (int)panel_get(tog_1, PANEL_TOGGLE_VALUE, 6);

v1 = (int)panel_get(tog_1, PANEL_TOGGLE_VALUE, 3);

v2 = (int)panel_get(tog_1, PANEL_TOGGLE_VALUE, 5);

if(v1 != train_up){

train_up = v1;

train_opt = 0;

} else if(v2 != train_opt){

train_up = 0;

train_opt = v2;

} else {

train_up = v1;

train_opt = v2;

}

 

updater = SET_TRAIN;

if((int)panel_get(tog_1, PANEL_TOGGLE_VALUE, 2) == TRUE)

updater = POINT_TRAIN;

draw_robot(theta1, theta2, 0);

kin_forward(theta1, theta2, &x, &y);

kin_inverse(&theta1, &theta2, x, y, elbow_flag);

draw_robot(theta1, theta2, 1);

}

/*

* Update the value for which joint is to be plotted

*/

n_display(UPDATE);

if(item == men_5){

if(value == 0) joints_plot = JOINT_1;

if(value == 1) joints_plot = JOINT_2;

if(value == 2) joints_plot = BOTH;

panel_set_value(men_5, value);

}

/*

* Update the value for joint information to be plotted

*/

if(item == men_4){

if(value == 0) data_plot = POSITION;

if(value == 1) data_plot = VELOCITY;

if(value == 2) data_plot = ACCELERATION;

if(value == 3) data_plot = MEAN_ERROR;

if(value == 4) data_plot = TORQUE;

panel_set_value(men_4, value);

}

/*

* Update the current window which is to be plotted in.

*/

if(item == men_3){

if(value == 0) current_graph = graph_1;

if(value == 1) current_graph = graph_2;

if(value == 2) current_graph = graph_3;

if(value == 3) current_graph = graph_4;

if(value == 4) current_graph = graph_5;

if(value == 5) current_graph = graph_6;

plot_x = PLOWIN_X;

plot_y = PLOWIN_Y;

if(value == 6){

current_graph = graph_big;

plot_x = PLOWIN_X * 2;

plot_y = PLOWIN_Y * 2;

}

panel_set_value(men_3, value);

}

}

 

 

 

 

int killer()

/*

* END THE PROGRAM

*

* The Sunview windows will be halted when this routine is called, and as a

* result, the program will end.

*

* March 8th, 1990.

*/

{

static int error;

error = NO_ERROR;

 

/*

* When the window is killed, the program will exit.

*/

window_destroy(main_window);

 

return(error);

}