<commit_before>/*
 *
 * Description:
 * This file holds the controller logic.  It manages the connection to the Atmega328.
 *
 */
var path = require('path'), spawn = require('child_process').spawn, CONFIG = require('./config'), StatusReader = require('./StatusReader'), ArduinoHelper = require('./ArduinoHelper'), logger = require('./logger').create(CONFIG), EventEmitter = require('events').EventEmitter, Hardware = require('../' + CONFIG.Hardware);
var setup_serial = function () {
  var location = path.join(__dirname, '..', './linux');
  logger.log('Starting the script from ' + location + ' to setup UART1...');
  var setuart_process = spawn('sudo', [path.join(location, 'setuart.sh')]);
  setuart_process.on('error', function (err) {
    logger.log('Error while starting the UART1 setup scipt!\nThe error was: ' + err);
  });
};
var statusdata = {};
var settingsCollection = {
    smoothingIncriment: 0,
    deadZone_min: 0,
    deadZone_max: 0,
    water_type: 0 // FreshWater
  };

var rovsys = { capabilities: 0 };

var OpenROVController = function (eventLoop, client) {
  var controller = this;
  var serial;
  var globalEventLoop = eventLoop;
  this.physics = new ArduinoHelper().physics;
  this.hardware = new Hardware();
  this.cockpit = client;

  this.hardware.on('serial-recieved', function (data) {
    globalEventLoop.emit('serial-recieved', data);
  });

  this.hardware.on('status', function (status) {
    statusdata = {};

    for (var i in status) {
      statusdata[i] = status[i];
    }
    controller.emit('status', statusdata);
    if ('ver' in status) {
      controller.ArduinoFirmwareVersion = status.ver;
    }
    if ('TSET' in status) {
      var setparts = status.settings.split(',');
      settingsCollection.smoothingIncriment = setparts[0];
      settingsCollection.deadZone_min = setparts[1];
      settingsCollection.deadZone_max = setparts[2];
      settingsCollection.water_type = setparts[3];
      controller.emit('Arduino-settings-reported', settingsCollection);
    }
    if ('CAPA' in status) {
      var s = rovsys;
      s.capabilities = parseInt(status.CAPA);
      controller.Capabilities = s.capabilities;
      controller.emit('rovsys', s);
    }
    if ('cmd' in status) {
      if (status.com != 'ping(0)'){
        controller.emit('command', status.cmd);
      }
    }
    if ('log' in status) {
    }
    if ('boot' in status){
      this.Capabilities = 0;
      controller.updateSetting();
      controller.requestSettings();
      controller.requestCapabilities();
    }
  });
  setup_serial();
  this.hardware.connect();
  controller.ArduinoFirmwareVersion = 0;
  controller.Capabilities = 0;

  globalEventLoop.on('register-ArdunoFirmwareVersion', function (val) {
    controller.ArduinoFirmwareVersion = val;
  });
  globalEventLoop.on('register-ArduinoCapabilities', function (val) {
    controller.Capabilities = val;
  });

  globalEventLoop.on('SerialMonitor_start_rawSerial', function () {
    controller.hardware.startRawSerialData();
  });

  globalEventLoop.on('SerialMonitor_stop_rawSerial', function () {
    controller.hardware.stopRawSerialData();
  });

  globalEventLoop.on('serial-stop', function () {
    logger.log('Closing serial connection for firmware upload');
    controller.hardware.close();
  });

  globalEventLoop.on('serial-start', function () {
    controller.hardware.connect();
    controller.updateSetting();
    controller.requestSettings();
    controller.requestCapabilities();
//    logger.log('Opened serial connection after firmware upload');
  });

  //Every few seconds we check to see if capabilities or settings changes on the arduino.
  //This handles the cases where we have garbled communication or a firmware update of the arduino.
  setInterval(function () {
    if (controller.notSafeToControl() === false) return;
      controller.updateSetting();
      controller.requestSettings();
      controller.requestCapabilities();
  }, 1000);

  return controller;
};
OpenROVController.prototype = new EventEmitter();
OpenROVController.prototype.constructor = OpenROVController;

