Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagohm committed Dec 26, 2023
2 parents 31e59b5 + f318b1f commit 94e19ad
Show file tree
Hide file tree
Showing 333 changed files with 6,149 additions and 3,547 deletions.
12 changes: 9 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ updates:
directory: "/"
schedule:
interval: "monthly"
day: "friday"
open-pull-requests-limit: 16
target-branch: "dev"
commit-message:
Expand All @@ -28,15 +27,20 @@ updates:
okhttp:
patterns:
- "com.squareup.okhttp3*"
rx:
patterns:
- "io.reactivex.rxjava3*"
jackson:
patterns:
- "com.fasterxml.jackson*"
kotlin:
patterns:
- "org.jetbrains.kotlin*"

- package-ecosystem: "npm"
directory: "/desktop"
schedule:
interval: "monthly"
day: "friday"
open-pull-requests-limit: 64
target-branch: "dev"
commit-message:
Expand All @@ -45,12 +49,14 @@ updates:
angular:
patterns:
- "@angular*"
types:
patterns:
- "@types*"

- package-ecosystem: "npm"
directory: "/desktop/app"
schedule:
interval: "monthly"
day: "friday"
target-branch: "dev"
commit-message:
prefix: "[desktop]"
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ objectbox*.dll
libobjectbox*.so
libobjectbox*.dylib

### Kotlin ###
.kotlin

# End of https://www.toptal.com/developers/gitignore/api/intellij,kotlin,java,gradle

