essay on programming languages, computer science, information techonlogies and all.

Wednesday, July 7, 2021

Finding planar rigid tranformation - linearized and weighted least squares

Rigid Transformation

A point P in the world can be expressed as Body coordinate as well as World coordinates, and the relationship between the two are rigid transformation - rotation and translation - like below.



Refer Wiki - Kinematics : Matrix representation

Image resolution and dimension

A point at an image can be expressed on world coordinates using Image resolution - i.e. mm / pixel - and dimension. At below, resolution is r. W is width and H is Height. Point at center (0,0) will be (320,240) of 640x480 image.



Geometric Model

For example, there is a pixel point (P) on a camera ( C ), that is offseted ( CO ) and assmebled to a machine (W).



And the machine has a stage (S) and it is moved by motor (M) and the stage has a point.



Then any point that camera see can be matched to a point on the stage.



Least square method on a linearized transformation matrix

If we know all other transformation except camera offset, then we can rearrange above equation like below for an i-th point.




The unknown CO transformation matrix can be linearized in assumption that the angle is small.



Then the equation can be rearranged putting the unknown X on right. Then the unknown can be solved by matrix inversion. Refer Wiki - Least Square : Linear least squares




Weighted least square method

If there is an uncertainty on each measurment of pixel point, the uncertainty can be put as weight (W) on each pixel point.




Then the equation can be rearranged for the unknown X. Note that element of X changed sign for convenience.







Monday, June 28, 2021

Continuous Integration of .NET Application using Azure DevOps

Are you still building exe in your local PC ?

Or maintain a dedicated PC that goes power-cycle at a stormy day or goes dead when HDD break down ? Aren't you tired of maintaining those build PCs ? Here is a story that can put those worries to history - only for .NET application using Azure DevOps now.

Cloud will build like local

Here,I want to make the build process runnable in the local PC as well as in the cloud - Azure DevOps - so that you can verify your change locally and you push the changes and know that the cloud will build your code in same manner. Then, once you fixed something on your local PC, you are just one push away to finish. Now if you sold, be patient and try to follow below.

Create Azure DevOps project

First, go to Azure DevOps and create a new project
Then clone the repository to your local PC. Or just clone template project

Directroy structure

Now you will populate the workspace with below directories. Or just copy and paste template project.

    /build         : contains build batch, project    
    /src   
       /bin        : generated dll, exe, pdb goes here
       /packages   : dependent component such as NUnit goes here
       /Foo        : various VS solutions
       /Bar
       ...

Local build

In local, you can open *.sln file at IDE and code and debug and build. Then you will open a command prompt and run build processs that will goes through all the solutions and make sure nothing break down by your change.

To make the process as easy as double-click an icon, there is Build command-line icon ath the build folder. When double click the icon, msbuild will be executed to build the whole process. Try to follow those arrows at below.


Your aim is to see below 'Build succeded.' like below.

Install packages

NuGet can put referenced dll on your local folder. It needs PackageReference instead of package.config - package.config will install packages at global repository. If correctly setup packages, you can find line something like below at csproj.
<ItemGroup>
<PackageReference Include="NUnit">
<Version>3.13.2</Version>
</PackageReference>
<PackageReference Include="NUnit.ConsoleRunner">
<Version>3.12.0</Version>
</PackageReference>
</ItemGroup>
The folder to hold those packages should be defined at nuget.config at the root folder.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value="src\packages" />
</config>
</configuration>
view raw nuget.config hosted with ❤ by GitHub
During build process, those packages should be downloaded and installed - called restore. At local build, it can be defined at the build.proj like below.
<ItemGroup>
<SolutionToBuild Include="..\src\Collider\Collider.sln"/>
</ItemGroup>
<Target Name="NuGetRestore">
<Exec Command="nuget.exe restore @(SolutionToBuild)"/>
</Target>
view raw build.proj hosted with ❤ by GitHub

Build and test

MSBuild task builds all solutions file listed up like below.
<ItemGroup>
<SolutionToBuild Include="..\src\Collider\Collider.sln"/> <!-- list up all the solution files -->
</ItemGroup>
<Target Name="Core">
<MSBuild
Projects="@(SolutionToBuild)"
Properties="Configuration=$(Configuration)"
/> <!-- $(Configuration) is 'Debug' or 'Release' -->
</Target>
view raw build.proj hosted with ❤ by GitHub
And it can test all the unittest like belew.
<PropertyGroup>
<NUnitConsoleRunner>src\packages\NUnit.ConsoleRunner\3.12.0\tools\nunit3-console.exe</NUnitConsoleRunner>
</PropertyGroup>
<ItemGroup>
<TestAssemblies Include="Collider.Unittest.dll"/>
</ItemGroup>
<Target Name="Unittest">
<Exec
Command="..\..\..\$(NUnitConsoleRunner) @(TestAssemblies) --labels=Before"
WorkingDirectory="..\src\bin\$(Configuration)"
CustomErrorRegularExpression = "Failed :"
IgnoreExitCode="true"
/>
</Target>
view raw build.proj hosted with ❤ by GitHub
If you want to debug the code - put a breakpoint - at the unitest, you will need to put '/process=Single'.

zip up binaires

After successful build and test, those dll, exe and relevant files can be zipped up. At below, files at src\bin\debug|release are ziped to src\bin\install\SampleNetApp.{Debug|Release}.zip
<Target Name="Install">
<ItemGroup>
<FilesToDelete Include="..\src\bin\$(Configuration)\*.pdb"/>
<FilesToDelete Include="..\src\bin\$(Configuration)\*.Unittest.dll"/>
<FilesToDelete Include="..\src\bin\$(Configuration)\TestResult.xml"/>
<FilesToDelete Include="..\src\bin\install\**\*"/>
</ItemGroup>
<Delete Files="@(FilesToDelete)" />
<MakeDir Directories="..\src\bin\install"/>
<ZipDirectory
SourceDirectory="..\src\bin\$(Configuration)"
DestinationFile="..\src\bin\install\SampleNetApp.$(Configuration).zip"
/>
</Target>
view raw build.proj hosted with ❤ by GitHub

Do the same thing at cloud

Azure can do what you did on local PC on cloud. It just need azure-pipelines.yml at the root folder.
trigger:
- 0.1 # any push to branch 0.1 will be trigger the pipeline
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release' # Release only
steps:
- task: MSBuild@1 # first nuget restore
timeoutInMinutes: 20
inputs:
solution: build\build.proj
msbuildArchitecture: 'Any'
configuration: '$(buildConfiguration)'
msbuildVersion: 'latest'
msbuildArguments: '-t:NuGetRestore'
- task: MSBuild@1 # main build
timeoutInMinutes: 20
inputs:
solution: build\build.proj
msbuildArchitecture: 'Any'
configuration: '$(buildConfiguration)'
msbuildVersion: 'latest'
- task: CopyFiles@1 # copy zipped file to artifact
inputs:
displayName: 'Copy Install to: $(Build.ArtifactStagingDirectory)'
sourcefolder: src\bin\install
targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: $(Build.ArtifactStagingDirectory)
artifactName: Installer
Then whenever you pushed change on git, then pipeline will start and build. You can look into build log.
With everything in place, you can get the build as zipped file at artifact.
Now as promised, you get the build from cloud in addition to your local PC. This is a simple continous integration of .NET application but it can be a good starting point on your journey.