-
Notifications
You must be signed in to change notification settings - Fork 5
Using ImcShell.jar
IMC Shell is a simple program that allows you to listen and send IMC messages from a command line.
- For compiling you need a Java compiler version 1.7+ (JDK) and the Apache Ant build system.
- On the directory where you checked out imcjava, run the command
ant ImcShell.jar
. This will create the file dist/ImcShell.jar. - To test the generated jar file enter the command
java -jar dist/ImcShell.jar
- For running you need a Java Runtime Environment 1.7+ (JRE).
- The file ImcShell.jar is an executable Java ARchive (jar). To run it just type
java -jar path/to/ImcShell.jar
.
While running you can access a list of available commands by using the command ?list
. Also you can get details about a specific command by using the command ?help
. To give an example, if you would like to know the arguments and description of the command bind, you would type:
?> ?help bind
When you start the shell you are given a clean environment with no messages stored. In order to add messages to your environment (for later composing other messages or sending them to the network) you should use the command create. Examples:
In order to create a message named myState of type EstimatedState and initializing it with default values:
?> create myState EstimatedState
To create a message named pc of type PlanControl and initializing it with given values. Any field values not specified will be initialized defaults. Also note that the value of field arg is assumed to be message previously stored in the environment:
?> create pc PlanControl type=REQUEST op=START arg=m1
You can also initialize messages by specifying valid (Java Script) expressions (escaping them with `):
?> create state EstimatedState lat=`3.1458+java.lang.Math.toRadians(41)`
After creation messages can still be changed by using the command change. To change the field lat of a message named m1 you could use:
?> change m1 lat=0.712399
You can replicate messages in the environment simply using the command copy. The following command will replicate an existing message (named m1) into a new message named newMsg:
?> copy m1 newMsg
When you create messages or you receive messages from the network these will get stored in the shell's environment. In order to access the current environment you can use the commands env and print. Printing all the currently available messages (in the environment):
?> env
Getting the value of a message named pc in the environment:
?> print pc
Getting the value of a field of a message in the environment:
?> print pc/arg
Getting the value of a field of a field of a message in the environment:
?> print pc/arg/lat
You can also use the environment when creating or changing messages like in the following (assuming there is a message named go1 with a field lat in the environment):
?> create go2 Goto lat=`${go1/lat}+0.5`
After a message is created, it can be sent to the network via UDP using the command send. If you know the port and hostname of the destination you can use the following command to send an existing pc message:
?> send localhost 6002 pc
You can also specify an IP address instead of the host name:
?> send 127.0.0.1 6002 pc
Moreover if you previously received an Announce message from the system you want to send the message to, you can send to it directly (you must have activated discovery as described in the following section):
?> send lauv-xtreme-2 pc
In order to activate IMC peer discovery and start receiving messages from the network, you must use the command bind. This command takes as sole argument the port you want to use for receiving messages. Example:
?> bind 6016
Afterwards, all received messages will be set in the local environment with a name <source>.<type> and it can be used in following commands.
You can run a stored script (sequence of commands) by using the (cliche built-in) command !run-script. This command takes as its single argument the filename to be executed:
?> !runscript SendAbort.ish
Moreover, when running scripts it might be useful to pause for a second or two. For that you can use the command sleep that takes as argument the number of seconds to sleep:
?> sleep 10
If you want to do a sequence of commands a number of times, you can use the command loop. Example:
?> loop 10 "sleep 1; print lauv-xplore-1.EstimatedState"
Finally, if you want to loop forever you can loop 0 (zero) number of times. The following script will forever print the latest EstimatedState received from the system named lauv-xplore-1:
?> loop 0 "sleep 1; print lauv-xplore-1.EstimatedState"
You can also execute a script file by passing it as an argument as follows (/path/to need to be changed obviously):
java -jar path/to/ImcShell.jar /path/to/script
Moreover in order to be able to execute any scripts you could also create an executable file in /usr/bin/imcshell with the contents:
#!/bin/sh
java -jar path/to/ImcShell.jar $@
Afterwards you can just add (in the beginning) the line #!/usr/bin/imcshell
in order for your script to be interpreted by ImcShell.
The following script can be used to initialize a vehicle simulator (send initial GpsFix) and command it a quick plan:
#!/usr/bin/imcshell
# Create an empty LBL configuration
create lblConfig LblConfig
send localhost 6002 lblConfig
# Create a GPS fix message to initialize the simulator (also passing it the current time)
create gps GpsFix validity=0xFFFF type=MANUAL_INPUT height=0 satellites=4 hdop=1 vdop=1 hacc=2 vacc=2
change gps "utc_year=`new Date().getUTCFullYear()`"
change gps "utc_month=`new Date().getUTCMonth()+1`"
change gps "utc_day=`new Date().getUTCDate()`"
change gps "utc_time=`new Date().getUTCHours()*3600+new Date().getUTCMinutes()*60+new Date().getUTCSeconds()`"
change gps "lat=`41.185 * (Math.PI / 180)`"
change gps "lon=`-8.706 * (Math.PI / 180)`"
send localhost 6002 gps
# Wait 3 seconds for the simulator to attain a sane state
sleep 3
# Create a quick plan which consists of a single maneuver and command it to the vehicle
create go1 Goto lat=`41.185*(Math.PI/180)` lon=`-8.705*(Math.PI/180)` z=2 z_units=DEPTH speed=1.2
create pc PlanControl arg=go1 type=REQUEST op=START flags=0
send localhost 6002 pc
The following script can be used to define, send to the vehicle and command execution of a cyclic plan:
#!/usr/bin/imcshell
# Create 2 Goto maneuvers
create g1 Goto lat=`41.185*(Math.PI/180)` lon=`-8.705*(Math.PI/180)` z=2 z_units=DEPTH speed=1.2
create g2 Goto lat=`41.184*(Math.PI/180)` lon=`-8.706*(Math.PI/180)` z=2 z_units=DEPTH speed=1.2
# Create a wrapping PlanManeuver message for each of the maneuvers
create p1 PlanManeuver maneuver_id="g1" data=g1
create p2 PlanManeuver maneuver_id="g2" data=g2
# Create two transitions (resulting in a cyclic plan)
create t1 PlanTransition source_man="g1" dest_man="g2" conditions="maneuverIsDone"
create t2 PlanTransition source_man="g2" dest_man="g1" conditions="maneuverIsDone"
# Create the plan specification by passing the maneuvers and transitions created
create spec PlanSpecification maneuvers=[p1,p2] transitions=[t1,t2] start_man_id="g1" plan_id="cyclic_apdl"
# Create a PlanDB message to command the vehicle to load the plan
create pdb PlanDB type=REQUEST op=SET request_id=1 plan_id="cyclic_apdl" arg=spec
send localhost 6002 pdb
# Wait for 1 second
sleep 1
# Request execution of the sent plan
create pc PlanControl type=REQUEST op=START flags=0 plan_id="cyclic_apdl"
send localhost 6002 pc