**/saved/*.png
Expand Down
2 changes: 1 addition & 1 deletion api/Main.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
value="nebulosa.api.MainKt"/>
<module name="nebulosa.api.main"/>
<option name="PROGRAM_PARAMETERS"
value="--server.port=7000 --spring.jpa.show-sql=true"/>
value="--server.port=7000 --spring.jpa.show-sql=true --logging.level.nebulosa=DEBUG"/>
<shortenClasspath name="NONE"/>
<method v="2">
<option name="Gradle.BeforeRunTask"
Expand Down
8 changes: 4 additions & 4 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import org.springframework.boot.gradle.tasks.bundling.BootJar

plugins {
kotlin("jvm")
id("org.springframework.boot") version "3.2.0"
id("org.springframework.boot") version "3.2.1"
id("io.spring.dependency-management") version "1.1.4"
kotlin("plugin.spring")
kotlin("kapt")
Expand All @@ -11,6 +11,7 @@ plugins {
dependencies {
implementation(project(":nebulosa-astap"))
implementation(project(":nebulosa-astrometrynet"))
implementation(project(":nebulosa-batch-processing"))
implementation(project(":nebulosa-common"))
implementation(project(":nebulosa-guiding-phd2"))
implementation(project(":nebulosa-hips2fits"))
Expand All @@ -31,8 +32,8 @@ dependencies {
implementation(libs.flyway)
implementation(libs.okhttp)
implementation(libs.oshi)
implementation(libs.rx)
implementation(libs.sqlite)
implementation(libs.hikari)
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-web") {
exclude(module = "spring-boot-starter-tomcat")
Expand All @@ -41,13 +42,12 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-websocket") {
exclude(module = "spring-boot-starter-tomcat")
}
implementation("org.springframework.boot:spring-boot-starter-batch")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-undertow")
implementation("org.hibernate.orm:hibernate-community-dialects")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
kapt("org.springframework:spring-context-indexer:6.1.1")
kapt("org.springframework:spring-context-indexer:6.1.2")
testImplementation(project(":nebulosa-test"))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package nebulosa.api.alignment.polar

import nebulosa.api.alignment.polar.darv.DARVStart
import nebulosa.api.beans.annotations.EntityBy
import nebulosa.api.alignment.polar.darv.DARVStartRequest
import nebulosa.api.beans.converters.indi.DeviceOrEntityParam
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.guide.GuideOutput
import org.springframework.web.bind.annotation.PutMapping
Expand All @@ -17,14 +17,14 @@ class PolarAlignmentController(

@PutMapping("darv/{camera}/{guideOutput}/start")
fun darvStart(
@EntityBy camera: Camera, @EntityBy guideOutput: GuideOutput,
@RequestBody body: DARVStart,
@DeviceOrEntityParam camera: Camera, @DeviceOrEntityParam guideOutput: GuideOutput,
@RequestBody body: DARVStartRequest,
) {
polarAlignmentService.darvStart(camera, guideOutput, body)
}

@PutMapping("darv/{camera}/{guideOutput}/stop")
fun darvStop(@EntityBy camera: Camera, @EntityBy guideOutput: GuideOutput) {
fun darvStop(@DeviceOrEntityParam camera: Camera, @DeviceOrEntityParam guideOutput: GuideOutput) {
polarAlignmentService.darvStop(camera, guideOutput)
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
package nebulosa.api.alignment.polar

import nebulosa.api.alignment.polar.darv.DARVPolarAlignmentExecutor
import nebulosa.api.alignment.polar.darv.DARVStart
import nebulosa.api.alignment.polar.darv.DARVExecutor
import nebulosa.api.alignment.polar.darv.DARVStartRequest
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.guide.GuideOutput
import org.springframework.stereotype.Service

@Service
class PolarAlignmentService(
private val darvPolarAlignmentExecutor: DARVPolarAlignmentExecutor,
private val darvExecutor: DARVExecutor,
) {

fun darvStart(camera: Camera, guideOutput: GuideOutput, darvStart: DARVStart) {
fun darvStart(camera: Camera, guideOutput: GuideOutput, darvStartRequest: DARVStartRequest) {
check(camera.connected) { "camera not connected" }
check(guideOutput.connected) { "guide output not connected" }
darvPolarAlignmentExecutor.execute(darvStart.copy(camera = camera, guideOutput = guideOutput))
darvExecutor.execute(darvStartRequest.copy(camera = camera, guideOutput = guideOutput))
}

fun darvStop(camera: Camera, guideOutput: GuideOutput) {
darvPolarAlignmentExecutor.stop(camera, guideOutput)
darvExecutor.stop(camera, guideOutput)
}
}
25 changes: 25 additions & 0 deletions api/src/main/kotlin/nebulosa/api/alignment/polar/darv/DARVEvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package nebulosa.api.alignment.polar.darv

import nebulosa.api.messages.MessageEvent
import nebulosa.guiding.GuideDirection
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.guide.GuideOutput
import java.time.Duration

sealed interface DARVEvent : MessageEvent {

val camera: Camera

val guideOutput: GuideOutput

val remainingTime: Duration

val progress: Double

val direction: GuideDirection?

val state: DARVState

override val eventName
get() = "DARV_POLAR_ALIGNMENT_ELAPSED"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package nebulosa.api.alignment.polar.darv

import io.reactivex.rxjava3.functions.Consumer
import nebulosa.api.messages.MessageEvent
import nebulosa.api.messages.MessageService
import nebulosa.batch.processing.JobExecution
import nebulosa.batch.processing.JobLauncher
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.guide.GuideOutput
import nebulosa.log.debug
import nebulosa.log.loggerFor
import org.springframework.stereotype.Component
import java.util.*

/**
* @see <a href="https://www.cloudynights.com/articles/cat/articles/darv-drift-alignment-by-robert-vice-r2760">Reference</a>
*/
@Component
class DARVExecutor(
private val jobLauncher: JobLauncher,
private val messageService: MessageService,
) : Consumer<MessageEvent> {

private val jobExecutions = LinkedList<JobExecution>()

@Synchronized
fun execute(request: DARVStartRequest) {
val camera = requireNotNull(request.camera)
val guideOutput = requireNotNull(request.guideOutput)

check(!isRunning(camera, guideOutput)) { "DARV job is already running" }

LOG.debug { "starting DARV. request=%s".format(request) }

with(DARVJob(request)) {
subscribe(this@DARVExecutor)
val jobExecution = jobLauncher.launch(this)
jobExecutions.add(jobExecution)
}
}

fun findJobExecution(camera: Camera, guideOutput: GuideOutput): JobExecution? {
for (i in jobExecutions.indices.reversed()) {
val jobExecution = jobExecutions[i]
val job = jobExecution.job as DARVJob

if (!jobExecution.isDone && job.camera === camera && job.guideOutput === guideOutput) {
return jobExecution
}
}

return null
}

@Synchronized
fun stop(camera: Camera, guideOutput: GuideOutput) {
val jobExecution = findJobExecution(camera, guideOutput) ?: return
jobLauncher.stop(jobExecution)
}

fun isRunning(camera: Camera, guideOutput: GuideOutput): Boolean {
return findJobExecution(camera, guideOutput) != null
}

override fun accept(event: MessageEvent) {
messageService.sendMessage(event)
}

companion object {

@JvmStatic private val LOG = loggerFor<DARVExecutor>()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package nebulosa.api.alignment.polar.darv

import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.guide.GuideOutput
import java.time.Duration

data class DARVFinished(
override val camera: Camera,
override val guideOutput: GuideOutput,
) : DARVEvent {

override val remainingTime = Duration.ZERO!!
override val progress = 0.0
override val state = DARVState.IDLE
override val direction = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package nebulosa.api.alignment.polar.darv

import nebulosa.api.messages.MessageEvent
import nebulosa.guiding.GuideDirection
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.guide.GuideOutput
import java.time.Duration

data class DARVGuidePulseElapsed(
override val camera: Camera,
override val guideOutput: GuideOutput,
override val remainingTime: Duration,
override val progress: Double,
override val direction: GuideDirection,
override val state: DARVState,
) : MessageEvent, DARVEvent
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package nebulosa.api.alignment.polar.darv

import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.guide.GuideOutput
import java.time.Duration

data class DARVInitialPauseElapsed(
override val camera: Camera,
override val guideOutput: GuideOutput,
override val remainingTime: Duration,
override val progress: Double,
) : DARVEvent {

override val state = DARVState.INITIAL_PAUSE
override val direction = null
}
83 changes: 83 additions & 0 deletions api/src/main/kotlin/nebulosa/api/alignment/polar/darv/DARVJob.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package nebulosa.api.alignment.polar.darv

import io.reactivex.rxjava3.subjects.PublishSubject
import nebulosa.api.cameras.*
import nebulosa.api.guiding.GuidePulseListener
import nebulosa.api.guiding.GuidePulseRequest
import nebulosa.api.guiding.GuidePulseStep
import nebulosa.api.messages.MessageEvent
import nebulosa.batch.processing.*
import nebulosa.batch.processing.ExecutionContext.Companion.getDouble
import nebulosa.batch.processing.ExecutionContext.Companion.getDuration
import nebulosa.batch.processing.ExecutionContext.Companion.getPath
import nebulosa.batch.processing.delay.DelayStep
import nebulosa.batch.processing.delay.DelayStepListener
import nebulosa.indi.device.camera.FrameType
import java.nio.file.Files
import java.time.Duration

data class DARVJob(
val request: DARVStartRequest,
) : SimpleJob(), PublishSubscribe<MessageEvent>, CameraCaptureListener, GuidePulseListener, DelayStepListener {

@JvmField val camera = requireNotNull(request.camera)
@JvmField val guideOutput = requireNotNull(request.guideOutput)
@JvmField val direction = if (request.reversed) request.direction.reversed else request.direction

@JvmField val cameraRequest = (request.capture ?: CameraStartCaptureRequest()).copy(
camera = camera,
exposureTime = request.exposureTime + request.initialPause,
savePath = Files.createTempDirectory("darv"),
exposureAmount = 1, exposureDelay = Duration.ZERO,
frameType = FrameType.LIGHT, autoSave = false, autoSubFolderMode = AutoSubFolderMode.OFF
)

override val subject = PublishSubject.create<MessageEvent>()

init {
val cameraExposureStep = CameraExposureStep(cameraRequest)
cameraExposureStep.registerCameraCaptureListener(this)

val initialPauseDelayStep = DelayStep(request.initialPause)
initialPauseDelayStep.registerDelayStepListener(this)

val guidePulseDuration = request.exposureTime.dividedBy(2L)
val forwardGuidePulseRequest = GuidePulseRequest(guideOutput, direction, guidePulseDuration)
val forwardGuidePulseStep = GuidePulseStep(forwardGuidePulseRequest)
forwardGuidePulseStep.registerGuidePulseListener(this)

val backwardGuidePulseRequest = GuidePulseRequest(guideOutput, direction.reversed, guidePulseDuration)
val backwardGuidePulseStep = GuidePulseStep(backwardGuidePulseRequest)
backwardGuidePulseStep.registerGuidePulseListener(this)

val guideFlow = SimpleFlowStep(initialPauseDelayStep, forwardGuidePulseStep, backwardGuidePulseStep)
add(SimpleSplitStep(cameraExposureStep, guideFlow))
}

override fun beforeJob(jobExecution: JobExecution) {
onNext(DARVStarted(camera, guideOutput, request.initialPause, direction))
}

override fun afterJob(jobExecution: JobExecution) {
onNext(DARVFinished(camera, guideOutput))
}

override fun onExposureFinished(step: CameraExposureStep, stepExecution: StepExecution) {
val savePath = stepExecution.context.getPath(CameraExposureStep.SAVE_PATH)!!
onNext(CameraExposureFinished(stepExecution.jobExecution, step.camera, 1, 1, Duration.ZERO, 1.0, Duration.ZERO, savePath))
}

override fun onGuidePulseElapsed(step: GuidePulseStep, stepExecution: StepExecution) {
val direction = step.request.direction
val remainingTime = stepExecution.context.getDuration(DelayStep.REMAINING_TIME)
val progress = stepExecution.context.getDouble(DelayStep.PROGRESS)
val state = if (direction == this.direction) DARVState.FORWARD else DARVState.BACKWARD
onNext(DARVGuidePulseElapsed(camera, guideOutput, remainingTime, progress, direction, state))
}

override fun onDelayElapsed(step: DelayStep, stepExecution: StepExecution) {
val remainingTime = stepExecution.context.getDuration(DelayStep.REMAINING_TIME)
val progress = stepExecution.context.getDouble(DelayStep.PROGRESS)
onNext(DARVInitialPauseElapsed(camera, guideOutput, remainingTime, progress))
}
}
Loading

0 comments on commit 94e19ad

Please sign in to comment.