InMoov Behaviors and Events
General idea here is to facilitate the requirements of behaviors and desired InMoov events and potentially implement them in a "non brittle way". Not sure how to implement this, but I know the solution isn't to "add them all to python" or "put them all in Java". Possibly it wll be to have extensible service methods which allow stable and extensible behavior or event growth.
- Health Check - checks battery, list of other things to check
Random Movements - random movements, always stopped when a gesture is in process.
Could be isolated to skeleton area. e.g. head, left arm, right arm, "all" etc...
- Random Tracking/Scanning - with opencv filters finds or track an object - stores or reacts to objects found in images or tracks an object it found - saved with meta data
Sleep Mode - only activation sensors are on - list of sensors to wakeup PIR, other...
auto sleep mode after some time of inactivity of list of sensors
- Some utilities or helper methods for AudioFile which will help play lists of files (shuffle, repeat, etc)
- Scheduled events - download news, mail, weather, other ...
- Default behaviors assigned to NeoPixel - emotional/error related other ..
- Default behaviors associated with ultrasonic sensors
- Default behaviors assoicated with finger sensors
- Default eyelid behaviors
- First time setup behavior
This is just to start the dialog.... (while I work on a general way of exporting service config that might be satisfactory for InMoov)
Nixie InMoov Config Proposal
Here is my proposal to manage Nixie InMoov configuration
I got input from Gael regarding how previous configuration worked in Manticore. I'd like to propose this for Nixie.
A single gigantic python file is way too overwhelming for regular users, me included..
Yet we want to make config exportable in a general way.
I thought about this problem for a while and came up with this possible solution which is general and might satisfy the requirements of being clear and simple to use.
What if we had an export - which exported a master config file for a complex service like inmoov, and all its peers as separate files ?
An example of how this might look like is this:
Where each file is a peer, and a master _config.py give you the easy ability to turn off or turn on the other files/peers.
The folders would be viewable in the InMoov UI here
Exporting the config from here would export all peers and their configuration into a new directory supplied by the user. The _config.py would be exported with the information regarding which peers are currently active.
Here it is ! ... all the peers of InMoov2 (only the first level) - the importan part is this UI was "generated" not hand coded ... on closer inspection it does generate some questions ....
Like why is head.rothead & head.neck defined as a peer if i01.head already has them ?
And controller left, right, controller3, controller4 ? Gael explained it to me once, but I really don't understand ... yet ..
saving and loading the configs...
We definitely need a better more consistent story around configs. We are in full agreement. We also, want to make sure the configs are easy to edit & understand.
A nice to have would be that all custom configs would live in the "data" directory, where as all default configs would live in the "resource" directory.
Long ago, we had a SaveCalibration and a LoadCalabration method on the InMoov, it would write out python that described all of the servos positions, pins, controller, min/max mapping info.
That served me very well with harry. I could load harry, use the gui to modify the servo configurations, i could save that out ... when the inmoov would load up, i could source my calibration.py file and all the servos would be attached and defaults like the rest position, velocity , etc, would be worky.
Reality is, we relied on the java code to generate the python code. But there was really no easy way to ensure that the generated python code was syntatically correct, as we refactored interfaces.
Another observation was that depending on when you load those calibratoin scripts, they might or might not be successful. You couldn't run those first and expect the services to already be created. You couldn't load them last, because then the inmoov starts up and went through some initial movements.. ..
Additionally, if the servos were detached or not enabled, they would ignore the moveTo calls. So, the saveCalibration script had to play some games where it would detach, configure, re-attach for each servo being configured.
Ultimately, it was a successful approach, it was easy to maintain the detailed configurations and servo calibrations for Harry, however, i felt like the fragility of the python as an intermediary was less than ideal.
So.,.. let's look at how the ServoMixer was desgned to work. It was specific in that it only targets the servo services. For each servo, it would grab the info about where the servo is, and it's velocity. It creates a Pose object that contains that info. Then it writes that pojo to disk as a json file.
The serov mixer then can read that json file back into a native java object directly. The servo mixer knows how to work with that Pose.java class and programmatically, it can restore the desired state from the info stored in the pose.json.
This apporach defines the configuration as a pojo. It creates methods on the servies that can load that pojo speciffically for the configuratoin options that users care about. (the intiial set being the params that are currently in the ini files.)
I feel like Service X shouldn't require a Python service to be able to save and load it's config.. that Service X should be able to deserialize it's config, and then apply that config, all natively in java.
A move in the right direction
We also need an easy way to add additional hardware and move services to use them.
In the example config for the Raspberry Pi, it shows two Adafruit servo drivers, whitch is what I currently have in Fred.
But one I attach his arms, there will be two more with servos attached to those.
Also thinking ahead a bit, the ability to add in two or more IMU such as the MPU6050 currently supported by MRL and typ those into the neck servos as well would be handy. (Not quite sure how this would be done in the Inmoov service)
What could also be useful is a way to read and write files in plain text files.
Do you remember from the days of computer antquity there used to be a set of functions that would allow you to read configuration pairs and groups from a text file?
Something akin to that would be handy when trying to program in self calibration features when using sensors for limit monitoring.
There is also the thought, that if you use the same servo service name through multiple projects, like Config_Project and Run_Ronot project, you could just use a save and load config file for that servo name...
On service start, check and see if a config file exists for that servo service and load it if it exists.
It's just a thought.
I like the idea of defining a set of "states" that the robot is in...
We can then group the behaviors that are applied when in each state. and potentially a sequence to switch from one state to the next.
The transition from bored to paying attention could disable the random activity... the transition from sleeping to paying attention could turn on the camera and microphone...
That might be an easy way for us to organize the behaviors..
Heh, I started mapping out
I started mapping out a State Diagram with what you said, then in the process remembered ...
"wait" I made a service for that .... http://myrobotlab.org/service/finitestatemachine
The FSM service is a way to build state graphs dynamically.
The Emoji service uses FSM ... hmm someone should document that too :P
At least there is a JavaDocs for it, I might have to have a play with it a bit later on. :-)
I've sort of been hooked with some of the filters in OpenCV, these may serve as input to changing state in a FSM....