Ammeter interface

by cisterni 5. September 2011 20:39

We are using VSLab as a console to coordinate experiments for measuring energy absorbed by algorithms. We have developed a methodology that allows us to get complexity behavior from the current absorbed by a computer on the AC power. Here is the source of a "virtual" ammeter based on phidgets sensors that allows us to decide the sampling frequency and wether use a buffer or not to accumulate samples. It is a nice application of unit of measure of F#, and shows also a pitfall of the language: "open" is a keyword but also the method name of the Phidgets .NET library, thus we resorted to reflection for invocation.

open Phidgets
 
let ifkit = new InterfaceKit()
let openPhidgets() = typeof<InterfaceKit>.GetMethod("open", [| |]).Invoke(ifkit, [| |]) |> ignore
 
[<Measure>] type V // Volt unit measure
[<Measure>] type A // Ampére unit measure
[<Measure>] type Hz // Hertz
[<Measure>] type s // Seconds
[<Measure>] type ms // Seconds
 
type AmmeterSensor(id:int, kit:InterfaceKit) =
  let k = 0.04204<A>
  let mutable buffered = false
  let sensor = kit.sensors.[id]
  let mutable lastv = 0.
  let mutable samplingRate = 10.<Hz>
  let mutable accumulator = 0.
  let mutable samplescount = 0.
  let mutable maxsz = 0 // Infinite
 
  let interval() = float(1. / samplingRate) * 1000.<ms>
  let mutable startInterval = System.DateTime.Now
 
  let buffer = new System.Collections.Generic.Queue<float<A>>()
 
  do
    sensor.Sensitivity <- 1
    kit.SensorChange.Add(fun v ->
      if v.Index = id && buffered then
        let dt = interval()
        let t = System.DateTime.Now
        if (t - startInterval).TotalMilliseconds > float(dt) then
          lastv <- (accumulator / samplescount)
          if maxsz > 0 && buffer.Count = maxsz then buffer.Dequeue() |> ignore
          buffer.Enqueue(lastv * k)
          startInterval <- t
          samplescount <- 0.
          accumulator <- 0.
        accumulator <- float(v.Value) + accumulator
        samplescount <- samplescount + 1.
    )
 
  member x.Buffered
    with get() = buffered
    and set(v) = buffered <- v
 
  member x.SamplingRate
    with get() = samplingRate
    and set(v) = samplingRate <- v
 
  /// <summary>
  /// NUmber of buffered samples. 0 means no bouds, please beware out of memory!
  /// </summary>
  member x.BufferSize
    with get() = maxsz
    and set(v) = maxsz <- v
 
  member x.nextValue() =
    if not buffered then
      Some(float(sensor.Value) * k)
    else
      if buffer.Count = 0 then
        let dt = interval()
        let t = System.DateTime.Now
        if (t - startInterval).TotalMilliseconds > float(dt) then
          startInterval <- t
          samplescount <- 0.
          accumulator <- 0.
          Some(float(sensor.Value) * k)
        else
          None
      else
        Some(buffer.Dequeue())
 
  member x.ToSequence () =
    seq {
      while kit.Attached do
        if buffered then
          let t = System.DateTime.Now
          let dt = float(interval())
          let elapsed = (t - startInterval).TotalMilliseconds
          if elapsed <= dt then
            System.Threading.Thread.Sleep(int(dt - elapsed) + 1)
        yield x.nextValue()
    }
 
 
 
 
openPhidgets()
 
let sens0 = new AmmeterSensor(3, ifkit)
 
sens0.Buffered <- true
 
sens0.ToSequence() |> Seq.take 1000 |> Seq.map (fun v -> match v with Some x -> float(x) | _ -> 0.)  |> Seq.toList |> Chart.Line
 
 
let sensors = [| 0 .. 2 |] |> Array.map (fun id -> new AmmeterSensor(id, ifkit))
sensors |> Array.iter (fun s -> s.Buffered <- true)
 
let values(amount) =
  seq {
    while true do
      let e = sensors |> Array.fold (fun v s -> v + s.nextValue().Value) 0.<A>
      System.Threading.Thread.Sleep(110)
      yield e
  } |> Seq.take amount
 
 
 
open System.IO
 
let out = File.CreateText(@"enclosure-5-pwr-100.xml")
out.WriteLine(@"<? xml version=""1.1"" encoding=""utf-8"" ?>")
out.WriteLine(@"<AmmeterSamples Description=""Enclosure with 5 blade pwr 100%"" SampleRate=""10Hz"">")
 
values(1200) |> Seq.iter (fun v -> out.WriteLine(sprintf "  <Sample>%f</Sample>" (float(v))))
 
out.WriteLine(@"</AmmeterSamples>")
out.Close()
printfn "Done."
 
 
sens0.nextValue()
 
let inp0 = ifkit.sensors.[0]
 
inp0.Sensitivity <- 1
 
inp0.Value
  ifkit.close()

Currently rated 2.5 by 10 people

  • Currently 2.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Design | General | F# Interactive

VSLab presentation at Functional Programming eXchange 2011!

by cisterni 20. March 2011 18:51

Now that VSLab is running on Visual Studio 2010 it is time to start blogging again I guess. Last friday I gave a brief talk about VSLab at Functional Programming eXchange 2011 in London, whatch the video here.

We are looking for contributions in terms of Viewlets, please let us know how are you using the plugin.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

General

First run on Visual Studio 2010!

by cisterni 23. June 2009 19:02

Big news! VSLab is running on Visual Studio 2010! Ok, this is rather big statement, so far we just managed to run the very first simple example as shown in figure. We expect a lot of work to update VSLab integration with Visual Studio, there are many differences between Visual Studio 2008 and Visual Studio 2010. But the very core mechanism still works, and it wasn't obvious since it is rather delicate. Now we have to find a way to rearrange source code so to have the two versions of VSLab.

Newer versions will target both environments as F# does.

Currently rated 4.0 by 5 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

General | Shell

Wall-E release is out!

by cisterni 19. June 2009 21:08

Hi everybody, first of all we should apologize for our long silence. But we work at a University and the second term has been tough and we delayed the VSLab release in the hope of concluding several on-going parts. But now the May CTP of F# is out and people was asking for un updated version. So today we have released VSLab Wall-E which is also planned to work on Visual Studio 2010 (which is something we are working on).

In this release the major step has been the consolidation of the foundation (of the hack would be more appropriate perhaps...) of the system. We are currently using it for real scientific projects now and we are really happy! We are building a machine for micro-fabrication of tissues in collaboration with biomedical engineers and everything works with VSLab better than with Matlab.

As for the development, we are working on a general purpose viewlet for data drawing with vectorial support (even if developed in Windows Forms) so that non-computer scientist may easily plot data. We are improving the lightweight controls library, and the overall Visual Studio integration (though this must cope with the new upcoming release).

From now on you'll hear more often from us, we're back!

Currently rated 3.3 by 8 people

  • Currently 3.25/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Community | Shell

MathLibraries

by cisterni 14. February 2009 10:32

A frequently asked question about VSLab is "ok, this is nice and I see the library can address many Matlab/Mathematica scenarios, but how about math?". My typical answer is: you can look for .NET math libraries out there, there are many. However often people looks for hints on how browse the jungle Web out there.

I suggest a couple of libraries that may address many of common situations: the Math.NET library, a very large library featuring a lot of features and it is LGPL and GPL and easily embeddable into VSLab projects; and dnAnalytics a library less complete but with merits, especially because of the attention to performances.

In the meantime we are working to a WPF viewlet (though with different architecture with respect to Viewlets) and Data Visualization viewlets to be used in experiments. We are also considering to add a CopyClipboard feature to viewlets so that it is easy to capture views and insert into papers.

 

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Shell

Next VSLab release upcoming

by cisterni 19. January 2009 22:51

Ok, we are close to a new release of VSLab. It will contain two major changes that are very very important. The first one is, as far as I know, the first implementation of Lightweight Controls for Windows Forms, made available for programming viewlets with ease but also available to all .NET applications. Wonder why are Lightweight Controls so important? Let's start with an example in C#:

    public partial class Form1 : Form    {

        public Form1()        {

            InitializeComponent();

            var lc = new LightweightContainer();

            var lb = new LightweightButton();

            var rb = new RoundButton();

            var rb2 = new RoundButton();

            lc.Dock = DockStyle.Fill;

            lb.Position = new Point(0, 0);

            lb.Text = "Hello World";

            lc.BackColor = Color.AliceBlue;

            lc.Add(lb);

            rb.Position = new Point(0, 100);

            rb.Size = new Size(50, 50);

            rb.Text = "Hello with very long text";

            lc.Add(rb);

            rb2.Position = new Point(0, 110);

            rb2.Size = new Size(50, 50);

            rb2.Text = "Hello 2";

            lc.Add(rb2);

            this.Controls.Add(lc);

        }

    }

This is a simple code meant for creating three buttons into a canvas. The LightweightContainer class is a sort of panel capable of hosting lightweight controls (classes derived from LightweightControl). The library features a number of predefined controls such as buttons (in Vista style) and scrollbars. In the example the lb variable holds an instance of a LightweightButton. The lightweight control container is docked within the form. The other two buttons are instances of RoundButton class which is a simple example of how to write a lightweight control:

    public class RoundButton : LightweightControl    {

        public string Text = "";

         public override void OnMouseMove(MouseEventArgs e)        {

            base.OnMouseMove(e);

            BackColor = Color.Red;

            Invalidate();

        }

        public override void OnClick(EventArgs e)        {

            base.OnClick(e);

            Position = new Point(Position.X, Position.Y + 10);

            Invalidate();

        }

         public override void OnPaint(PaintEventArgs e)        {

            var g = e.Graphics;

            using (var b = new SolidBrush(Color.FromArgb(40, BackColor)))            {

                g.FillEllipse(b, e.ClipRectangle);

                g.DrawEllipse(Pens.Black, e.ClipRectangle);

                var sf = new StringFormat();

                sf.Alignment = StringAlignment.Center;

                sf.LineAlignment = StringAlignment.Center;

                g.DrawString(Text, Font, Brushes.Black, new RectangleF(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width, e.ClipRectangle.Height), sf);

            }

        }

    }

 The RoundButton is written as a standard UserControl except for the fact that it inherits from LightweightControl (and that not all the features of UserControl are available). The output is shown in the following picture: 

Here is a more complete screenshot of one of our regression tests running inside VSLab:

Lightweight controls are important for viewlets because it is not possible using the standard controls, therefore having user control abstractions makes viewlet development a lot easier. One of the example is the addition of a button over the Chart and the 3D Chart viewlets as shown in this screenshot:

The other important update in this new release is the implementation of double buffering for Viewlets (the Chart viewlet sample does not flicker anymore once enabled) which has been challenging to implement because of the internals of VSLab. The overall code has been cleaned up and reviewed in order to offer a more consistent programming API.

Now we are getting back to the original ideas of featuring new viewlets for data visualization and system shell replacement. In the meantime we are using VSLab in projects involving biomedical engineers.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

General | Shell | Viewlets

Lightweight controls, VSLab and F#

by cisterni 5. January 2009 11:14

November and december have been busy months and time was short to find enough time to write about VSLab. However, things are going on and we are planning a new release of VSLab soon. The major contribution is from Giacomo Righetti, who has spent time for building a framework of lightweight controls using a former definition from me. Lightweight controls are missing from Windows Forms, and now you can have them in F# (and .NET languages). Giacomo implemented a set of predefined controls such as buttons, scrollbars, and many others so that viewlet development becomes easier. The VSLab shell project is also going on, and actually I have configured my Acer aspire one to start VSLab as a system shell :) I don't really miss Windows explorer... (ok, ok, I know I'm a little bit biased!).

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Design | General

VSLab update and measure units sample

by cisterni 30. October 2008 23:29

Ok, it is some time since the last update of VSLab, but today I decided to update the installer and commit several changes I did to improve stability and support for events. I finally managed to go through the whole Viewlet definition and fully document supported and unsupported events inherited from UserControl. I also managed to fix several bugs in this respect.

 This is term period and in the Graphical interfaces courses I'm teaching using F# (interactively). Today to discuss animations I've implemented a simple application with balls moving around and quickly converted into a viewlet! The nice thing about this application is the use of unit measures in a graphical application to estimate velocity (<px/s>). Once you run the viewlet you can create a new ball by simply clicking in the client area and drag the initial velocity vector. Here is a screenshot:

 

and here it is the code:

#light

open System.Drawing

open System.Windows.Forms [<Measure>] type px

[<Measure>] type s

open VSLab

let ballsz = new SizeF(25.0f, 25.0f)

type Ball(ipx: float<px>, ipy:float<px>, ivx:float<px/s>, ivy:float<px/s>) =

  let mutable vx = ivx

  let mutable vy = ivy

  let mutable px = ipx

  let mutable py = ipy

  let sz = ballsz

  member x.Update(interval:float<s>) =

    px <- px + vx * interval

    py <- py + vy * interval

  member x.Size

    with get() = sz

  member x.Position     with get() = (px, py)

 

  member x.CenterPosition

    with get() = ((px + 1.0<px> * (float (sz.Width / 2.0f))), (py + 1.0<px> * (float (sz.Height / 2.0f))))

 

  member x.Velocity

    with get() = (vx, vy)

    and set (v:float<px/s>*float<px/s>) =

      vx <- fst v

      vy <- snd v

type SampleViewlet() as x =

  inherit Viewlet()

  let balls = new ResizeArray<Ball>()

  let framerate = 0.02<s>

  let t = new Timer()

  let mutable newball:Option<Ball> = None

  let mutable mousepos = (0, 0)

 

  do

    t.Interval <- int(framerate * 1000.0)

    t.Tick.Add(fun _ ->

    balls |> ResizeArray.iter (fun b ->

      b.Update(framerate)

      let px, py = b.Position

      let pxi = (int px)

      let pyi = (int py)      let mutable vx, vy = b.Velocity

 

      if (pxi < 0 || pxi > x.ClientSize.Width - (int b.Size.Width)) then

        vx <- vx * -1.0

      if (pyi < 0 || pyi > x.ClientSize.Height - (int b.Size.Height)) then

        vy <- vy * -1.0

 

      b.Velocity <- (vx, vy)

      )

 

      x.Invalidate()

    )

    t.Start()

    x.Text <- "Animate!"

  override x.OnMouseDown e =

    mousepos <- (e.X, e.Y)

    let px = 1.0<px>*((float e.X) - ((float ballsz.Width) / 2.0))

    let py = 1.0<px>*((float e.Y) - ((float ballsz.Height) / 2.0))

    let b = new Ball(px, py, 0.0<px/s>, 0.0<px/s>)

    balls.Add(b)

    newball <- Some(b)

  override x.OnMouseMove e =

    if newball.IsSome then

      mousepos <- (e.X, e.Y)

  override x.OnMouseUp e =

    if newball.IsSome then

      let px, py = newball.Value.Position

      let vx = (float (fst mousepos - (int px)))*1.0<px/s>

      let vy = (float (snd mousepos - (int py)))*1.0<px/s>

      newball.Value.Velocity <- (vx, vy)

      newball <- None

  override x.OnPaint e =    let g = e.Graphics

    g.SmoothingMode <- Drawing2D.SmoothingMode.AntiAlias

    balls |> ResizeArray.iter (fun b ->

    let px, py = b.Position

    g.FillEllipse(Brushes.Blue, (single px), (single py), ballsz.Width, ballsz.Height))

    if newball.IsSome then

      let px, py = newball.Value.CenterPosition

      let ipx = (int px)

      let ipy = (int py)

      let mx, my = mousepos

      use p = new Pen(Color.Black)

      p.EndCap <- Drawing2D.LineCap.ArrowAnchor

      g.DrawLine(p, ipx, ipy, mx, my)

 

  override x.OnViewletVisibilityChange e =

  t.Enabled <- e

let v = new SampleViewlet()

v.Show()

v.Close()

Currently rated 2.8 by 8 people

  • Currently 2.75/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

General | Viewlets

Massage yourself with VSLab

by cisterni 6. October 2008 19:53

I just ordered the Gaming Jacket from TNGames  and guess what? I couldn't resist to implement a F#/VSLab library for controlling the gaming Jacket from F#.

I compiled a C++ DLL that simply exposes the API and defined F# PInvoke statements in a module. A class is used to expose the Jacket to F# programs including to the F# interactive.

This is an example of usage:

#light

#r @"ManagedJacket.dll"

open ManagedJacket

open System

let j = new Jacket()

let sequence = [| Actuator.BackBottomLeft; Actuator.FrontBottomLeft; Actuator.BackBottomRight; Actuator.FrontBottomRight; Actuator.BackTopLeft; Actuator.FrontTopLeft; Actuator.BackTopRight; Actuator.FrontTopRight |]

for i in 1..10 do

  for v in sequence do

    j.SetAirCell 5uy v

System.Threading.Thread.Sleep 100

(j :> IDisposable).Dispose()

 This code performs a very simple form of massage. Now we are considering to use blasts when you do bad coding in Visual Studio!!!

I include the definition of the library that maps one on one on the functionality of the SDK.

This is the content of the interop.fs file:

#light

module ManagedJacket.Interop

open System.Runtime.InteropServices

[<DllImport("JacketDLL.dll")>]

extern int internal Jacket_SetUpJacket()

[<DllImport("JacketDLL.dll")>]

extern void internal Jacket_TearDownJacket()

[<DllImport("JacketDLL.dll")>]

extern int internal Jacket_SetEffect(int nEffect)

[<DllImport("JacketDLL.dll")>]

extern int internal Jacket_SetEffect2(int speed,int actuator)

[<DllImport("JacketDLL.dll")>]

extern void internal Jacket_FlushBuffer(int actuator)

[<DllImport("JacketDLL.dll")>]

extern int internal Jacket_GetErrorCode()

And this is the public definition of the library (jacket.fs):

#light

namespace ManagedJacket

open ManagedJacket.Interop

type Effect =

| MachinegunFront = 0

| MachinegunBack = 1

| BigBlastFront = 2

| BigBlastBack = 3

| SmallBlastFront = 4

| SmallBlastBack = 5

| PistolFront = 6

| PunchFront = 7

| StabFront = 8

| ShotgunFront = 9

| RifleFront = 10

| PistolBack = 11

| PunchBack = 12

| StabBack = 13

| ShotgunBack = 14

| RifleBack = 15

| LeftSideHit = 16

| RightSideHit = 17

| Acceleration = 18

| Deceleration = 19

| Leftturn = 20

| Rightturn = 21

| AccelerationStop = 22

| DecelerationStop = 23

| LeftturnStop = 24

| RightturnStop = 25

type Actuator =

| FrontTopRight = 1

| FrontTopLeft = 2

| FrontBottomRight = 3

| FrontBottomLeft = 4

| BackTopRight = 5

| BackTopLeft = 6

| BackBottomRight = 7

| BackBottomLeft = 8

type Jacket() =

  do

    if Jacket_SetUpJacket() <> 0 then failwith "Error connecting with Jacket"

 

  member x.SetPredefinedEffect(e:Effect) =

    if Jacket_SetEffect (int e) <> 0 then failwith "Error activating effect"

 

  member x.SetAirCell (speed:byte) (actuator:Actuator) =

    if Jacket_SetEffect2((int speed), (int actuator)) <> 0 then failwith "Error activating effect"

 

  member x.FlushBuffer (actuator:Actuator) =

    Jacket_FlushBuffer(int actuator)

 

  interface System.IDisposable with

    member x.Dispose() =

      Jacket_TearDownJacket()

A video will follow.

Currently rated 2.7 by 3 people

  • Currently 2.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Applications | General

VSLab Visual Tutorial updated!

by cisterni 5. October 2008 19:38
I finally managed to update the VSLab visual tutorial. Now I have to go through the rest of the documentation and update it. Then I can move on further development. Nevertheless during this process I'm writing unit and regression tests for viewlets.

Currently rated 2.7 by 3 people

  • Currently 2.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

General

Powered by BlogEngine.NET 1.4.0.0
Theme by Mads Kristensen

VSLab blog

VSLab is a Visual Studio extension designed to support Visual Studio interaction from F# interactive. It is a Microsoft product developed at University of Pisa, by a team lead by Antonio Cisternino.

Resources

Recent comments

Comment RSS

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in  anyway.

© Copyright 2008