Code Search for Developers
 
 
  

raster_scan.c from EmStar at Krugle


Show raster_scan.c syntax highlighted

/*
 *
 * Copyright (c) 2003 The Regents of the University of California.  All 
 * rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Neither the name of the University nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*
 *  Raster scan: for data collection
 *  Input: 
 *    bounding box which the raster scan operates on 
 *    incr resolution in horizontal and vertical direction respectively
 *    motor device name, various sensor device names in the vertical node.
 *  Output: 
 *    log files in human readable format which logs the timestamp, location 
 *    stamp, and sensor value;
 *    matrix file: only logs sensor data value, but in Matlab matrix format.
 */

#include <libdev/include/query_client.h>
#include "mobility_control.h"
#include "libdev/sensor_client.h"

//change the following line based on the actual sensor data type.
typedef float  NimsSensorDataType;

#define __GNU_SOURCE
#include <getopt.h>
#define MAX_TEST_POINTS   20

buf_t *log_buf=NULL;

typedef  struct motor_client_state {
    char device_name[100];
    char status_device_name[100];
    int  staytime; // in terms of ms
    int  binary_mode_; 
    status_client_context_t  * sc_ref;
    //current point 
    int pt_x;
    int pt_y;	  
    int total_pts;
    query_client_ctx_t  * qc;

    //current motor position:
    int  curx;
    int  cury;

    // raster scan region
    int xmin;
    int xmax;
    int ymin;
    int ymax;
    int xres;
    int yres;

    //sensor device names:
    char par_sdev_name[100];
    char humidity_sdev_name[100];
    char temp_sdev_name[100];

    FILE * flog;
    FILE * log_file[3];
    FILE * matrix_file[3];
} motor_client_state_t;

#define  PAR 		0
#define  HUMIDITY 	1
#define  TEMP		2

/*
 *  clients for regression test driver
 */

static void take_sample( motor_client_state_t * mc );
static int retrieve_humidity_sample_value(void *arg, sc_sample_t * one_sample);
static int retrieve_temp_sample_value(void *arg, sc_sample_t * one_sample);
static int retrieve_par_sample_value(void *arg, sc_sample_t * one_sample);
static void goto_next_point( motor_client_state_t * mc);
void log_data( motor_client_state_t * mc, int sensor_type, NimsSensorDataType val);

void install_monitor_motor_client(motor_client_state_t *mcs);
void  setup_timer(motor_client_state_t * mcs, int timeout);

static 
void raster_scan_usage(char *n)
{
    fprintf(stderr, "%s -a [xmin] -b [xmax] -c [ymin] -d [ymax] -x [x_dir_resolution] -y [y_dir_resolution]  -m  /dev/motor/command_motor  -h  [humidity-sensor-device-name]  -t [temprature-sensor-device-name]  -p [par-sensor-device-name]\n", n);
    exit(1);
}


static
void move_motor( motor_client_state_t * m_client, float x, float y);

int move_motor_resp(query_client_ctx_t *qc, int retval, buf_t *response)
{
  motor_cmd_return_state_t   * ret;

  motor_client_state_t  * mcs = (motor_client_state_t  * )query_client_data( qc );

  if (retval) {
    elog( LOG_ERR, "got error: %s\n", strerror(retval));
    exit(1);
  }

  if (response) {
    ret = ( motor_cmd_return_state_t * ) response->buf;
    if  ( (! ret) || (ret->state != MOTOR_SUCCESS) )
	   elog( LOG_NOTICE, "FAIL: check command again\n");
    else  if  ( ret->state == MOTOR_SUCCESS )
    {   
       elog( LOG_NOTICE, "SUCCESS: reaching (%.2f, %.2f), now move to the next\n", ret->cx, ret->cy);

if (mcs->flog)
{
 fprintf(mcs->flog, "%lf, %lf\n", ret->cx, ret->cy );
 fflush( mcs->flog );
}
       mcs->total_pts ++;
       
       take_sample( mcs );
	setup_timer(mcs, mcs->staytime);
       
    }  
    buf_free(response);
  }

  return EVENT_RENEW;
}

