Aqua stuff...

PPP connection

pppd /dev/ttys0 passive noauth lock proxyarp 115200 192.168.2.2:192.168.2.1
then you can do ssh or telnet to the ip. For  Ubuntu, the command is:
pppd /dev/ttyS0 115200 passive noauth lock proxyarp 192.168.2.2:192.168.2.1


The serial port devices in QNX are named /dev/ser1 and /dev/ser2

To start simsect on a machine:
Window 1:
in SWRI/Supervisor do:
./start.sh
Window 2:
in Operator do:
./start.sh 3000 localhost 5000
(The last 5000 indicate the remote port, default value. The 3000 indicate the OCU port, and can't be the same as 5000 otherwise they would collide).

Go in RoboDevel/RHex to build.
Do a make depend to get the proper dependencies.
Do a make distclean in the fltk directory to clean up the installation.

To plot the data collected by the logger, you can do a small script like this:
angles = [data.Microstrain_Angles];
x = [data.time];
subplot(3,1,1);
plot(x,angles(1,:));
title('Roll angle');

GUI/OCU stuff:
1) Add the variables in the .mod file
2) Compile the robot, otherwise the accessor variables won't be accessible in the GUI tool.
3) Start the GUI without any arguments: ./start.sh
4) Do panel edit in the [Panel V] button.
5) You access/update the variable in the mode.cc file.
5) When you save it, make sure it's in the ../SWRI/Operator/RHexPanel.cfg file.
 
Files involved:
*ModeStructs.hh
*Mode.mod
SWRI/Operator/RHexPanel.cfg
Operator/UnderwaterSwimmerMode.acc
Operator/RHexPanel.cfg


To get a scaling factor for input command on a slider for example:
1) For the widget you want to be scaled, in the Widget panel, set the partner to your scale variable name: $SCALE_XXX. Set mode is Multiply.
2) As a scaler, you can use a Slide bar. Use the variable name $SCALE_XXX as the accessor. At this point I am not sure if the $ is required. But eh! it works.



Test tools for QNX H/W platform are available in directory:
RoboDevel/RHex/RobotCode/TestTools

The common directory is
/home/exchange/AQUA_Team/

Possibility of using firewire for communications: "Ethernet over 1394" linux or "IPv4 over 1394".
In the mean time, we could use USB connections and adapter:
http://www.accesio.com/go.cgi?p=../serial_com/usb-232-422485.html
With QNX support: http://www.sealevel.com/products.asp?bus_id=5&USB_RS-232%2C_RS-422%2C_RS-485_Serial%3B_Digital_I%2FO__+
Another solution would be to place the PCMCIA card in there... maybe it is not so feasible.

To set up the dhcp on QNX on an interface:
dhcp.client -i en0
you might have to manually change the entry for en0 in net.cfg to
[en0]
type ethernet
mode dhcp
from
mode manual

Linux

To use the USB keys on the desktop machines:
cd /r/a1
don't forget to cd out of the directory when you are done, to write the files to it. Paul had a bad experience about it.

net.cfg contains network configuration information

To look for a string in files of a given directory tree, you can create a small script file:
find . -name "$1" -exec grep "$2" '{}' \; -print

To copy a compact flash, it seems it's something like
dd if=/dev/hde of=name_of_image

To tar a whole directory, simply do:
tar -cvf target.tar dir

To run eclipse in linux (located in the mrl common directory) you might want to use the following command if it can't find the JRE:

./eclipse -vm `which java`

To find files that have been modified recently in the RHEX directory, I used the .cdtproject file as a yardstick. It seems to be working.
find . -name "*.??" -newer .cdtproject -print

To create .gif of equations, use textogif function. Its manual can be found here.

On terra, to use the DVD/CD-ROM, you have to first open a terminal window and do:
cd /removable
cd /cdrom
then you'll hear the disc spin and you are all set!
to unmount it, just close all the windows and the terminal window referring to it.

Joystick
In ubuntu, you need to install the joystick package. you should see the joystick device as js0, either at /dev/input/js0 or at /dev/js0.
you can use jstest js0 to test the joystick connectivity. you then have to create a symbolic link to point the /dev/js0 to /dev/input/js0

It seems that the "orbital" usb pad works better with my laptop and kernel 4.26.  the AQUA usb pad has some axes mixed up.
jscal will calibrate the joystick.


To install a package in ubuntu
dpkg -i ***.deb

To mount usb stick:
fdisk -l   ---> to list all disks and their format. USB most probably fat16/fat32.
mkdir /media/usbstick
mount -t vfat /dev/[nameofdisk] /media/usbstick

Control Theory
A quick way to compute an IIR first order low-pass filter is with a function:
gain = exp(-SamplingPeriod/FilterTimeConstant);

inline float IIR(float old, float in, float gain)
{
return old + (1.0-gain)*pi_adjust(in-old);
}


RHex
fModifications to do the Aqua branching:
  1. Add AQUA_TOPDIR, AQUA_HARDWARE environment variables.
  2. Add AQUA_HARDWARE in RoboDevel/setvars.sh
RHexLib

if you have an undefined reference to vtable, you are probably not linking the .o files together.

ModeSupervisor.cc manages the modes. The update() function within that module is in charge of checking to see if the database has changed. The database will contain the requested mode from the GUI. The structure ModeSupervisorCommands_t is used as a container for the Mode change.
The update() is done with the following stack/function calls.

