I wanted to start a conversation about how to structure the configuration for a robot running MyRobotLab.

Having a consistent configuration that is flexible that defines the services that are started and how they attach to each other would be a great starting place.  

Going beyond that, it would be nice to capture the mechanical structure of the robot to define how long the arms and legs are, how heavy they are, and all the other physical aspects of the robot would be nice.  Let's consider this part phase 2.  (we could potentially leverage something like URDF   (Universial Robot Descriptor Format) as this is used by ROS.

 

So, back to "phase 1"..  the basic requirements that I see are the following

1. define a set of services.

2.defined the connection between those services.

3. as a nice to have, it'd be good to "group" services.  (For example,. these 6 servos, and these 5 pressure sensors define the hand.)

 

We should use a well structured config file format for this configuration.  That format should have support in most popular file editors and IDEs, so that really leaves the list to the following formats.  (I have added comments as my thoughts on them.)

1. XML - very old standard.  Supported by pretty much everything.  Looks like HTML so the syntax is widely understood.  Has DTD / XSD definitions that allow you to specify the valid format for the XML.  Many editors have auto-completion for XML if a DTD/XSD is defined.   XML files tend to be larger in file size due to all the markup around the config properties and values.

2. JSon - more modern, very compatable with javascript based web applications.  much more lightweight than xml in terms of syntax and markup.  No official structure definition to validate that it's a valid json format.  This is commonly used in object serialization as it's more effecient than XML.

3. YML - this is yet another markup language... It has almost no markup, except for new lines.  It's white space sensitive.  It usually requires special parsers to be able to read and write these files.

4. flat files & non-standard formats  .. let's not go there.

 

In addition to these config files, it's nice to have an additional "property" file.  That allows you to subsitute values into the main config so you don't have to edit a full config file to change something like a com port.  One goal is that you should be able to use the same config on 2 different InMoov's and the only thing that would be different in the config would be the properties file.  (this is easy to add while we do it..  People can choose to use this feature or not.  It's up to them.

I guess with that above,  I think I'd advocate for either JSON or XML.  JSON is a bit easier to work with due to the large number of serialization libraries that exist.  (currently we use the GSON library in MRL for this.)

Next, we need a way to load  (and potentially save) robot configs.  My initial thought is that we should give this task to the Runtime service.  Which means, at a minimum, a "loadConfig" method on the RuntimeService.  

The design should represent the Config as an actual Java object  ( POJO ) .  The loadConfig method would deserialize the config from the json file into the config object.

The config will be fully parsed at this point.  So, the list of services and the list of attachments would be defined.  There are 2 loops.

1. launch all services

2. create the attachments between the services.

 

At that point all services should be started and wired together.  Detaills about the configuration of the service sould be provided in the service definition of the config.  (ex. min/max values of the servo position.)

 

And most imporantly.

The config loading needs to be documented & autotested

thoughts welcome...

 

 

 

 

moz4r

5 years 11 months ago

Hi Kwatters ! About the structured config file point in your post I don't think we need a new structured config file environemnt ( I think scripting is enough ), but global property file like you said to override things is a good idea.
I'm afraid about multiple places to drive things, that's why I plan to remove/evolve inmoov1 configuration system.

We already have one structured config file ( that worky like a charm ) : this is related generated json for services. I explain with a worky sample : today if we close mrl every servo last positions are stored inside servoX.json. ( lastPos ) . Now if you open mrl again your servo init the last know position.
Same thing for default voice for speech , etc ... 

We just need to do same thing for min/max , default controller etc ... for every services. Just 1 or 2 code lines to deal about default values. 

Play with a cursor and magically saved. Transparent for all but tweakable for all.

So if we want to change min/max we can use a common scripting method to everride or gui if we use it. I like the idea to use existing json for services. so close to code.

I agree that is limited because it is service related, that's why you want maybe a new place to store attached things outside the scripting, like

sensor01 > finger02 > hand01 ...

The bigest problem I see with the current config setup is the in-ability to define a diferent type of control system.

The config assumes that you are using one or two Arduino's to drive all the IO. 

There are some hardware arangements that do not have any arduinos at all, but instead use the I2C bus and the Adafruit 16 Channel I2C servo drivers and I2C based remote IO device for input and or output from devices like the PIR and normal LED lights or relays to provide power bus isolation.

While the relays and extra LED aren't part of the inmoov scripts, the PIR is, as is all the servos.