OpenROVController.prototype.notSafeToControl = function () {
  //Arduino is OK to accept commands. After the Capabilities was added, all future updates require
  //being backward safe compatible (meaning you cannot send a command that does something unexpected but
  //instead it should do nothing).
  if (this.Capabilities !== 0)
    return false;
  //This feature added after the swap to ms on the Arduino
//  console.log('Waiting for the capability response from Arduino before sending command.');
//  console.log('Arduno Version: ' + this.ArduinoFirmwareVersion);
//  console.log('Capability bitmap: ' + this.Capabilities);
  return true;
};


OpenROVController.prototype.send = function (cmd) {
  var controller = this;
  if (controller.notSafeToControl())
    return;

  var command = cmd + ';';

  controller.hardware.write(command);
};

OpenROVController.prototype.requestCapabilities = function () {
  var command = 'rcap();';
  this.hardware.write(command);
};

OpenROVController.prototype.requestSettings = function () {
  //todo: Move to a settings manager
  var command = 'reportSetting();';
  this.hardware.write(command);
  command = 'rmtrmod();';
  this.hardware.write(command);
};

//TODO: Move the water setting to diveprofile
OpenROVController.prototype.updateSetting = function () {
  function watertypeToflag(type){
    if(type=='fresh'){return 0;}
    return 1;
  }

  var command = 'updateSetting('
    + CONFIG.preferences.get('smoothingIncriment') + ','
    + CONFIG.preferences.get('deadzone_neg') + ','
    + CONFIG.preferences.get('deadzone_pos') + ','
    + watertypeToflag(CONFIG.preferences.get('plugin:diveprofile:water-type')) + ');';
  this.hardware.write(command);
  //This is the multiplier used to make the motor act linear fashion.
  //for example: the props generate twice the thrust in the positive direction
  //than the negative direction.  To make it linear we have to multiply the
  //negative direction * 2.
};

OpenROVController.prototype.sendMotorTest = function (port, starbord, vertical) {
  var command = 'go(' + this.physics.mapRawMotor(port) + ',' +
    this.physics.mapRawMotor(vertical) + ',' +
    this.physics.mapRawMotor(starbord) + ',1)';
  //the 1 bypasses motor smoothing
  this.send(command);
};

