Notifications
Clear all

Dummy driver for cam and serial connection.


mario
Posts: 569
Admin
Topic starter
(@mario)
Member
Joined: 4 years ago

@Dangerdad137

Development would be easier if we have a dummy driver for the camera device and the serial connection. Such drivers would allow to run the FabScanPi-Server without the hardware. 

https://github.com/mariolukas/FabScanPi-Server/tree/develop/src/fabscan/scanner/laserscanner/driver

What i have in my mind is:

Dummy cam driver: 

A camera class which is implemented such as the one for the picamera, but it should grab the images from a folder instead of a camera. This folder should keep different plain pictures which i will make with the fabscan hardware. One set during a scan and one set during the settings window is opened.

Serial dummy driver:

The serial driver is quite easy, it should be a the serial driver as it is now but only as a stub/mock which will do nothing expect to confirm that the message was send.

Both dummy drivers should be encapsulated in a way that you can set the driver in the config. There is already something like that for the camera driver, because in an early stage of implementing that i experimented to write a driver for usb cams (parts of this code are still there).

I think that might be an excellent entry point for you and it will help us all and especially the guy who is developing the current frontend version because he does not own a working hardware setup at the moment. I would appreciate that.

By the way we are the only core developers by now :)

Reply
7 Replies
Dangerdad137
Posts: 19
(@dangerdad137)
Active Member
Joined: 2 years ago

I'm used to doing this in C# moving entry points to services implementing interfaces so they can be implemented by mocks or by real backends.  Not sure what the typical approach is in python.  Are we moved to python3?  Do I just clone the project and go to town?

Reply
mario
Admin
(@mario)
Joined: 4 years ago

Member
Posts: 569
Posted by: @dangerdad137

I'm used to doing this in C# moving entry points to services implementing interfaces so they can be implemented by mocks or by real backends.  Not sure what the typical approach is in python.  Are we moved to python3?  Do I just clone the project and go to town?

Yes python2 reached EOL in january. You can start from the python3 feature branch. I am doing some final test with this branch. If all things work i will merge it to the dev branch and after the release also to the master.

I know that i was a little bit lazy in the past when i started to use interfaces in python. You are right there should be clear interfaces. I started using interfaces for the main independet classes. https://github.com/mariolukas/FabScanPi-Server/tree/develop/src/fabscan/scanner

My idea was that fabscan should support different scan approaches (laser scanner, photogrammetry, projector based structured light... etc.). Until now only the laser scanning approach works. I had still not the time to implement another scanning approach. Long story short... i introduced the interfaces. 

https://github.com/mariolukas/FabScanPi-Server/tree/develop/src/fabscan/scanner/interfaces

FSCalibration.py - serves the calibration algorithm for the selected approach.

FSHardwareController.py - serves an abstraction layer to the hardware drivers (camera, serial, turntable etc.)

FSImageProcessor.py - should implement a class which does all the heavy calculations based on images.

FSScanProcessor.py - should implement an actor which does the logic part of the scanning approach