#1  0x081108aa in ModuleManager::updateModules() (this=0x81b29e0) at ModuleManager.cc:387
#2  0x0811121c in ModuleManager::runLoop() (this=0x81b29e0) at ModuleManager.cc:617
#3  0x08111202 in ModuleManager::mainLoop() (this=0x81b29e0) at ModuleManager.cc:606
#4  0x0804c9f5 in MMMainLoop () at /home/discovery/philg/aqua/RoboDevel/Libraries/RHexLib/include/ModuleManager.hh:430
#5  0x0804c77a in SupervisorBase::run(bool) (this=0x81b91f0, safety=true) at SupervisorBase.cc:121

UpdateDatabase()
#0  UnderwaterSwimmerMode::updateDatabase() (this=0x82885b0)
    at UnderwaterSwimmerMode.cc:297
#1  0x081108f6 in ModuleManager::updateModules() (this=0x81b29e0)
    at ModuleManager.cc:386
#2  0x08111268 in ModuleManager::runLoop() (this=0x81b29e0) at ModuleManager.cc:616
#3  0x0811124e in ModuleManager::mainLoop() (this=0x81b29e0) at ModuleManager.cc:605
#4  0x0804c9f5 in MMMainLoop ()
    at /home/discovery/philg/aqua/RoboDevel/Libraries/RHexLib/include/ModuleManager.hh:430
#5  0x0804c77a in SupervisorBase::run(bool) (this=0x81b91f0, safety=true)
    at SupervisorBase.cc:121
#6  0x0804ad3f in main (argc=1, argv=0xbfffda04) at supervisor.cc:118
#7  0x420158d4 in __libc_start_main () from /lib/i686/libc.so.6

The time for propagation could depend on this:
DBBase::DBBase CommManager mgr,


int  fundamental_rate,


int  priority = -1


 

This constructor creates a database using communications manager "mgr" with a fundamental rate "fundamental_rate". This rate indicates roughly the minimum time in milliseconds between periodic updates and the minimum rate at which immediate changes will be propagated. Both database manager and database clients create an entry monitoring subthread which runs roughly every fundamental_rate milliseconds. If priority is negative, then this sub-thread runs at a relative priority of the current thread priority plus priority. If priority is positive, then the sub-thread will run with the absolute priority priority.


In BaseGUI.hh, a whole bunch of parameters are defined. One of them sets the update rate of the database, in ms. Somehow this parameter seems to have a 1,2 or 3 times multiplier
#define BB_UPDATE_TIME 200


The underwater structure names are defined in a header file. The #define command sets it for example to:
UWSM_CURCOMMANDS_ENTRY_NAME
The function BBAccessor::initialize in BBAccessor.cc reads the configurate file and register all the interesting variables, at least from the Underwater module point of view. The database update time is set through the function call of PanelGUI::initialize in PanelGUI.cc.



Hardware "interfaces"

There exist a bunch of standard hardware interfaces that are for each type of robot. In our case (AQUA), it is in the RuggedHW directory that you find all the AQUA-specific generic hardwares.


Replacing the rhio board
The best of course would be a drop in replacement and an interface file. If we look how it is currently done in the RHex platform, we have the ruggedMotor.cc and ruggedHardware.cc files..  Functions to watch out for:
PowerHW::instance()->voltage();
analogIO->write()
analogIO->read
analogIO->readOutput

The data is pumped from the rhio board by the rHioReaderModule. The function called in the update() loop is downloadFromRAM(). Data is sent to the rhio board via the rHioWriterModule(). the low level function called is uploadToRAM(). So it seems it is a memory mapped driver data transfer. If we could align the memory block to be exactly the same for the MPC555 and the rhio, then that part would be taken care of automatically.

The quadrature decoding is done elsewhere. It would have to be mapped in a different memory area than the rhio stuff, possibly continuous.
rhexio.hh defines the rinp function, which is in8 and roup which is out8.
config.hh defines the base address for the hardware:
#define RHIO_BASE_ADDR     (0xfc00)
#define MSIP400_BASE_ADDR  (0xfbe0)

Motor control for AQUA
The motor control is done through the PositionControl module and the EncoderReader module. The desired position and velocity is set through the setTarget() method. The Target is defined as:
Target structure
Motor gain structure
typedef struct {
  /** Position target */
  double    pos;
  /** Velocity target */
  double    vel;
  /** Acceleration target */
  double    acc;
} MotorTarget_t;
typedef struct {
  /** Proportional gain */
  double        kp;
  /** Derivative gain */
  double        kd;
  /** Acceleration gain */
  double        ka;
} MotorGains_t;
getTarget()
setTarget()
getGains()
setGains()

The PositionControl module is derived from MotorControl base class.

There seems to be some torque computation done in the ScoutBound module:
void ScoutBound::Stand( void )
{
  int i;
  for (i=0;i<6;i++)
  {
    poserr[i] = 0 - enc[i]->getPosition();
    speederr[i] = 0 - enc[i]->getSpeed();
    torque[i] = gains[i].kp * poserr[i] + gains[i].kd * speederr[i];

    control[i]->setTarget( &(tar[i]) ); // set a target simply for the
                                        // purposes of logging
    control[i]->setTorqueOffset( torque[i] );
  }
}


The error The CLASS function must be called from a class constructor has something to do with a @ or linked directory. see the ~/aqua/matlab/nn/kdtree for an example.

Further Readings

Some ways to measure fluid flows: from MIT final paper and here.

An underwater glider named Spray

Charlie MIT swimming tuna, to test the Gray paradox (that swimming has 1/7 of the drag of a non-swimming body)

Efficient walking robots:
Press release from Cornell

Things to read:
Hybrid controller for walking