OpenROVController.prototype.sendCommand = function (throttle, yaw, vertical) {
  var motorCommands = this.physics.mapMotors(throttle, yaw, vertical);
  var command =
    'go(' + motorCommands.port + ',' +
    motorCommands.vertical + ',' +<commit_msg>Cleaned up unused functions and variables<commit_after>/*
 *
 * Description:
 * This file holds the controller logic.  It manages the connection to the Atmega328.
 *
 */
var path            = require('path');
var spawn           = require('child_process').spawn;
var CONFIG          = require('./config');
var StatusReader    = require('./StatusReader');
var ArduinoHelper   = require('./ArduinoHelper');
var logger          = require('./logger').create(CONFIG);
var EventEmitter    = require('events').EventEmitter;
var Hardware        = require('../' + CONFIG.Hardware);

var statusdata = {};
var settingsCollection = {
    smoothingIncriment: 0,
    deadZone_min: 0,
    deadZone_max: 0,
    water_type: 0 // FreshWater
  };

var rovsys = { capabilities: 0 };

var OpenROVController = function (eventLoop, client) {
  var controller        = this;
  var globalEventLoop   = eventLoop;
  
  this.physics  = new ArduinoHelper().physics;
  this.hardware = new Hardware();
  this.cockpit  = client;

  this.hardware.on('serial-recieved', function (data) {
    globalEventLoop.emit('serial-recieved', data);
  });

  this.hardware.on('status', function (status) {
    statusdata = {};

    for (var i in status) {
      statusdata[i] = status[i];
    }
    
    controller.emit('status', statusdata);
    
    if ('ver' in status) 
    {
      controller.ArduinoFirmwareVersion = status.ver;
    }
    
    if ('TSET' in status) 
    {
      var setparts = status.settings.split(',');
      settingsCollection.smoothingIncriment = setparts[0];
      settingsCollection.deadZone_min = setparts[1];
      settingsCollection.deadZone_max = setparts[2];
      settingsCollection.water_type = setparts[3];
      controller.emit('Arduino-settings-reported', settingsCollection);
    }
    
    if ('CAPA' in status) 
    {
      var s = rovsys;
      s.capabilities = parseInt(status.CAPA);
      controller.Capabilities = s.capabilities;
      controller.emit('rovsys', s);
    }
    
    if ('cmd' in status) 
    {
      if (status.com != 'ping(0)'){
        controller.emit('command', status.cmd);
      }
    }
    
    if ('log' in status)
    {
    }
    
    if ('boot' in status)
    {
      this.Capabilities = 0;
      controller.updateSetting();
      controller.requestSettings();
      controller.requestCapabilities();
    }
  });
  
  this.hardware.connect();
  controller.ArduinoFirmwareVersion = 0;
  controller.Capabilities = 0;

  globalEventLoop.on('register-ArdunoFirmwareVersion', function (val) {
    controller.ArduinoFirmwareVersion = val;
  });
  globalEventLoop.on('register-ArduinoCapabilities', function (val) {
    controller.Capabilities = val;
  });

  globalEventLoop.on('SerialMonitor_start_rawSerial', function () {
    controller.hardware.startRawSerialData();
  });

  globalEventLoop.on('SerialMonitor_stop_rawSerial', function () {
    controller.hardware.stopRawSerialData();
  });

  globalEventLoop.on('serial-stop', function () {
    logger.log('Closing serial connection for firmware upload');
    controller.hardware.close();
  });

  globalEventLoop.on('serial-start', function () {
    controller.hardware.connect();
    controller.updateSetting();
    controller.requestSettings();
    controller.requestCapabilities();
  });

  //Every few seconds we check to see if capabilities or settings changes on the arduino.
  //This handles the cases where we have garbled communication or a firmware update of the arduino.
  setInterval(function () {
    if (controller.notSafeToControl() === false) return;
      controller.updateSetting();
      controller.requestSettings();
      controller.requestCapabilities();
  }, 1000);

  return controller;
};

OpenROVController.prototype = new EventEmitter();
OpenROVController.prototype.constructor = OpenROVController;

OpenROVController.prototype.notSafeToControl = function () {
  // Arduino is OK to accept commands. After the Capabilities was added, all future updates require
  // being backward safe compatible (meaning you cannot send a command that does something unexpected but
  // instead it should do nothing).
  if (this.Capabilities !== 0)
  {
    return false;
  }
  
  return true;
};


OpenROVController.prototype.send = function (cmd) {
  var controller = this;
  if (controller.notSafeToControl())
  {
    return;
  }

  var command = cmd + ';';

  controller.hardware.write(command);
};

OpenROVController.prototype.requestCapabilities = function () {
  var command = 'rcap();';
  this.hardware.write(command);
};

OpenROVController.prototype.requestSettings = function () {
  //todo: Move to a settings manager
  var command = 'reportSetting();';
  this.hardware.write(command);
  command = 'rmtrmod();';
  this.hardware.write(command);
};

//TODO: Move the water setting to diveprofile
OpenROVController.prototype.updateSetting = function () {
  function watertypeToflag(type){
    if(type=='fresh'){return 0;}
    return 1;
  }

  var command = 'updateSetting('
    + CONFIG.preferences.get('smoothingIncriment') + ','
    + CONFIG.preferences.get('deadzone_neg') + ','
    + CONFIG.preferences.get('deadzone_pos') + ','
    + watertypeToflag(CONFIG.preferences.get('plugin:diveprofile:water-type')) + ');';
    
  this.hardware.write(command);
  //This is the multiplier used to make the motor act linear fashion.
  //for example: the props generate twice the thrust in the positive direction
  //than the negative direction.  To make it linear we have to multiply the
  //negative direction * 2.
};

OpenROVController.prototype.sendMotorTest = function (port, starbord, vertical) {
  var command = 'go(' + this.physics.mapRawMotor(port) + ',' +
    this.physics.mapRawMotor(vertical) + ',' +
    this.physics.mapRawMotor(starbord) + ',1)';
  //the 1 bypasses motor smoothing
  this.send(command);
};

OpenROVController.prototype.sendCommand = function (throttle, yaw, vertical) {
  var motorCommands = this.physics.mapMotors(throttle, yaw, vertical);
  var command =
    'go(' + motorCommands.port + ',' +
    motorCommands.vertical + ',' +
{'fraction_non_alphanumeric': 0.13149774507476858, 'fraction_numerical': 0.004272489912176596, 'mean_word_length': 3.709388971684054, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5368562', 'n_tokens_mistral': 3834, 'n_tokens_neox': 3707, 'n_words': 887}