This may yet become more complex later as sections are upgraded with stronger DIY servo for the likes of the bicep, elbow and shoulders, as the contruction methods being devoloped for the leg projects are then implemented in the upper body as upgrades.

Inmoov is an incredible project and has to potential to be so much more than was first envisaged, what we need is a configuration setup that lets us define the service and service support service independant of the scripting. 

I think a mix of what we have and what Kwatters is suggesting could be the best way forward.

We need a definition of standard end service names such as IO1.left.arm.elbow.servo

On first setup that could be configured as a standard Inmoov with Arduino and Nervo boards would be done.

We then allow the user to create new runtime service such as Raspi, then Adafruit16CH driver and then change the existing servo reference to use the adafruit I2C driver, this config then gets remembers in a jason file for the next time the system is started.

If we look at the overall sysem assembly, then maybe we need to add to each of the services a disable config, this could be in the form of a check box, when a service is diabled, the the service description becomes a place holder for the service, any other services attaching to the service would by definition be disabled as well. while a service is disabled, MRL should not try and access the hardware that the service describes.

That way, all potential service used in the default Inmoov setup could be defined and most disabled.

The GUI is easy for any user to access and change, so as the users add parts to their builds they can go in and enable what they need and even change the pin connections if needed without having to find the correct config file to edit and restart MRL.

At this point I would suggest that the startup command line then contain the config file that you want to start with, that allows a tes config to be used when testing new hardware.

Thats just my two cents

 

Ray

GroG

5 years 11 months ago

There is currently support for saving most settings in each service.  Its done in JSON format, and its saved and loaded from the .myrobotlab .

I think going forward the "attach" concept will help us by simplifying our code & configuration.

 

1. define a set of services. (and config)

s1 = Runtime.start("s1","Servo")
s2 = Runtime.start("s2","Servo")
arduino = Runtime.start("arduino","Arduino")

1.5 configure them

s1.setPin(5)
s2.setPin(7)
arduino.connect("COM4")

2.defined the connection between those services.

arduino.attach(s1)
arduino.attach(s2)

I've tried to keep the interfaces very minimal.  This potentially could be what is used to start, configure and run any service.  You could separate them into different files.  Even "override" configuraiton by running another config file (last one wins).

I don't know what benefit we get by exchanging the python above for some other format (json, xml, other?), Especially, if the python is actually smaller in size than a proposed config file.

The grouping of services were the intent of the InMoov services.  Also the InMoov service itself is similar to a Factory pattern .  It "creates" sub-parts e.g. i01.startLeftHand("COM8")  i01.startRightHand("COM10") . 

I think one of the biggest issues at the moment, was the idea that Arduinos were always to be used.  A refactoring which could fix this is having the ServoController externally defined.  Instead of the COM port being passed in - you would just pass in the servo controller.

controller = Runtime.start("s32", "Ssc32UsbServoController")
i01.startLeftHand(controller) 

Our objective should be allowing flexibility, but attempt simplicity. Defaults are ok, as long as they don't interfere with flexibility (as the defaulting Arduino did in InMoov)

 

 I sort of agree with you Grog on the InMoov config, but also have my reservations.

A lot of the new users have trouble navigating the current config files and their layout, the layout is good, but can be difficult to follow for a non programmer.
They were laid out the way they are because the scripts assume you will be using an Arduino or two and the end user knows a bit about programming.

What if we separate the service configuration away from the running scripts.

Have an official defined set of servo names and IO devices that the scripts will use, the way the service are defined then do not affect the runtime scripts at all.

The initial configuration of the service can then be done by a run once script that then triggers a save config function within the runtime service. 

If the Runtime service is launched with a config name specified, that config can be loaded, if the config named is not found, then a config not found flag can be set, the InMoov scripts can check for this flag at startup and run the service setup script for a default setting.

The end users will find it easier to then use the GUI to then adjust the min/max setting, change the pin numbers or even the controllers for the more adventurous builders.

If the option was there to save the setting direct from the GUI it would make it easier for the end user, we have two great GUI's why not take advantage of them beyond a bit of debug....

Most of the questions that are answered on the InMoov forums is around the basic configuration.
While developers have no trouble working out the current configuration and exploring the scripts that run the InMoov, most of the users don't know how to program at all.
The ones we see in here have some sort of programing ability ranging from basic like myself to advance like yourself.  Those without programming ability tend to stay in the InMoov forums, this place scares them :-)

There is a whole new group of users out there as a result of the cost of 3D printing falling and the technical knowledge required to run a 3D printer diminishing. 
Site like Thingverse are introducing new users to advanced designs, and they are now able to print those without too much trouble. 

I think we are going to see more and more of this type of user looking at MRL for the control system, and if the control system is easy for that type of user, the places MRL will be used will expand.

It's just my thoughts, but my views are tainted from working with non technical users in a technical environment.

 

Ray

Good input Ray.

Ahhh .. the GUI(s)  :)

Yes, this is our interface to humans, so absolutely .. it is very important.  However, I think there  should be another form of refactoring there.

Our GUI's show or control only the current state.  That's why when you start inmoov you get a bajillion tabs which are nearly impossible to navigate trhough.  I'm squinting for waaay too long scanning the skittle tabs looking for a specific service. 

What our GUIs lack is a "WORKFLOW".

"As a beginner", I want to be guided through configuration. If I press the Start InMoov button for the first time - I want it to ask me what parts I want to start, maybe I just bullt a hand.  It can ask me what controller I'm using (Arduino, RasPi).  In case of Arduino it can help me load MRLComm on it.  It can step me through the process of moving fingers and helping me calibrate min & max.  When the flow is done, it can save all this information in a Python script - which looks similar to what I was describing before.

At this point for the webgui there are quite a few libraries which are made for this concept.

https://ourcodeworld.com/articles/read/328/top-10-best-tour-website-gui…;

Let's look at one - go here - https://introjs.com/  and press demo.

It's currently doing an "Intro" of itself, but it could just as well step you through the configuration of InMoov. Under the hood it would be saving out a Pythong script to quickly run with a single button.

Even if the user did not have anything built, they could step through the intro and it would guide the user to configure a virtual inmoov - again saving it to be run (as a python script under the hood) with a single button.

To take it even further, the InMoov build itself could flow through an interfactive tutorial where the code and the parts are being built and tested together.

As far as naming yes - standards are very important, and that is what the InMoov service with the factory pattern does.  It names everything "to spec".

The idea of a setup script is great, but I still think we need to be able to go into the individual servo config if just to adjust the Max/Min and Map settings, especially after servicing the hands or re-fitting a servo that results in a slight misalignment compared to the original point.

This would be nice to be done under voice control, but I don't think that's reliable enough yet..

Your quite correct about the number of tabs in the GUI, I tend to use SwingGUI most of the time, but remotely WebGUI would be the same.

When running the InMoov service, i note the the objects are arranged in groups, starting with the InMoov group first.

If we work on the bases, that only the end service should be in this structure, could we not have collapsible tabs in the GUI.

In the GUI you would have the Welcome, CLI, Log, Runtime and python tabs, you could than have the InMoov tab.
The InMoov tab is simply a Structure place holder and in the GUI, an expandable tab.  In its user interface box, you can list the possible tabs that open when you expand it.

In this example, expanding the InMoov tab would add tabs for Brain (ProgAB, Speech, Ear ect), Head, Torso, LeftArm, RightArm, Legs.

this allows you to then expand out each section drilling down as it were to the target servo or sensor for calibration or adjustment.

At the top level, you would have the controller service, such as Arduino, Raspi, Adafruit ServoDriver ect.

Its just a thought, the search option would be good as an either or approach as well.

 

GroG

5 years 11 months ago

Another enhancement for the gui I would like to do is "Search"
Looking through a bajillion tabs is no fun..  I want a text box I can search by name or by type and have stuff come back.
 

I did this for RuntimeGui searching through service types of services and now use it all the time..

I want a box I can search for leftHand and it immediately brings up all the parts related to the left hand for finer control or configuration.  I think beginners & intermediate users might benefit from this.

GroG

5 years 11 months ago

Jenkins is one of the most complex, yet well designed software projects I know ... It's building the mass technium's brain every day...   

To me, its an actual pleasure to install this software ..
It switches from a native installer to a web ui quickly.

It has a workflow were you modify things to your liking

And then an install phase 

Imagine an install workflow for InMoov that started like this - with configuration stages - but final outcome would be a python script.  The "user" does not need to be aware of the python script - because its auto-magically run at the end.   "When/If" a user is interested in details of tweaking, or want more advanced control - they just find & use their python script as a starting point to hacking !

Like it !