void take_sample( motor_client_state_t * mc )
{
  //take samples.
  if  (strlen(mc->humidity_sdev_name) > 1)
	sc_get_next_sample( mc->humidity_sdev_name, 0,
			        retrieve_humidity_sample_value, mc, NULL);
  if  (strlen(mc->temp_sdev_name) > 1)
	sc_get_next_sample( mc->temp_sdev_name, 0,
			        retrieve_temp_sample_value, mc, NULL);
  if  (strlen(mc->par_sdev_name) > 1)
	sc_get_next_sample( mc->par_sdev_name, 0,
			        retrieve_par_sample_value, mc, NULL);
  //Else goto_next_point( mc );
}

void move_motor( motor_client_state_t * m_client, float x, float y )
{
  static consistent_query_client_t * qobj= NULL;
  char  cmd[256];
  char  device[50];

  sprintf( cmd, "%s:x=%f:y=%f", MOTOR_MOVE_CMD, x, y );
  elog( LOG_ERR, "%s", cmd );
  sprintf(device, "%s", m_client->device_name);

  if  (qobj == NULL)
  	qobj = consistent_query_client_new(m_client, cmd, move_motor_resp, device);

  consistent_query_client_issue_cmd( qobj, cmd );
  return;
}

int main(int argc, char **argv)
{
  /* 
   * check options
   */
  motor_client_state_t  m_client={};
  char  * key; 
  char  fname[256];
 
 if ((key = misc_parse_out_option(&argc, argv, "help", '?'))) {
        raster_scan_usage( argv[0] );
	exit(1);
  }

  if ((key = misc_parse_out_option(&argc, argv, "xmin", 'a'))) {
        m_client.xmin = atoi( key );
  }
  else {
        elog(LOG_ERR,"No xmin is specified for the raster scan region!\n");
        exit(1);
  }

  if ((key = misc_parse_out_option(&argc, argv, "xmax", 'b'))) {
        m_client.xmax = atoi( key );
  }
  else {
        elog(LOG_ERR,"No xmax is specified for the raster scan region!\n");
        exit(1);
  }
 
  if ((key = misc_parse_out_option(&argc, argv, "ymin", 'c'))) {
        m_client.ymin = atoi( key );
  }
  else {
        elog(LOG_ERR,"No ymin is specified for the raster scan region!\n");
        exit(1);
  }

  if ((key = misc_parse_out_option(&argc, argv, "ymax", 'd'))) {
        m_client.ymax = atoi( key );
  }
  else {
        elog(LOG_ERR,"No ymax is specified for the raster scan region!\n");
        exit(1);
  }
 

  if ((key = misc_parse_out_option(&argc, argv, "xres", 'x'))) {
        m_client.xres = atoi( key );
  }
  else {
        elog(LOG_ERR,"No xres is specified for the raster scan region!\n");
        exit(1);
  }

  if ((key = misc_parse_out_option(&argc, argv, "yres", 'y'))) {
        m_client.yres = atoi( key );
  }
  else {
        elog(LOG_ERR,"No y-resolution is specified for the raster scan region!\n");
        exit(1);
  }
 

  if ((key = misc_parse_out_option(&argc, argv, "timeout", 'q'))) {
        m_client.staytime = atoi( key );
  }
  else {
        elog(LOG_ERR,"No y-resolution is specified for the raster scan region!\n");
        exit(1);
  }
 
  //extract various device name from the command line options.
  //motor device 
 strcpy( m_client.device_name,  "\0") ;
 strcpy( m_client.humidity_sdev_name,  "\0") ;
 strcpy( m_client.temp_sdev_name,  "\0") ;
 strcpy( m_client.par_sdev_name,  "\0") ;

 if ((key = misc_parse_out_option(&argc, argv, "motor-device-name", 'm'))) {
        strcpy(m_client.device_name, key );
  }
  else {
        elog(LOG_ERR,"No motor device is specified for the motor driver!\n");
        exit(1);
  }
 

 if ((key = misc_parse_out_option(&argc, argv, "motor-status-device-name", 's'))) {
        strcpy(m_client.status_device_name, key );
  }
  else {
        elog(LOG_ERR,"No motor status device is specified for the motor driver!\n");
        exit(1);
  }
 
 if ((key = misc_parse_out_option(&argc, argv, "humidity-sensor-device-name", 'h'))) {
        strcpy(m_client.humidity_sdev_name, key );
  }
  else {
        elog(LOG_ERR,"No humidity sensor device is specified!\n");
  }
 
 if ((key = misc_parse_out_option(&argc, argv, "temprature-sensor-device-name", 't'))) {
        strcpy(m_client.temp_sdev_name, key );
  }
  else {
        elog(LOG_ERR,"No temprature sensor device is specified!\n");
  }
 
 if ((key = misc_parse_out_option(&argc, argv, "par-sensor-device-name", 'p'))) {
        strcpy(m_client.par_sdev_name, key );
  }
  else {
        elog(LOG_ERR,"No temprature sensor device is specified!\n");
  }
  if  ( strlen( m_client.par_sdev_name ) > 1 )
  {
     sprintf( fname, "%s.log", m_client.par_sdev_name );
     m_client.log_file[PAR] = fopen( fname, "w" );

    if (m_client.log_file[PAR] == NULL) {
      elog( LOG_ERR, "failed opening file %s\n", fname);
      return (-1);
    }
  }

  if  ( strlen( m_client.par_sdev_name ) > 1 )
  {
     sprintf( fname, "%s.matrix", m_client.par_sdev_name );
     m_client.matrix_file[PAR] = fopen( fname, "w" );

    if (m_client.matrix_file[PAR] == NULL) {
      elog( LOG_ERR, "failed opening file %s\n", fname);
      return (-1);
    }
  }

 
  if  ( strlen( m_client.humidity_sdev_name ) > 1 )
  {
     sprintf( fname, "%s.log", m_client.humidity_sdev_name );
     m_client.log_file[HUMIDITY] = fopen( fname, "w" );

    if (m_client.log_file[HUMIDITY] == NULL) {
      elog( LOG_ERR, "failed opening file %s\n", fname);
      return (-1);
    }
  }

  if  ( strlen( m_client.humidity_sdev_name ) > 1 )
  {
     sprintf( fname, "%s.matrix", m_client.humidity_sdev_name );
     m_client.matrix_file[HUMIDITY] = fopen( fname, "w" );

    if (m_client.matrix_file[HUMIDITY] == NULL) {
      elog( LOG_ERR, "failed opening file %s\n", fname);
      return (-1);
    }
  }

 
  if  ( strlen( m_client.temp_sdev_name ) > 1 )
  {
     sprintf( fname, "%s.log", m_client.temp_sdev_name );
     m_client.log_file[TEMP] = fopen( fname, "w" );

    if (m_client.log_file[TEMP] == NULL) {
      elog( LOG_ERR, "failed opening file %s\n", fname);
      return (-1);
    }
  }

  if  ( strlen( m_client.temp_sdev_name ) > 1 )
  {
     sprintf( fname, "%s.matrix", m_client.temp_sdev_name );
     m_client.matrix_file[TEMP] = fopen( fname, "w" );

    if (m_client.matrix_file[TEMP] == NULL) {
      elog( LOG_ERR, "failed opening file %s\n", fname);
      return (-1);
    }
  }

  m_client.flog = fopen("locations", "w");
  if  (m_client.flog == NULL)
	elog(LOG_ERR, "open location log file error" );

  m_client.binary_mode_ = 1;
  install_monitor_motor_client( &m_client);

  //go to the first point.
  goto_next_point( & m_client );

  g_main();
  
  return 0;
}

