Skip to content

Commit

Permalink
Merge pull request #510 from gemini-hlsw/probe-guide
Browse files Browse the repository at this point in the history
Probe guide
  • Loading branch information
cquiroz authored Jan 30, 2024
2 parents 96620cf + e6d7577 commit e7b42d1
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 16 deletions.
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ lazy val navigate_server = project
libraryDependencies ++= Seq(
CatsEffect.value,
Fs2,
Log4Cats.value
Log4Cats.value,
LucumaAgs
) ++ MUnit.value ++ LucumaCore.value ++ Http4sClient
)
.dependsOn(navigate_model % "compile->compile;test->test")
Expand Down
16 changes: 16 additions & 0 deletions modules/server/src/main/scala/navigate/server/tcs/ProbeGuide.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package navigate.server.tcs

import cats.Eq
import cats.Show
import cats.derived.*
import lucuma.ags.GuideProbe

/** Data type for guide config. */
case class ProbeGuide(
from: GuideProbe,
to: GuideProbe
) derives Eq,
Show
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel](

val m1 = (x: TcsCommands[F]) =>
config.m1Guide match {
case M1GuideConfig.M1GuideOff => x.m1GuideCommand.state(false)
case M1GuideConfig.M1GuideOff =>
x.m1GuideCommand.state(false).probeGuideModeCommand.setMode(config.probeGuide)
case M1GuideConfig.M1GuideOn(source) =>
x.m1GuideCommand
.state(true)
Expand All @@ -384,6 +385,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel](
.frames(1)
.m1GuideConfigCommand
.filename("")
.probeGuideModeCommand
.setMode(config.probeGuide)
}

config.m2Guide match {
Expand All @@ -396,6 +399,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel](
.mode(config.mountGuide)
.mountGuideCommand
.source("SCS")
.probeGuideModeCommand
.setMode(config.probeGuide)
.post
.verifiedRun(ConnectionTimeout)
case M2GuideConfig.M2GuideOn(coma, sources) =>
Expand All @@ -405,7 +410,11 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel](
.flatMap(x => beams.map(y => (x, y)))
.foldLeft(
requireReset.fold(
gains(tcsEpics.startCommand(timeout)).m2GuideResetCommand.mark.post
tcsEpics
.startCommand(timeout)
.m2GuideResetCommand
.mark
.post
.verifiedRun(ConnectionTimeout),
ApplyCommandResult.Completed.pure[F]
)
Expand All @@ -427,6 +436,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel](
.beam(beam)
.m2GuideConfigCommand
.reset(false)
.probeGuideModeCommand
.setMode(config.probeGuide)
.post
.verifiedRun(ConnectionTimeout),
r.pure[F]
Expand All @@ -441,6 +452,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel](
.mode(config.mountGuide)
.mountGuideCommand
.source("SCS")
.probeGuideModeCommand
.setMode(config.probeGuide)
.post
.verifiedRun(ConnectionTimeout),
ApplyCommandResult.Completed.pure[F]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ case class TcsChannels[F[_]](
mountGuide: MountGuideChannels[F],
oiwfs: WfsChannels[F],
guide: GuideConfigStatusChannels[F],
guiderGains: GuiderGainsChannels[F]
guiderGains: GuiderGainsChannels[F],
probeGuideMode: ProbeGuideModeChannels[F]
)

object TcsChannels {
Expand Down Expand Up @@ -513,6 +514,23 @@ object TcsChannels {
)
}

case class ProbeGuideModeChannels[F[_]](
state: Channel[F, String],
from: Channel[F, String],
to: Channel[F, String]
)

object ProbeGuideModeChannels {
def build[F[_]](
service: EpicsService[F],
top: TcsTop
): Resource[F, ProbeGuideModeChannels[F]] = for {
state <- service.getChannel[String](top.value, "wfsGuideMode.A")
from <- service.getChannel[String](top.value, "wfsGuideMode.B")
to <- service.getChannel[String](top.value, "wfsGuideMode.C")
} yield ProbeGuideModeChannels(state, from, to)
}

object GuiderGains {
def build[F[_]](
service: EpicsService[F],
Expand Down Expand Up @@ -601,6 +619,7 @@ object TcsChannels {
oi <- WfsChannels.build(service, tcsTop, "oiwfs", "oi")
gd <- GuideConfigStatusChannels.build(service, tcsTop)
gg <- GuiderGains.build(service, pwfs1Top, pwfs2Top, oiTop)
gm <- ProbeGuideModeChannels.build(service, tcsTop)
} yield TcsChannels[F](
tt,
p1tt,
Expand Down Expand Up @@ -631,7 +650,8 @@ object TcsChannels {
mng,
oi,
gd,
gg
gg,
gm
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import cats.effect.Resource
import cats.effect.Temporal
import cats.effect.std.Dispatcher
import eu.timepit.refined.types.string.NonEmptyString
import lucuma.ags.GuideProbe
import lucuma.core.math.Angle
import mouse.all.*
import navigate.epics.Channel
Expand Down Expand Up @@ -89,6 +90,7 @@ object TcsEpicsSystem {
val p1GuiderGainsCmd: Command3Channels[F, Double, Double, Double]
val p2GuiderGainsCmd: Command3Channels[F, Double, Double, Double]
val oiGuiderGainsCmd: Command3Channels[F, Double, Double, Double]
val probeGuideModeCmd: Command3Channels[F, BinaryOnOff, GuideProbe, GuideProbe]

// val offsetACmd: OffsetCmd[F]
// val offsetBCmd: OffsetCmd[F]
Expand Down Expand Up @@ -897,6 +899,21 @@ object TcsEpicsSystem {
)

}

override val probeGuideModeCommand: ProbeGuideModeCommand[F, TcsCommands[F]] =
new ProbeGuideModeCommand[F, TcsCommands[F]] {
override def setMode(pg: Option[ProbeGuide]): TcsCommands[F] =
pg.fold(
addParam(tcsEpics.probeGuideModeCmd.setParam1(BinaryOnOff.Off))
)(pg =>
addMultipleParams(
List(tcsEpics.probeGuideModeCmd.setParam1(BinaryOnOff.On),
tcsEpics.probeGuideModeCmd.setParam2(pg.from),
tcsEpics.probeGuideModeCmd.setParam3(pg.to)
)
)
)
}
}

class TcsEpicsSystemImpl[F[_]: Monad: Parallel](epics: TcsEpics[F], st: TcsStatus[F])
Expand All @@ -911,6 +928,12 @@ object TcsEpicsSystem {
applyCmd: GeminiApplyCommand[F],
channels: TcsChannels[F]
) extends TcsEpics[F] {
given Encoder[GuideProbe, String] = _ match {
case GuideProbe.GmosOiwfs => "OIWFS"
case GuideProbe.Pwfs1 => "PWFS1"
case GuideProbe.Pwfs2 => "PWFS2"
}

override def post(timeout: FiniteDuration): VerifiedEpics[F, F, ApplyCommandResult] =
applyCmd.post(timeout)

Expand Down Expand Up @@ -1073,6 +1096,14 @@ object TcsEpicsSystem {
channels.guiderGains.oiTiltGain,
channels.guiderGains.oiFocusGain
)

override val probeGuideModeCmd: Command3Channels[F, BinaryOnOff, GuideProbe, GuideProbe] =
Command3Channels(
channels.telltale,
channels.probeGuideMode.state,
channels.probeGuideMode.from,
channels.probeGuideMode.to
)
}

case class ParameterlessCommandChannels[F[_]: Monad](
Expand Down Expand Up @@ -1508,6 +1539,10 @@ object TcsEpicsSystem {
def fileName(v: String): S
}

trait ProbeGuideModeCommand[F[_], +S] {
def setMode(pg: Option[ProbeGuide]): S
}

trait WfsSignalProcConfigCommand[F[_], +S] {
def darkFilename(v: String): S
}
Expand Down Expand Up @@ -1561,6 +1596,7 @@ object TcsEpicsSystem {
val mountGuideCommand: MountGuideCommand[F, TcsCommands[F]]
val oiWfsCommands: WfsCommands[F, TcsCommands[F]]
val guiderGainsCommands: GuiderGainsCommand[F, TcsCommands[F]]
val probeGuideModeCommand: ProbeGuideModeCommand[F, TcsCommands[F]]
}
/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ case class TelescopeGuideConfig(
mountGuide: Boolean,
m1Guide: M1GuideConfig,
m2Guide: M2GuideConfig,
dayTimeMode: Boolean
dayTimeMode: Boolean,
probeGuide: Option[ProbeGuide]
) derives Eq,
Show
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package navigate.server.tcs
import cats.effect.IO
import cats.effect.Ref
import cats.syntax.all.*
import lucuma.ags.GuideProbe
import lucuma.core.math.Angle
import lucuma.core.math.Coordinates
import lucuma.core.math.Epoch
Expand Down Expand Up @@ -34,7 +35,7 @@ import TcsBaseController.*
import M2GuideConfig.M2GuideOn
import TestTcsEpicsSystem.GuideConfigState

class TcsBaseControllerEpicsSpec extends CatsEffectSuite {
class TcsBaseControllerEpicsSuite extends CatsEffectSuite {

private val DefaultTimeout: FiniteDuration = FiniteDuration(1, TimeUnit.SECONDS)

Expand Down Expand Up @@ -574,7 +575,8 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite {
mountGuide = true,
m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs),
m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)),
dayTimeMode = false
dayTimeMode = false,
probeGuide = none
)

for {
Expand Down Expand Up @@ -660,7 +662,8 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite {
mountGuide = true,
m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs),
m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)),
dayTimeMode = true
dayTimeMode = true,
probeGuide = none
)

for {
Expand Down Expand Up @@ -746,7 +749,8 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite {
mountGuide = true,
m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs),
m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)),
false
dayTimeMode = false,
probeGuide = none
)

for {
Expand All @@ -772,6 +776,7 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite {
assert(r1.m2GuideReset.connected)
assert(r1.mountGuide.mode.connected)
assert(r1.mountGuide.source.connected)
assert(r1.probeGuideMode.state.connected)

assertEquals(r1.m1Guide.value.flatMap(Enumerated[BinaryOnOff].fromTag), BinaryOnOff.On.some)
assertEquals(r1.m1GuideConfig.source.value.flatMap(Enumerated[M1Source].fromTag),
Expand Down Expand Up @@ -804,6 +809,59 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite {
assertEquals(r2.mountGuide.mode.value.flatMap(Enumerated[BinaryOnOff].fromTag),
BinaryOnOff.Off.some
)
assertEquals(r1.probeGuideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag),
BinaryOnOff.Off.some
)
}
}

test("Set guide mode OIWFS to OIWFS") {
val guideCfg = TelescopeGuideConfig(
mountGuide = true,
m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs),
m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)),
dayTimeMode = false,
probeGuide = ProbeGuide(GuideProbe.GmosOiwfs, GuideProbe.GmosOiwfs).some
)

for {
x <- createController
(st, ctr) = x
_ <- ctr.enableGuide(guideCfg)
r1 <- st.get
} yield {
assert(r1.probeGuideMode.state.connected)

assertEquals(r1.probeGuideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag),
BinaryOnOff.On.some
)
assertEquals(r1.probeGuideMode.from.value, "OIWFS".some)
assertEquals(r1.probeGuideMode.to.value, "OIWFS".some)
}
}

test("Set guide mode PWFS1 to PWFS2") {
val guideCfg = TelescopeGuideConfig(
mountGuide = true,
m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs),
m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)),
dayTimeMode = false,
probeGuide = ProbeGuide(GuideProbe.Pwfs1, GuideProbe.Pwfs2).some
)

for {
x <- createController
(st, ctr) = x
_ <- ctr.enableGuide(guideCfg)
r1 <- st.get
} yield {
assert(r1.probeGuideMode.state.connected)

assertEquals(r1.probeGuideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag),
BinaryOnOff.On.some
)
assertEquals(r1.probeGuideMode.from.value, "PWFS1".some)
assertEquals(r1.probeGuideMode.to.value, "PWFS2".some)
}
}

Expand Down
Loading

0 comments on commit e7b42d1

Please sign in to comment.