The "searchbox" will be so very useful ! While I'm thinking of it maybe a new level of tabs will be useful also : 1 hand tad > 5 subtabs etc .. just an idea because on some computers the main screen if very "full" . because of too many servo controls.

kwatters

5 years 11 months ago

This is exactly the sort of feedback that I was hoping for!  Wow, where to start.. first, I think we should wait until after Nixie before taking on this configuration topic in much more details.

This does not mean that we won't do it, but I don't want it to distract us while we're making sure the plumbing is in good shape with Nixie.  (This has been a lot of work and it's been pretty amazing to see it come together.)

I also really like the idea of search in both the swing gui and the web gui and having interative dialogs and tutorials built right into the gui.  This is probably the best for of documentation to get people started quickly.

Ok, so onto the core topic at hand.  I gather a few things from the comments.

1. there's not much appetite for yet another config system. (and this is OK)

2. there is some json service state serialization support already, and we shouldn't ignore that.

3. there's an existing system for configuration of the inmoov with the inmoov ini config files, and we shoudln't ignore that.

4. having a configuration based approach to launching and attaching services seems like a good idea, and one form of configuration could be python scripting (or json, or xml, or other)

5. having a GUI is better than having config (sometimes) so long as you can save and restore state of the gui/ config

Ok.. so now what to do..  it seems like the best approach would be to just have configuration that is saved as python code and loaded that is python code.  This is inline with an approach that has worked for me in the past with the InMoov load & saveCalibration methods...  We could try to have the MRL generate and save it's config as standard python..

Either way,  I think the conversation should continue, and perhaps the first focus on this really should just be some polishing of the InMoov swing/web gui and enhancing the abillity to load and save the current config.

This might go the farthest the quickest to have a nice quick win to make inmoov development and testing easier...  

(we might want to consider doing something for those out there who are interested in non-inmoov related robots and their configurations.)

 

For me, i agree with Grog, we should have a factory standard, name specific and stick to it.

Most inmoov builders do not have any clue whatsoever on coding, and they are soon bailing on MRL and i see that ezb is wheeling them in (although they have a basic gui, if you want something done, its coding time.)

Back on topic, We all can code, some have the fuuu way better under control then others but we all know what mrl is and does. But new members get lost in tabs, configuring, calibration, editing files, searching for files and not even talk about programAB...

I like the idea that a run once file (like the old install or config file) guides you through the troubles of setting up your inmoov. Now that the  raspis are getting more used, the jetson, and other nice systems we should make it not only arduino based. (that way it can be adapted for any robot without much work, inmoov is a part of mrl but is see r2d2's are getting more popular too.)

The trouble always is that when many people work on a project there are many opinions. Some prefer the notepad, some the whiteboard and some a touchscreen. But mostly that is based on personal preference and based on the level of what realms within your posibilities. My suggestion would be to use a model/system that has been proven to work, that is easy for the end user but would still be useable for a coder. 

 

"As a beginner", I want to be guided through configuration. If I press the Start InMoov button for the first time - I want it to ask me what parts I want to start, maybe I just bullt a hand.  It can ask me what controller I'm using (Arduino, RasPi).  In case of Arduino it can help me load MRLComm on it.  It can step me through the process of moving fingers and helping me calibrate min & max.  When the flow is done, it can save all this information in a Python script - which looks similar to what I was describing before.

Personally i think Grog hit it dead on. If thinking with the end user in mind, but as Ray said we also have to tweak if we add, subtract or edit the system.

The idea of a setup script is great, but I still think we need to be able to go into the individual servo config if just to adjust the Max/Min and Map settings, especially after servicing the hands or re-fitting a servo that results in a slight misalignment compared to the original point.,

That way we can always override the system, keep it simple for new users but when they understand how it works and they learn how to tweak or want to learn how to tweak the system they can.

 

And as someone who cant code as most of you can, i dont know how hard is is to implement but i agree that it should be done the right way, not just implement it as fast as possible and determine that it was ok but not what we need. So Kevin is right that it should be for Ogre and not Nixie because it is very important to make it is not only made to work with inmoov, but it is made to work with something like domotica, r2d2's, animatronics, Work-E and all the projects we are going to make in the future.

And as i said before, im totally not a coder and for me you guys are truly the greatest in code-fuu so i cant even understand what it would take. I can only give my 2 cents as a 'newbie' in code and i always think how would a 'newbie' look at it.

This has been way more that i wanted to type, so forgive me, i am giving my opinion.

Myrobotlab Rulezzzzz