First Rule of MRLClub is everyone has an opinion and ideas, and you will treat each other with respect and kindness - even if you totally disagree.... its an easy first rule...
I'm always learning things in MRLClub. Recently, I've learned how 5 people can successfully work together simultaneously on a piece of code .. Whoa ! Very cool.
Here is my MRLClub log :
Where we've been (Aka the problems with old MRLComm)
Here's a laundry list of problems with MRLComm
- Messages seemed to disappear
- Communication mysteriously stopped
- Debugging was difficult
- It was written in C
- Its not an Arduino library
- When compiled and uploaded to an Uno - the uno would complain with memory warnings
- MRLComm would sometimes lobotimize itself without warning
- Custom messages and custom MRLComm code was used to support different devices
- AFMotor control used a weird 'customization' of code for attempt of support
Where we are (Aka - the work we are doing now)
- C++ classes - modular "Devices"
- Dynamically created Devices
- Low memory footprint
- Easier to debug
- Structured Writing & Reading of Devices & Sensors
- Structured attaching of Devices and initialization of config
- No need for "custom" MRLComm(s)
- Wider support for different Devices & Sensors without the need of modification
- PinArray will offer potentially faster pin reading (both Digital & Analog)
- Mats implemented I2C gateway device !!! YAY !! \o/
Where we are going (Aka - what we need to do)
- Rock solid communication
- Super Junit testing - without the need of other dependencies besides the DeviceController your testing
- Re-Implement all of MRLComm's original functionality (Big Job)
- Re-Implement Servo
- Re-Implement UltrasonicSensor
- Re-Implement non-blocking PulseIn
- Re-Implement Motor simple 2 PWM & DIR + PWM
- Implement Stepper (finally)
- Implement AFMotorSheild
- Implement super easy Pingdar
- Implement PinArray with WebGui which looks like Servo Orchestrator :)
- Improve Arduino gui to report line speed & memory now
- Implement Serial Relay device - serial over Arduino Mega pins or Esp6288 pins
New Standards ?
Standards and conventions are a great thing. The whole publish/subscribe "convention" is a convention started by us. It now provides a great "core" feature of distributed communication between services.
So what new standards are we creating with this huge MRLComm refactor ?
Let's go over it:
We've created DeviceControllers and DeviceControl.
These are a pair of thingys which potentially can "attach" to one another.
People and other systems are interested in DeviceControl, but in order to actually use them you need this other "thingy" which provides the low level commands.
DeviceControl has high level command ... For example with MotorControl you can moveTo(33) .. this is high level control .. in order for this to work the DeviceControl tells the DeviceController.motorMoveTo(MotorControl)
On the inside of the DeviceController it uses methods from MotorControl to get the data it needs to provide the results of the MotorControl.moveTo(33)
Maybe this means pulse one pin 33 times, or maybe it means activate a PWM pin and listen to the encoder pulses until they reach 33.
This structured pattern appears to work for many things. The first step is always to attach the DeviceControl to the DeviceController.
For example we can attach an Arduino to a shield. The syntax would be like this :
and then maybe we want to attach a shield to a servo
the user of the servo now can simply say servo.moveTo(33) and magically it will work !
both of these methods call a "lower level" method to do the "common" implementation of what is needed in the DeviceController to 'attach'
DeviceController.attachDevice(DeviceControl device, Object... config)
it comes with a variable argument Object... config - so any number of arguments can get passed, if more data is needed.
I and I think Mats both got confused in regards to Servos .. we mistakenly thought attaching a device was the same as Servo.attach(pin) ... ITS NOT !!!!
ITS VERY VERY VERY DIFFERENT
The "Arduino library" Servo.attach(pin) is a HIGH level method ... like MotorControl.moveTo(int) or Servo.sweep(10, 20, 30)
shield.attach(servo) is a LOW level method which registers the DeviceControl with the DeviceController, initializing objects, maps, and call back routes for a new device.
I like to see concrete examples of what the code would look like .. here would be examples in Python
arduino = Runtime.start("arduino", "Arduino")
servo = Runtime.start("servo", "Servo")
Here is what is happening the the above code segment
- arduino & servo services are started
- the arduino "connects" to the hardware
- arduino.attach(servo) - calls arduino.attachDevice(servo) directly - no need to pass additional config... the servo & controller are "pinless" - it does not have a pin .. the ServoController just knows there is a device of Servo type now attached to it... pin is undefined.
- servo.attach(7) - calls a "high level ServoControl" method - which energizes the servo on pin 7 of the controller
- servo.moveTo(33) - calls "high level ServoControl" method - which moves the servo to position 33
The different (and important part) of this example is difference in attaching a device, and calling a high level control method. I (think/hope) Mats believes the same thing. He once eluded to this when he said to me setController is different than attach ... I agree completely, its just the method names are a little different..
In regards to who 'owns' the pin, or which system has a copy of it ... We could still debate.. In Arduino's setup potentially 3 systems can have a copy of the pin (1. The Servo 2. Arduino Java service & 3. MRLComm) .. The problems with copies of data is 1. you need to know where the "system of record" is - which is the "real" copy.. then there is 2. keeping them in sync vs convienence
Because of the number of variables involved - this becomes a subjective decision, base on a "sweet spot" of data normalization vs convienence... we can discuss further
Below will be where I'll compile sequence diagrams to implement our DeviceControllers & Devices
UltrasonicSensor Sequence Diagram
Here is part of a diagram (in process) of the new Arduino & MRLComm command sequence. I already know what needs to be added, its just a matter of finishing the diagram. I intend to do several examples of other services. Not only the UltrasonicSensor, but PIR & Arduino (PinArray).
The collaborative spirit has been really great, and I think MRL'ians and the Arduino service will greatly benefit from it! :D
Thank you for this
Thank you for this informations, i think it's like rewrite MRL from scratch !
Does all inmoov services need to be rewrite or they "adapt" to the new mrlcomm ?
rules accepted :)
Ok, so first off.. I just did a pull and , holy shit, I had a small unit test start an arduino and a servo, I attached the servo to the arduino on pin 7, and told it to move to 10 degrees, and it worked.. WOW!
AWESOME! Wow, project mayhem is not to be talked about...
Ok, so now here is my punch. I think arduino.attach(servo, 7) also needs the initial angle .. (the config for a servo is actually 2 numbers, pin and initial angle)
arduino.attach(servo, pin, angle)
I noticed in the unit test, i attach the servo and it has no idea where it was previously, so it just goes back to some default angle in MRLComm... It could be dangerous for a servo in the arduino mrlcomm code to just initialize and jump to an angle..
This seems like a good idea.
This seems like a good idea. It forces the user of the servo to set something which has always been undefined in all Servo history ...
Hi moz4r, most will adapt ..
most will adapt .. but anything which attaches to the Arduino will need refactoring ...
The "really" good part is our templates & methodolgies in writing Services and implementing functiionality on microcontrollers will be substantially easier.