Gokulnath's Blogs2022-11-19T12:48:47+00:00https://blogs.gokulnath.comMarkdown Based Blogging Website2020-06-01T00:00:00+00:00https://blogs.gokulnath.com/2020/06/01/markdown-based-blogging-website<p>After getting fond of <a href="https://en.wikipedia.org/wiki/Markdown#:~:text=Markdown%20is%20a%20lightweight%20markup,same%20name%20only%20supports%20HTML.">Markdown</a> while documenting my open source project <a href="https://github.com/gokulm/BoltOn">BoltOn</a>, decided to use a blogging engine based on Markdown.</p>
<p>Did a basic research, and found out that <a href="https://pages.github.com/">GitHub Pages</a> with <a href="https://jekyllrb.com/">Jekyll</a> to be the simplest one in terms of setup and maintenance.</p>
<p>Set it up without installing Ruby and other things, but Docker, check out <a href="https://medium.com/@sebagomez/setting-up-a-github-page-with-jekyll-and-a-docker-container-c712e448649b">this article</a>.</p>
<p>Here is the command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run -v /Users/gokul/gokulm.github.io:/srv/jekyll -p 4000:4000 -it jekyll/jekyll:builder bash
</code></pre></div></div>
<p>Here is the <a href="https://jamstackthemes.dev/theme/sidey-jekyll/">theme</a> I used.</p>
LEGO Hexapod2011-06-27T00:00:00+00:00https://blogs.gokulnath.com/2011/06/27/lego-hexapod<h2 id="video">Video</h2>
<p><a href="https://www.youtube.com/watch?v=wgWyWG2s7wk"><img src="https://img.youtube.com/vi/wgWyWG2s7wk/0.jpg" alt="LEGO Bot" /></a></p>
<h2 id="source-code">Source Code</h2>
<p>Here is the <a href="https://github.com/gokulm/LEGO.HexaPod">GitHub Repository</a></p>
<h2 id="requirements">Requirements:</h2>
<ul>
<li><a href="https://www.amazon.com/LEGO-Mindstorms-NXT-Discontinued-manufacturer/dp/B001V7RF9U">LEGO Mindstorms NXT 2.0</a></li>
<li><a href="https://www.microsoft.com/en-us/download/details.aspx?id=29081">Microsoft Robotics Developer Studio</a> (the link points to the latest version, please refer the code to the appropriate version)</li>
</ul>
<p>For the installation and setup, please refer to the previous posts:</p>
<ul>
<li><a href="/2010/09/04/how-to-create-dss-service">How to create DSS Service?</a></li>
<li><a href="/2010/11/05/lego-bot">Lego Bot</a></li>
</ul>
LEGO Bot2010-11-05T00:00:00+00:00https://blogs.gokulnath.com/2010/11/05/lego-bot<h2 id="video">Video</h2>
<p><a href="https://www.youtube.com/watch?v=YUXAIZXGfQk"><img src="https://img.youtube.com/vi/YUXAIZXGfQk/0.jpg" alt="LEGO Bot" /></a></p>
<h2 id="source-code">Source Code</h2>
<p>Here is the <a href="https://github.com/gokulm/LEGO.Bot">GitHub Repository</a></p>
<h2 id="requirements">Requirements:</h2>
<ul>
<li><a href="https://www.amazon.com/LEGO-Mindstorms-NXT-Discontinued-manufacturer/dp/B001V7RF9U">LEGO Mindstorms NXT 2.0</a></li>
<li><a href="https://www.microsoft.com/en-us/download/details.aspx?id=29081">Microsoft Robotics Developer Studio</a> (the link points to the latest version, please refer the code to the appropriate version)</li>
<li>Network/IP Camera (I used my iPhone with WiFi Camera app installed on it)</li>
<li>WPF Dashboard Controls</li>
</ul>
<h2 id="how-to-set-it-up">How to set it up?</h2>
<p>Create a MRDS Service and add the partners - NxtDrive and NxtBattery. Adding the partners will automatically declare and instantiate an object for BatteryOperations and an object for DriveOperations. Please add one more for DriveOperations as the code mentioned below.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/// <summary>
/// NxtBattery partner
/// </summary>
[Partner("NxtBattery", Contract = battery.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
battery.BatteryOperations _nxtBatteryPort = new battery.BatteryOperations();
/// <summary>
/// NxtDrive partner
/// </summary>
[Partner("NxtDrive", Contract = drive.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
drive.DriveOperations _nxtDrivePort = new drive.DriveOperations();
drive.DriveOperations _nxtDriveNotify = new drive.DriveOperations();
</code></pre></div></div>
<p>Add a new class library project to the solution, and add an interface to it. This project needs to be referenced in the MRDS Service and the WPF UI projects (will explain the UI project later).</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public interface IMyLegoCarService
{
double GearPower { get; set; }
long LeftEncoderCurrent { get; set; }
long RightEncoderCurrent { get; set; }
double LeftPowerCurrent { get; set; }
double RightPowerCurrent { get; set; }
double BatteryPower { get; set; }
void Drive(DriveAction driveDirection);
void StopEngine();
}
</code></pre></div></div>
<p>Change the MRDS Service in such a way that it implements this interface. Values for all the properties but the first property (GearPower) will be set in the service, and they will be retrieved and used in the UI layer.</p>
<p>Now, add a new WPF project. VS will choose x86 as the targeted platform by default, change it to “Any CPU”. Declare a property named Service of type IMyLegoCarService, and add a constructor, something like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public Dashboard(IMyLegoCarService service) : this()
{
Service = service;
Service.GearPower = 0;
brsr_ipcamera.Navigate(new Uri("http://ipoftheiphoneorthewebserver/iphonecamera/index.htm"));
UpdateInitialOdometer();
uiTimer = new DispatcherTimer();
uiTimer.Interval = TimeSpan.FromSeconds(1);
uiTimer.Tick += uiTimer_Tick;
uiTimer.Start();
}
</code></pre></div></div>
<p>This constructor should be called from the Service’s constructor, so that the service and the UI will be on the same thread. Here “brsr_ipcamera” is the web browser control to display the ip camera’s image/video (in my case my iphone). I added an html page to my webserver displaying only the video from the camera. Add a timer control to display the information retrieved from the service periodically. Here I’ve used WPF Dashboard Controls’ dial controls as speedometers (for left motor front, left motor reverse, right motor front and right motor reverse), odometer control as odometer and progress bar control as fuel gauge. Left/Right Power Current properties were used to initialize the speedometers. Left/Right Encoder properties were used to initialize the odometer, these properties basically give us the degrees that the servo motors rotated. Using the formula: <strong>distance = Convert.ToInt32(Math.Abs(currentEncoderCurrent) / 360 * 2 * 3.14 * 0.75</strong>, we can calculate the distance covered. Here, pi = 3.14 and 0.75 is the radius of the wheels.</p>
<p><img src="https://github.com/gokulm/LEGO.Bot/blob/master/CropperCapture%5B5%5D_thumb.jpg" alt="Screenshot" /></p>
<p>Coming back to the service. Declare and/or instantiate the following classes.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wpf.WpfServicePort _wpfServicePort;
drive.SetDriveRequest _nxtSetDriveRequest = new drive.SetDriveRequest();
battery.BatteryState _nxtBatteryState;
</code></pre></div></div>
<p>WpfServicePort is used toinvoke the WPF UI, SetDriveRequest to rotate the motors and the BatteryState to get the battery information.</p>
<p>Add a port named “TimerTick” to the service types similar to the automatically created ports “Get”, “Subscribe” etc. Now your serviceoperations class declaration will be something like this -</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[ServicePort]
public class MyLegoCarServiceOperations : PortSet<DsspDefaultLookup, DsspDefaultDrop, Get, Subscribe, TimerTick>
{
}
public class TimerTick : Update<TimerTickRequest, PortSet<DefaultUpdateResponseType, Fault>>
{
public TimerTick()
: base(new TimerTickRequest())
{
}
}
[DataContract]
public class TimerTickRequest
{
}
</code></pre></div></div>
<p>Modify the service’s start method something like this -</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protected override void Start()
{
SpawnIterator(DoStart);
}
private IEnumerator<ITask> DoStart()
{
DispatcherQueue queue = new DispatcherQueue();
this._wpfServicePort = wpf.WpfAdapter.Create(queue);
// invoke the UI
var runWindow = this._wpfServicePort.RunWindow(() => (Window)new Dashboard(this));
yield return (Choice)runWindow;
var exception = (Exception)runWindow;
if (exception != null)
{
LogError(exception);
StartFailed();
yield break;
}
// Subscribe to partners
var subscribe1 = this._nxtDrivePort.Subscribe(_nxtDriveNotify);
yield return (Choice)subscribe1;
_timerPort.Post(DateTime.Now);
// Activate independent tasks
Activate<ITask>(
Arbiter.Receive<drive.DriveEncodersUpdate>(true, _nxtDriveNotify, DriveEncoderHandler),
Arbiter.Receive(true, _timerPort, TimerHandler)
);
// Start operation handlers and insert into directory service.
StartHandlers();
}
private void StartHandlers()
{
// Activate message handlers for this service and insert into the directory.
base.Start();
}
</code></pre></div></div>
<p>Timerport is used to retrieve the battery information periodically.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[ServiceHandler(ServiceHandlerBehavior.Exclusive)]
public IEnumerator<ITask> TimerTickHandler(TimerTick incrementTick)
{
incrementTick.ResponsePort.Post(DefaultUpdateResponseType.Instance);
battery.Get batteryGet;
yield return _nxtBatteryPort.Get(GetRequestType.Instance, out batteryGet);
_nxtBatteryState = batteryGet.ResponsePort;
if (_nxtBatteryState != null)
{
BatteryPower = _nxtBatteryState.PercentBatteryPower;
}
yield break;
}
void TimerHandler(DateTime signal)
{
_mainPort.Post(new TimerTick());
Activate(
Arbiter.Receive(false, TimeoutPort(3000),
delegate(DateTime time)
{
_timerPort.Post(time);
}
)
);
}
</code></pre></div></div>
<p>DriveEncoderUpdate to retrieve the information from the servo motors.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private void DriveEncoderHandler(drive.DriveEncodersUpdate statistics)
{
LeftEncoderCurrent = statistics.Body.LeftEncoderCurrent;
RightEncoderCurrent = statistics.Body.RightEncoderCurrent;
LeftPowerCurrent = statistics.Body.LeftPowerCurrent;
RightPowerCurrent = statistics.Body.RightPowerCurrent;
}
</code></pre></div></div>
<p>Create an enum named “DriveAction” in the common class library project. This is to handle the keyboard or the click events from the UI Layer.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public enum DriveAction
{
Front,
Back,
Left,
Right,
Stop
}
</code></pre></div></div>
<p>Implement the Drive method in the service.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public void Drive(DriveAction driveAction)
{
switch (driveAction)
{
case DriveAction.Front:
_nxtSetDriveRequest.LeftPower = -GearPower;
_nxtSetDriveRequest.RightPower = -GearPower;
_nxtDrivePort.DriveDistance(_nxtSetDriveRequest);
break;
case DriveAction.Back:
_nxtSetDriveRequest.LeftPower = GearPower;
_nxtSetDriveRequest.RightPower = GearPower;
_nxtDrivePort.DriveDistance(_nxtSetDriveRequest);
break;
case DriveAction.Left:
_nxtSetDriveRequest.LeftPower = -.4;
_nxtSetDriveRequest.RightPower = .4;
_nxtDrivePort.DriveDistance(_nxtSetDriveRequest);
break;
case DriveAction.Right:
_nxtSetDriveRequest.LeftPower = .4;
_nxtSetDriveRequest.RightPower = -.4;
_nxtDrivePort.DriveDistance(_nxtSetDriveRequest);
break;
case DriveAction.Stop:
_nxtDrivePort.AllStop(MotorStopState.Coast);
break;
default:
break;
}
}
</code></pre></div></div>
<p>I suppose I’ve explained most of the important parts in the service. Please let me know if you have any questions.</p>
Microsoft Robotics Developer Studio DSS Service2010-09-04T00:00:00+00:00https://blogs.gokulnath.com/2010/09/04/how-to-create-dss-service<p>When I wanted to create my first robotics service, I had many difficulties and found very few resources over the internet for LEGO NXT 2.0 using Microsoft Robotics Developer Studion, so just thought of writing about it, especially the Decentralized Software Service (DSS).</p>
<h2 id="requirements">Requirements</h2>
<ul>
<li><a href="https://www.amazon.com/LEGO-Mindstorms-NXT-Discontinued-manufacturer/dp/B001V7RF9U">LEGO Mindstorms NXT 2.0</a></li>
<li><a href="https://www.microsoft.com/en-us/download/details.aspx?id=29081">Microsoft Robotics Developer Studio</a> (the link points to the latest version, please refer the code to the appropriate version)</li>
</ul>
<h2 id="installation">Installation</h2>
<p>Microsoft Robotics Studio can be used as a stand-alone development environment or it can be used with any of the Visual Studio 2008 or 2010 Editions, including the Express Editions.</p>
<h2 id="how-to-create-decentralized-software-service-dss">How to create Decentralized Software Service (DSS)?</h2>
<ol>
<li>After Installing Microsoft Robotics Studio, open Visual Studio IDE (I’m using 2010).</li>
<li>Click File/New Project, you should be able to see Microsoft Robotics under C# like this -</li>
</ol>
<p><img src="/assets/img/how-to-create-dss-service/screenshot1.jpg" /></p>
<ol>
<li>Create the project under Microsoft Robotics Studio installation folder (it will be mostly in c:\user\username\microsoft robotics dev studio 2008 r3), so that the common robotics dlls will be referenced properly.</li>
<li>Click OK and you will be allowed to enter your service name, namespace and other details. The most important thing is – you will be allowed to choose your partners from here -</li>
</ol>
<p><img src="/assets/img/how-to-create-dss-service/screenshot2.jpg" /></p>
<ol>
<li>Choose the partners one by one from the list and click “Add as partner”. Check the “Add notification port” checkbox and leave the Creation Policy as it is. Lego NXT Brick (v2) should be selected as one of the partners, and the other partners can be selected based on the sensors that you will be using. In case if you want to edit or delete any of the added partners, you can choose the partner from the partner dropdown and perform your actions. Once all the partners are selected, click OK.</li>
<li>You should be able to see the auto-generated code now. Build your solution.</li>
</ol>
<h2 id="how-to-create-manifest-using-dss-manifest-editor">How to create manifest using DSS Manifest Editor?</h2>
<ol>
<li>Open DSS Manifest Editor.</li>
<li>Choose your service from the left, drag and drop it on the editor. You should be able to see this -</li>
</ol>
<p><img src="/assets/img/how-to-create-dss-service/screenshot3.jpg" /></p>
<ol>
<li>Search for your partners on the left, drag and drop on “Use service’s partner definition (UseExistingOrCreate)” boxes appropriately.</li>
<li>As the sensors in turn use the nxtbrick as their partner, another set of “Use service’s partner definition (UseExistingOrCreate)” boxes will be created for the brick.</li>
<li>You need to select nxtbrick service again and drop it on the boxes. If you see a pop like the one below, choose the already created service and NOT “Add a new instance”.</li>
</ol>
<p><img src="/assets/img/how-to-create-dss-service/screenshot4.jpg" /></p>
<ol>
<li>To configure the service, click it and then press “Create Initial State” button on the properties window. For the NxtBrick, you need to set the serial port number used for bluetooth connection. For the sensors, you need to set the ports appropriately.</li>
<li>Replace this manifest with the manifest created by the service.</li>
<li>To start the service execute <strong>dsshost /port:50000 /manifest:”C:\Users\username\Microsoft Robotics Dev Studio 2008 R3\MyDemoService\MyDemoService.manifest.xml”</strong> in DSS Command Prompt.</li>
<li>You can also start the service from the DSS Control Panel. In order to view the control panel, start DSS Node and then go to http://localhost:50000 (default port is 50000, if you’ve changed it use it accordingly).</li>
<li>Switch ON your LEGO NXT 2.0 and then start the service. If everything is configured properly, you should be able to hear connecting sound from the NXT Brick.</li>
</ol>
Thirukkural/திருக்குறள்2010-05-15T00:00:00+00:00https://blogs.gokulnath.com/2010/05/15/thirukkural<p>Thirukural, written by Thiruvalluvar, in the form of couplets that convey noble thoughts. It is considered to be a book of ethics for the ordinary man, the administrator, the king and the ascetic. It is universal in perspective, and hence called “Ulaga Podhu Marai” meaning the Common Knowledge for the world. It is as timely today as when it was written more than 2000 years ago. <a href="https://en.wikipedia.org/wiki/Tirukku%E1%B9%9Ba%E1%B8%B7">Click here</a> to know more about this book.</p>
<p>It has been translated to 80 languages (including many Indian languages). However, as far as I know only few people from India, other than from Tamil Nadu (a southern state in India) have known about or read this book. It is one of the reasons why I decided to build a website with English translation and transliteration … just an attempt to spread this book further, hope you will do the same.</p>
<p>Check it out - <a href="http://thirukkural.gokulnath.com">http://thirukkural.gokulnath.com</a></p>
<p><strong>Acknowledgements:</strong></p>
<p>Took most of the content from:</p>
<ul>
<li><a href="/assets/files/thirukkural/Tamil.pdf">Tamil.pdf</a></li>
<li><a href="/assets/files/thirukkural/English.pdf">English.pdf</a></li>
<li><a href="/assets/files/thirukkural/TamilMeaning.pdf">TamilMeaning.pdf</a></li>
<li>Used Azhagi for reverse-transliterations.</li>
</ul>
<p>Vazhga Tamil!!</p>