static 
int retrieve_humidity_sample_value(void *arg, sc_sample_t * one_sample)
{
  motor_client_state_t  *state = (motor_client_state_t *)arg;

  if  ( sizeof(NimsSensorDataType) != one_sample->data->len )
  {
     elog( LOG_ERR, "Invalid sample size: %d\n", one_sample->data->len );
     exit(-1);
  }

  NimsSensorDataType  value = * (NimsSensorDataType *) one_sample->data->buf;

  log_data(state, HUMIDITY, value);

  return 0;
}

static 
int retrieve_temp_sample_value(void *arg, sc_sample_t * one_sample)
{
  motor_client_state_t  *state = (motor_client_state_t *)arg;

  if  ( sizeof(NimsSensorDataType) != one_sample->data->len )
  {
     elog( LOG_ERR, "Invalid sample size: %d\n", one_sample->data->len );
     exit(-1);
  }

  NimsSensorDataType  value = * (NimsSensorDataType *) one_sample->data->buf;

  log_data(state, TEMP, value);

  return 0;
}

static 
int retrieve_par_sample_value(void *arg, sc_sample_t * one_sample)
{
  motor_client_state_t  *state = (motor_client_state_t *)arg;

  if  ( sizeof(NimsSensorDataType) != one_sample->data->len )
  {
     elog( LOG_ERR, "Invalid sample size: %d\n", one_sample->data->len );
     exit(-1);
  }

  NimsSensorDataType  value = * (NimsSensorDataType *) one_sample->data->buf;

  log_data(state, PAR, value);

  return 0;
}