(Don't be confused, i know the interfaces are empty classes. I definetly need to add the needed function definitions which are needed)

Python does not support the DI pattern by default. I build an injector class which is used to provide the implementations for the interfaces when the application is booting up. 

https://github.com/mariolukas/FabScanPi-Server/blob/develop/src/fabscan/server/FSScanServer.py#L86

The scanning approach is set in the config file. A factory created the scanner type.

https://github.com/mariolukas/FabScanPi-Server/blob/develop/src/fabscan/scanner/interfaces/__init__.py

I am thinking about refactoring the drivers 

https://github.com/mariolukas/FabScanPi-Server/tree/develop/src/fabscan/scanner/laserscanner/driver

for using them in a similar way within the FSHardwareController.py implementation, where the drivers are created.

 

Reply
Dangerdad137
Posts: 19
(@dangerdad137)
Active Member
Joined: 2 years ago

Yah, it seems like a stub would be more useful than a mock inside of a formal testing framework.  I went ahead and got PyCharm Pro -- the monthly fee is reasonable and using the same tools as yours will likely save more than the $8 / month in frustration.

How do you go about launching the dev code headless?  What's your typical work flow when running the code?

Reply
mario
Posts: 569
Admin
Topic starter
(@mario)
Member
Joined: 4 years ago

I will add a dev setup guide with screenshots to the documentation this evening. (8:00 pm CET). 

Reply
Dangerdad137
Posts: 19
(@dangerdad137)
Active Member
Joined: 2 years ago

I'm happy to help with the doc FYI, if the steps aren't to complex to figure out, I'd be happy to document them as I go.

Reply
Dangerdad137
Posts: 19
(@dangerdad137)
Active Member
Joined: 2 years ago

So, now that I have the dev env set up, I can go ahead and start with the testing work.  Is this a viable guide to get started?  Seems pretty straightforward, but I haven't dug into the implementations of the classes.

https://www.jetbrains.com/help/pycharm/testing-your-first-python-application.html

I can start with an empty test and start building as I go.  If I have to refactor anything, where are you currently working so I am less likely to step on any toes?

 

Reply
mario
Posts: 569
Admin
Topic starter
(@mario)
Member
Joined: 4 years ago
Posted by: @dangerdad137

So, now that I have the dev env set up, I can go ahead and start with the testing work.  Is this a viable guide to get started?  Seems pretty straightforward, but I haven't dug into the implementations of the classes.

Yes you can go with it. There are already some tests in the test folder. ( Yes shame on me for only writing a few tests over all years i am working on FabScan now ? )

Posted by: @dangerdad137

I can start with an empty test and start building as I go.  If I have to refactor anything, where are you currently working so I am less likely to step on any toes?

I think i am preparing the upcoming release ( the current python3 feature branch).  Afterwards i will do some work on the new UI. So i think there should ne no conflicts. Otherwise we can keep each other up to date.

Start by forking the project and create a new feature branch. I will keep you informed when you need to merge the current dev branch into your feature branch ( when it is nessesary).

I think the best starting point is the serial driver. This is the easiest task. The "dummy" only needs to pass the command without doing real sending. The real hardware/FabScanPi HAT returns an ACK when the command was executed (motor movement, laser switching, led on/off). The ACK is just an echo of the command which was sent to the HAT. 

So the serial dummy driver should just implement the callable functions which are provided by the real serial driver class. The functions should return fake data ( e.g. for requesting version number) or fake ACK signals ( directly passing through the G-Code command by the return statement).

Further thoughts (does not affect the camera parts): 

I am planing to encapsulate the serial driver in a more general/generic approach. Because future versions of the FabScanPi Server should be able to handle also Raspberry Pi GPIO's Pins instead of a serial connection to a microcontroller. There are some scanners which are able to control the hardware over thee GPIO's. So i am thinking about a abstraction layer ( proxy pattern) for handling different hardware types for hardware controlling. Something like a class called connector would be great which implements a factory for creating an instance of the current needed control unit ( FSSerial.py, FSGPIO.py). The protocol and interface should be the same so that the FSLaser, FSTurntable, FSLed classes send the command as it is and the instantiated connector implementation handles sending/executing depending on which type of hardware it uses. The connector can be configured by the default.config.json. There should be a configuration object which replaces the serial object. This approach can also be reliable and useful when we want to configure the dummy driver. Maybe we should start with this layer of abstraction for the hardware communication. 

"serial": {
"plattform_type": "fabscanpi",
"baudrate": 115200,
"autoflash": "True",
"flash_baudrate": 115200,
"port": "/dev/ttyAMA0"
},

should be something like (for serial)


"connector": {
"type: "serial",
"config: {
"plattform_type": "fabscanpi", <--- needed by the serial driver to detect the current uses hardware
"baudrate": 115200,
"autoflash": "True",
"flash_baudrate": 115200,
"port": "/dev/ttyAMA0"
}
},

should be something like (for GPIO)

"connector": {
"type: "gpio",
"config: {
gpio_laser_0: xx
gpio_laser_1: xx
gpio_turntable_step: xx
gpio_turntable_dir: xx
gpio_led: xx
}
},

and finally of course the dummy driver: 

"connector": {
"type: "serial_dummy",
"config: {
"plattform_type": "fabscanpi",
"baudrate": 115200,
"autoflash": "True",
"flash_baudrate": 115200,
"port": "/dev/ttyAMA0"
}
},



This also keeps the gate open for other connection types like i2c,spi etc.

Reply
Share: