Skip to content

Commit

Permalink
Merge pull request #72 from AllenNeuralDynamics/bc/add-zaber-axis-set…
Browse files Browse the repository at this point in the history
…tings

Add operators to directly interface with Axis `Settings`
  • Loading branch information
bruno-f-cruz authored Jul 30, 2024
2 parents 85d677c + c12267f commit d8c66ff
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageTags>Bonsai Rx Zaber AllenNeuralDynamics</PackageTags>
<TargetFramework>net472</TargetFramework>
<Features>strict</Features>
<Version>0.5.0</Version>
<Version>0.5.1</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
64 changes: 64 additions & 0 deletions src/AllenNeuralDynamics.Zaber/GetSetting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.ComponentModel;
using System.Reactive.Linq;
using Bonsai;
using Zaber.Motion;
using Zaber.Motion.Ascii;

namespace AllenNeuralDynamics.Zaber
{
/// <summary>
/// Represents an operator that sends reads a setting from a given axis..
/// </summary>
[Description("Gets the value of a setting from an axis.")]
public class GetSetting : Combinator<double>
{
/// <summary>
/// Gets or sets the COM port or alias of the target <see cref="ZaberDevice"/>
/// </summary>
[TypeConverter(typeof(PortNameConverter))]
[Description("The name of the serial port used to communicate with the manipulator.")]
public string PortName { get; set; }

/// <summary>
/// Gets or sets the device to be controlled. Defaults to 0.
/// </summary>
[Description("The axis index to be actuated.")]
public int? Device { get; set; }

/// <summary>
/// Gets or sets the axis of the manipulator to be controlled.
/// </summary>
[Description("The axis index to be actuated.")]
public int Axis { get; set; }

/// <summary>
/// Gets or sets the axis setting to be queried.
/// </summary>
[Description("The setting to get.")]
public string Setting { get; set; }


/// <summary>
/// Gets or sets the Units of the transaction.
/// </summary>
[Description("The setting to get.")]
public Units Units { get; set; } = Units.Native;

/// <summary>
/// Sends a request to get a specific setting for an axis.
/// </summary>
/// <returns>
/// On each event, it will emit the response of the device.
/// </returns>
public override IObservable<double> Process<T>(IObservable<T> source)
{
return Observable.Using(
async token => await ZaberDeviceManager.ReserveConnectionAsync(PortName),
async (connection, cancellationToken) => source.Select(_ =>

Check warning on line 58 in src/AllenNeuralDynamics.Zaber/GetSetting.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
Observable.FromAsync( async token =>
await connection.Device.GetSetting(Device, Axis, Setting, Units)
)).Concat());
}
}
}
77 changes: 77 additions & 0 deletions src/AllenNeuralDynamics.Zaber/SetSetting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using System.ComponentModel;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Bonsai;
using Zaber.Motion;


namespace AllenNeuralDynamics.Zaber
{
/// <summary>
/// Represents an operator that sets a setting for a specified axis.
/// </summary>
[Description("Sets an axis setting.")]
public class SetSetting : Sink<double>
{
/// <summary>
/// Gets or sets the COM port or alias of the target <see cref="ZaberDevice"/>
/// </summary>
[TypeConverter(typeof(PortNameConverter))]
[Description("The name of the serial port used to communicate with the manipulator.")]
public string PortName { get; set; }

/// <summary>
/// Gets or sets the device to be controlled. Defaults to 0.
/// </summary>
[Description("The axis index to be actuated.")]
public int? Device { get; set; }

/// <summary>
/// Gets or sets the axis of the manipulator to be controlled.
/// </summary>
[Description("The axis index to be actuated.")]
public int Axis { get; set; }

/// <summary>
/// Gets or sets the axis setting to be set.
/// </summary>
[Description("The setting to get.")]
public string Setting { get; set; }


/// <summary>
/// Gets or sets the Units of the transaction.
/// </summary>
[Description("The setting to get.")]
public Units Units { get; set; } = Units.Native;

/// <summary>
/// Moves to the target absolute position when a valid value is received.
/// </summary>
/// <returns>
/// Returns the original input sequence.
/// </returns>
public override IObservable<double> Process(IObservable<double> source)
{
return Observable.Using(
cancellationToken => ZaberDeviceManager.ReserveConnectionAsync(PortName),
(connection, cancellationToken) =>
{
return Task.FromResult(source.Do(value =>
{
lock (connection.Device)
{
connection.Device.SetSetting(
Device,
Axis,
Setting,
value,
Units
);
}
}));
});
}
}
}
12 changes: 12 additions & 0 deletions src/AllenNeuralDynamics.Zaber/ZaberDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,25 @@ public void Home(int? deviceIndex, int? axis)
_ = axis.HasValue ? device.GetAxis(axis.Value).HomeAsync(false) : device.AllAxes.HomeAsync(false);
}

public void SetSetting(int? deviceIndex, int axis, string setting, double value, Units units = Units.Native)
{
Axis thisAxis = devices[deviceIndex.HasValue ? deviceIndex.Value : 0].GetAxis(axis);
thisAxis.Settings.SetAsync(setting, value, units);
}

public void GenericCommandNoResponse(int? deviceIndex, int? axis, string command)
{
comm.GenericCommandNoResponseAsync(command,
deviceIndex.HasValue ? deviceIndex.Value : 0,
axis.HasValue? axis.Value : 0);
}

public async Task<double> GetSetting(int? deviceIndex, int axis, string setting, Units unit)
{
Axis thisAxis = devices[deviceIndex.HasValue ? deviceIndex.Value : 0].GetAxis(axis);
return await thisAxis.Settings.GetAsync(setting, unit);
}

public async Task<double> GetPosition(int? deviceIndex, int axis, Units unit)
{
Axis thisAxis = devices[deviceIndex.HasValue ? deviceIndex.Value : 0].GetAxis(axis);
Expand Down

0 comments on commit d8c66ff

Please sign in to comment.