static
void goto_next_point( motor_client_state_t * mc)
{
  int cx, cy;
  elog( LOG_ERR, "cur position: %d %d : total # of points: %d, bounding box:(%d, %d), (%d, %d)\n", mc->pt_x, mc->pt_y, mc->total_pts, mc->xmin, mc->xmax, mc->ymin, mc->ymax );

  if  ( mc->total_pts == 0 )
  {
    cx = mc->xmin;
    cy = mc->ymin;
    goto done;
  }
  
  cx = mc->pt_x; 
  cy = mc->pt_y;

  cy += mc->yres;

  if ( cy > mc->ymax )
  {
    cy = mc->ymin;
    cx += mc->xres;
    if  ( cx > mc->xmax )
    {
	elog( LOG_ERR, "done!\n" );
	exit(0);
    }
  }

done:
  mc->pt_x = cx;
  mc->pt_y = cy;
  move_motor( mc, cx, cy );
}

void log_data( motor_client_state_t * mc, int sensor_type, NimsSensorDataType val)
{
  struct timeval t;
  int py = mc->pt_y + mc->yres;

  gettimeofday(&t,NULL);

  fprintf(mc->log_file[sensor_type], "%s  (%d, %d) %f\n", misc_print_date(&t), mc->curx, mc->cury,  val);

  fprintf( mc->matrix_file[sensor_type], "%f ", val );

  if ( py > mc->ymax )
  {
    fprintf( mc->matrix_file[sensor_type], "\n" );
  }
	
  fflush(mc->log_file[sensor_type]);
  fflush(mc->matrix_file[sensor_type]);
}

int  stay_still_timeout(void *data, int interval, g_event_t *event)
{
  motor_client_state_t *mcs = (motor_client_state_t *) data;

  goto_next_point( mcs );
  return TIMER_DONE;
}

void  setup_timer(motor_client_state_t * mcs, int timeout)
{
     if (g_timer_add(timeout, stay_still_timeout, mcs, NULL, NULL) < 0) {
	 elog(LOG_CRIT, "Failed to install timer: %m");
      }

}

static
int status_print_bin_output(void *new_buffer, size_t size, void *data)
{
  motor_client_state_t  *state = (motor_client_state_t *) data;
  motor_cmd_return_state_t * ret;

  if (size > 1)
  {
	ret = (motor_cmd_return_state_t *) new_buffer;
	state->curx= ret->cx;
	state->cury= ret->cy;
  }
  else {
	free(new_buffer);
elog(LOG_ERR, "g_status_client_destroy(state->sc_ref);\n" );
	g_status_client_destroy(state->sc_ref);
  }

  return EVENT_RENEW;
}

static
int status_print_ascii_output(void *new_buffer, size_t size, void *data)
{
    elog(LOG_ERR, "received status update: ascii: %s, size = %d\n", (char *) new_buffer, size);
    return EVENT_RENEW;
}

void install_monitor_motor_client(motor_client_state_t *mcs)
{
     status_client_opts_t opts = {};
     opts.devname = mcs->status_device_name; 
     opts.private_data = mcs;
//     opts.crashed = handle_crash;
//     opts.destroy = destroy_private_data; 
     opts.read_as_ascii = ! mcs->binary_mode_;
     
     if (mcs->binary_mode_ == 1) {
	opts.handler =  status_print_bin_output;
     } else {
	opts.handler =  status_print_ascii_output;
     }   

     g_status_client_full(&opts, &mcs->sc_ref);
}





See more files for this project here

EmStar

EmStar is a software system for developing and deploying wireless sensor networks involving Linux-based platforms. As the wireless sensor network community has attempted to deploy more complex designs---large-scale, long-lived systems that need self-organization and adaptivity---a number of difficult software design issues have arisen. Advances in software design have not kept pace with the capabilities of hardware. This is because designing for an adaptive, efficient, and useful sensor network has turned out to be surprisingly complex and difficult. EmStar is a Linux-based software framework, whose goal is to dramatically reduce this complexity, enabling work to be shared and reused, and simplifying and speeding the design of new sensor network applications.

Project homepage: http://cvs.cens.ucla.edu/emstar/
Programming language(s): C,Shell Script
License: other

  motor_test.c
  raster_scan.c
  readme
  test