From 35495a11b20be18e65cdc36cf1802f6873b1311e Mon Sep 17 00:00:00 2001 From: Mark Sproul Date: Mon, 29 Apr 2024 10:23:29 -0400 Subject: [PATCH] Build 177, Added support for GPS input --- Makefile | 477 ++++--- alpacapi_EditHistory.txt | 227 ++-- docs/index.html | 22 + src/JsonResponse.c | 2 + src/alpaca_defs.h | 4 +- src/alpacadriver.cpp | 153 ++- src/alpacadriver.h | 2 +- src/alpacadriverSetup.cpp | 4 +- src/alpacadriver_gps.cpp | 390 ++++++ src/alpacadriver_gps.h | 20 + src/calibration_Alnitak.cpp | 10 +- src/calibration_Alnitak.h | 2 +- src/cameradriver.cpp | 124 +- src/cameradriver.h | 5 +- src/cameradriverAnalysis.cpp | 6 + src/cameradriver_ASI.cpp | 10 +- src/cameradriver_ASI.h | 4 +- src/cameradriver_ATIK.cpp | 2 +- src/cameradriver_ATIK.h | 2 +- src/cameradriver_FLIR.cpp | 2 +- src/cameradriver_FLIR.h | 2 +- src/cameradriver_OGMA.cpp | 1228 ++++++++++++++++++ src/cameradriver_OGMA.h | 83 ++ src/cameradriver_QSI.cpp | 2 +- src/cameradriver_QSI.h | 2 +- src/cameradriver_SONY.cpp | 4 +- src/cameradriver_SONY.h | 2 +- src/cameradriver_TOUP.cpp | 2 +- src/cameradriver_TOUP.h | 2 +- src/cameradriver_fits.cpp | 46 +- src/cameradriver_gps.cpp | 59 +- src/cameradriver_readthread.cpp | 15 +- src/cameradriver_save.cpp | 3 +- src/cameradriver_sim.cpp | 4 + src/cameradriver_sim.h | 2 +- src/controller_image.cpp | 17 +- src/controller_image.h | 1 + src/domedriver.cpp | 2 +- src/eventlogging.c | 3 +- src/filterwheeldriver.cpp | 11 +- src/filterwheeldriver.h | 3 + src/filterwheeldriver_Play1.cpp | 454 +++++++ src/filterwheeldriver_Play1.h | 49 + src/gps_data.cpp | 105 +- src/gps_data.h | 10 + src/helper_functions.h | 1 + src/slittracker.cpp | 2 +- src/telescopedriver.cpp | 214 +++- src/telescopedriver.h | 8 + src_imu/imu_lib.c | 2 +- src_mlsLib/GPS_graph.c | 1522 ++++++++++++++++++++++ src_mlsLib/GPS_graph.h | 28 + src_mlsLib/ParseNMEA.c | 163 ++- src_mlsLib/ParseNMEA.h | 66 +- src_mlsLib/Statistics.c | 247 ++++ src_mlsLib/Statistics.h | 16 + src_mlsLib/web_graphics_opencv.cpp | 1882 ++++++++++++++++++++++++++++ src_mlsLib/web_graphics_opencv.h | 243 ++++ 58 files changed, 7546 insertions(+), 427 deletions(-) create mode 100644 src/alpacadriver_gps.cpp create mode 100644 src/alpacadriver_gps.h create mode 100644 src/cameradriver_OGMA.cpp create mode 100644 src/cameradriver_OGMA.h create mode 100644 src/filterwheeldriver_Play1.cpp create mode 100644 src/filterwheeldriver_Play1.h create mode 100644 src_mlsLib/GPS_graph.c create mode 100644 src_mlsLib/GPS_graph.h create mode 100644 src_mlsLib/Statistics.c create mode 100644 src_mlsLib/Statistics.h create mode 100644 src_mlsLib/web_graphics_opencv.cpp create mode 100644 src_mlsLib/web_graphics_opencv.h diff --git a/Makefile b/Makefile index 9691364..1c3b9d1 100755 --- a/Makefile +++ b/Makefile @@ -64,6 +64,7 @@ #++ Oct 17, 2022 Added _ENABLE_FILTERWHEEL_USIS_ #++ Mar 5, 2023 Re-organizing object lists #++ Dec 2, 2023 Added piswitch3 +#++ Apr 22, 2024 Added _INCLUDE_MULTI_LANGUAGE_SUPPORT_ ###################################################################################### # Cr_Core is for the Sony camera ###################################################################################### @@ -95,6 +96,8 @@ OPENCV_LINK += -L$(OPENCV_LIB) PHASEONE_INC = /usr/local/include/phaseone/include/ PHASEONE_LIB = /usr/local/lib/ +PLAYERONE_LIB = /usr/local/lib/ + SRC_DIR = ./src/ SRC_IMGPROC = ./src_imageproc/ SRC_IMU = ./src_imu/ @@ -103,6 +106,7 @@ SRC_MOONRISE = ./src_MoonRise/ SRC_SERVO = ./src_servo/ SRC_PDS = ./src_pds/ SRC_SKYIMAGE = ./src_skyimage/ +SRC_SPECTROGRAPH = ./src_spectrograph/ MLS_LIB_DIR = ./src_mlsLib/ OBJECT_DIR = ./Objectfiles/ @@ -143,6 +147,12 @@ TOUP_DIR = ./toupcamsdk TOUP_INCLUDE_DIR = $(TOUP_DIR)/inc TOUP_LIB_DIR = $(TOUP_DIR)/linux/x64 +############################################ +OGMA_DIR = ./OGMAcamSDK +OGMA_INCLUDE_DIR = $(OGMA_DIR)/inc +OGMA_LIB_DIR = $(OGMA_DIR)/linux/arm64 + + ############################################ FLIR_INCLUDE_DIR = /usr/include/spinnaker @@ -159,10 +169,12 @@ QHY_INCLUDE_DIR = ./QHY/include # QSI support QSI_INCLUDE_DIR = ./qsiapi-7.6.0 -DEFINEFLAGS += -D_INCLUDE_HTTP_HEADER_ -DEFINEFLAGS += -D_INCLUDE_ALPACA_EXTENSIONS_ DEFINEFLAGS += -D_ALPACA_PI_ +DEFINEFLAGS += -D_INCLUDE_ALPACA_EXTENSIONS_ +DEFINEFLAGS += -D_INCLUDE_HTTP_HEADER_ DEFINEFLAGS += -D_USE_CAMERA_READ_THREAD_ +DEFINEFLAGS += -D_INCLUDE_MULTI_LANGUAGE_SUPPORT_ + CFLAGS = -Wall -Wno-multichar -Wno-unknown-pragmas -Wstrict-prototypes CFLAGS += -Wextra #CFLAGS += -Werror @@ -199,6 +211,9 @@ INCLUDES = -I/usr/include \ -I/usr/local/include \ -I$(SRC_DIR) \ -I$(SRC_SKYIMAGE) \ + -I$(SRC_IMGPROC) \ + -I$(SRC_PDS) \ + -I$(SRC_SPECTROGRAPH) \ -I$(ASI_INCLUDE_DIR) \ -I$(ATIK_INCLUDE_DIR) \ -I$(ATIK_INCLUDE_DIR2) \ @@ -206,8 +221,6 @@ INCLUDES = -I/usr/include \ -I$(FLIR_INCLUDE_DIR) \ -I$(MLS_LIB_DIR) \ -I$(QHY_INCLUDE_DIR) \ - -I$(SRC_IMGPROC) \ - -I$(SRC_PDS) \ -I$(TOUP_INCLUDE_DIR) \ -I$(SONY_INCLUDE_DIR) \ @@ -320,20 +333,20 @@ CAMERA_DRIVER_OBJECTS= \ $(OBJECT_DIR)cameradriver_FLIR.o \ $(OBJECT_DIR)cameradriver_jpeg.o \ $(OBJECT_DIR)cameradriver_livewindow.o \ + $(OBJECT_DIR)cameradriver_OGMA.o \ $(OBJECT_DIR)cameradriver_opencv.o \ $(OBJECT_DIR)cameradriver_overlay.o \ $(OBJECT_DIR)cameradriver_png.o \ $(OBJECT_DIR)cameradriver_QHY.o \ $(OBJECT_DIR)cameradriver_QSI.o \ $(OBJECT_DIR)cameradriver_readthread.o \ + $(OBJECT_DIR)cameradriver_PlayerOne.o \ $(OBJECT_DIR)cameradriver_SONY.o \ $(OBJECT_DIR)cameradriver_save.o \ $(OBJECT_DIR)cameradriver_sim.o \ $(OBJECT_DIR)cameradriver_TOUP.o \ $(OBJECT_DIR)NASA_moonphase.o \ $(OBJECT_DIR)multicam.o \ - $(OBJECT_DIR)ParseNMEA.o \ - $(OBJECT_DIR)NMEA_helper.o \ ###################################################################################### @@ -362,6 +375,7 @@ SHUTTER_DRIVER_OBJECTS= \ FITLERWHEEL_DRIVER_OBJECTS= \ $(OBJECT_DIR)filterwheeldriver.o \ $(OBJECT_DIR)filterwheeldriver_ATIK.o \ + $(OBJECT_DIR)filterwheeldriver_Play1.o \ $(OBJECT_DIR)filterwheeldriver_QHY.o \ $(OBJECT_DIR)filterwheeldriver_ZWO.o \ $(OBJECT_DIR)filterwheeldriver_sim.o \ @@ -397,6 +411,7 @@ SWITCH_DRIVER_OBJECTS= \ TELESCOPE_DRIVER_OBJECTS= \ $(OBJECT_DIR)telescopedriver.o \ $(OBJECT_DIR)telescopedriver_comm.o \ + $(OBJECT_DIR)telescopedriver_ExpSci.o \ $(OBJECT_DIR)telescopedriver_lx200.o \ $(OBJECT_DIR)telescopedriver_Rigel.o \ $(OBJECT_DIR)telescopedriver_servo.o \ @@ -463,6 +478,10 @@ IMU_OBJECTS= \ # GPS objects GPS_OBJECTS= \ $(OBJECT_DIR)gps_data.o \ + $(OBJECT_DIR)ParseNMEA.o \ + $(OBJECT_DIR)NMEA_helper.o \ + $(OBJECT_DIR)GPS_graph.o \ + $(OBJECT_DIR)web_graphics_opencv.o \ # $(OBJECT_DIR)serialport.o \ @@ -615,6 +634,13 @@ gpscam : DEFINEFLAGS += -D_USE_OPENCV_CPP_ gpscam : DEFINEFLAGS += -D_ENABLE_CTRL_IMAGE_ gpscam : DEFINEFLAGS += -D_ENABLE_LIVE_CONTROLLER_ gpscam : DEFINEFLAGS += -D_ENABLE_GLOBAL_GPS_ +gpscam : DEFINEFLAGS += -D_ENABLE_GPS_GRAPHS_ +gpscam : DEFINEFLAGS += -D_ENABLE_ALTITUDE_TRACKING_ +gpscam : DEFINEFLAGS += -D_ENABLE_LAT_LON_TRACKING_ +gpscam : DEFINEFLAGS += -D_ENABLE_NMEA_POSITION_ERROR_TRACKING_ +gpscam : DEFINEFLAGS += -D_ENABLE_PDOP_TRACKING_ +gpscam : DEFINEFLAGS += -D_ENABLE_SATELLITE_TRAILS_ +gpscam : DEFINEFLAGS += -D_ENABLE_SATELLITE_ALMANAC_ gpscam : \ $(CAMERA_DRIVER_OBJECTS) \ $(DRIVER_OBJECTS) \ @@ -866,28 +892,30 @@ moonlite : ###################################################################################### #pragma mark make allcam # this is primarily for development, all cameras are enabled -allcam : DEFINEFLAGS += -D_INCLUDE_MILLIS_ allcam : DEFINEFLAGS += -D_ENABLE_CAMERA_ allcam : DEFINEFLAGS += -D_ENABLE_ASI_ -#allcam : DEFINEFLAGS += -D_ENABLE_ATIK_ +allcam : DEFINEFLAGS += -D_ENABLE_ATIK_ #allcam : DEFINEFLAGS += -D_ENABLE_FLIR_ allcam : DEFINEFLAGS += -D_ENABLE_QHY_ -allcam : DEFINEFLAGS += -D_ENABLE_SONY_ +#allcam : DEFINEFLAGS += -D_ENABLE_SONY_ allcam : DEFINEFLAGS += -D_ENABLE_TOUP_ +allcam : DEFINEFLAGS += -D_INCLUDE_MILLIS_ allcam : DEFINEFLAGS += -D_ENABLE_DISCOVERY_QUERRY_ allcam : DEFINEFLAGS += -D_ENABLE_FITS_ -allcam : DEFINEFLAGS += -D_ENABLE_FILTERWHEEL_ -allcam : DEFINEFLAGS += -D_ENABLE_FILTERWHEEL_ZWO_ +#allcam : DEFINEFLAGS += -D_ENABLE_FILTERWHEEL_ +#allcam : DEFINEFLAGS += -D_ENABLE_FILTERWHEEL_ZWO_ allcam : DEFINEFLAGS += -D_USE_OPENCV_ allcam : DEFINEFLAGS += -D_USE_OPENCV_CPP_ allcam : DEFINEFLAGS += -D_ENABLE_CTRL_IMAGE_ #allcam : INCLUDES += -I$(SONY_INCLUDE_DIR) allcam : DEFINEFLAGS += -D_ENABLE_LIVE_CONTROLLER_ +allcam : TOUP_LIB_DIR = $(TOUP_DIR)/linux/arm64 allcam : \ $(DRIVER_OBJECTS) \ $(CAMERA_DRIVER_OBJECTS) \ $(LIVE_WINDOW_OBJECTS) \ $(SOCKET_OBJECTS) \ + $(HELPER_OBJECTS) \ $(LINK) \ @@ -895,6 +923,7 @@ allcam : \ $(CAMERA_DRIVER_OBJECTS) \ $(LIVE_WINDOW_OBJECTS) \ $(SOCKET_OBJECTS) \ + $(HELPER_OBJECTS) \ $(OPENCV_LINK) \ -L$(ATIK_LIB_DIR)/ \ -L$(TOUP_LIB_DIR)/ \ @@ -914,7 +943,7 @@ allcam : \ ###################################################################################### #pragma mark make tele C++ linux-x86 -tele : DEFINEFLAGS += -D_INCLUDE_MILLIS_ +tele : DEFINEFLAGS += -D_INCLUDE_MILLIS_ tele : DEFINEFLAGS += -D_ENABLE_ASI_ #tele : DEFINEFLAGS += -D_ENABLE_ATIK_ tele : DEFINEFLAGS += -D_ENABLE_CAMERA_ @@ -960,7 +989,41 @@ tele : \ -o alpacapi-telescope -# -ludev \ +###################################################################################### +#pragma mark make pmc8 explore scientific +pmc8 : DEFINEFLAGS += -D_INCLUDE_MILLIS_ +pmc8 : DEFINEFLAGS += -D_USE_OPENCV_ +pmc8 : DEFINEFLAGS += -D_ENABLE_TELESCOPE_ +pmc8 : DEFINEFLAGS += -D_ENABLE_TELESCOPE_EXP_SCI_ +pmc8 : DEFINEFLAGS += -D_ENABLE_GLOBAL_GPS_ +pmc8 : DEFINEFLAGS += -D_ENABLE_GLOBAL_GPS_ +pmc8 : DEFINEFLAGS += -D_ENABLE_GPS_GRAPHS_ +pmc8 : DEFINEFLAGS += -D_ENABLE_ALTITUDE_TRACKING_ +pmc8 : DEFINEFLAGS += -D_ENABLE_LAT_LON_TRACKING_ +pmc8 : DEFINEFLAGS += -D_ENABLE_NMEA_POSITION_ERROR_TRACKING_ +pmc8 : DEFINEFLAGS += -D_ENABLE_PDOP_TRACKING_ +pmc8 : DEFINEFLAGS += -D_ENABLE_SATELLITE_TRAILS_ +pmc8 : DEFINEFLAGS += -D_ENABLE_SATELLITE_ALMANAC_ +pmc8 : DEFINEFLAGS += -D_ENABLE_NMEA_SENTANCE_TRACKING_ +pmc8 : \ + $(DRIVER_OBJECTS) \ + $(GPS_OBJECTS) \ + $(TELESCOPE_DRIVER_OBJECTS) \ + $(HELPER_OBJECTS) \ + $(SERIAL_OBJECTS) \ + $(SOCKET_OBJECTS) \ + $(IMU_OBJECTS) \ + + $(LINK) \ + $(DRIVER_OBJECTS) \ + $(GPS_OBJECTS) \ + $(TELESCOPE_DRIVER_OBJECTS) \ + $(HELPER_OBJECTS) \ + $(SERIAL_OBJECTS) \ + $(SOCKET_OBJECTS) \ + $(OPENCV_LINK) \ + -lpthread \ + -o alpacapi-expsci ###################################################################################### #pragma mark make imutest @@ -1494,18 +1557,23 @@ phaseone : DEFINEFLAGS += -D_ENABLE_PHASEONE_ phaseone : INCLUDES += -I$(PHASEONE_INC) phaseone : \ $(CAMERA_DRIVER_OBJECTS) \ - $(HELPER_OBJECTS) \ - $(TEST_OBJECTS) \ + $(CPP_OBJECTS) \ $(DRIVER_OBJECTS) \ - $(SOCKET_OBJECTS) \ + $(HELPER_OBJECTS) \ $(IMU_OBJECTS) \ + $(SOCKET_OBJECTS) \ + $(LIVE_WINDOW_OBJECTS) \ + $(TEST_OBJECTS) \ + $(LINK) \ $(CAMERA_DRIVER_OBJECTS) \ + $(DRIVER_OBJECTS) \ $(HELPER_OBJECTS) \ - $(TEST_OBJECTS) \ + $(IMU_OBJECTS) \ $(SOCKET_OBJECTS) \ - $(DRIVER_OBJECTS) \ + $(LIVE_WINDOW_OBJECTS) \ + $(TEST_OBJECTS) \ $(OPENCV_LINK) \ -L$(PHASEONE_LIB) \ -lCameraSdkCpp \ @@ -2800,6 +2868,103 @@ atik : \ -lcfitsio \ -o atik +###################################################################################### +#pragma mark PlayerOne filterwheel +# make playerone +playerone : DEFINEFLAGS += -D_ENABLE_FILTERWHEEL_PLAYERONE_ +playerone : DEFINEFLAGS += -D_ENABLE_FILTERWHEEL_ +playerone : INCLUDES += -I./PlayerOne/PlayerOne_FilterWheel_SDK_Linux_V1.2.0/include +playerone : \ + $(DRIVER_OBJECTS) \ + $(FITLERWHEEL_DRIVER_OBJECTS) \ + $(CPP_OBJECTS) \ + $(HELPER_OBJECTS) \ + $(SOCKET_OBJECTS) \ + + $(LINK) \ + $(DRIVER_OBJECTS) \ + $(FITLERWHEEL_DRIVER_OBJECTS) \ + $(HELPER_OBJECTS) \ + $(SOCKET_OBJECTS) \ + -L$(PLAYERONE_LIB) \ + -lPlayerOnePW \ + -ludev \ + -lusb-1.0 \ + -lpthread \ + -o alpacapi + + + +###################################################################################### +#pragma mark PlayerOne with ZWO camera +# make poz +poz : DEFINEFLAGS += -D_ENABLE_CAMERA_ +poz : DEFINEFLAGS += -D_ENABLE_ASI_ +poz : DEFINEFLAGS += -D_ENABLE_CAMERA_PLAYERONE_ +poz : DEFINEFLAGS += -D_ENABLE_FITS_ +poz : DEFINEFLAGS += -D_ENABLE_FILTERWHEEL_PLAYERONE_ +poz : DEFINEFLAGS += -D_ENABLE_FILTERWHEEL_ +poz : INCLUDES += -I./PlayerOne/PlayerOne_FilterWheel_SDK_Linux_V1.2.0/include +poz : INCLUDES += -I./PlayerOne/PlayerOne_Camera_SDK_Linux_V3.3.0/include +poz : DEFINEFLAGS += -D_USE_OPENCV_ +poz : DEFINEFLAGS += -D_USE_OPENCV_CPP_ +poz : \ + $(DRIVER_OBJECTS) \ + $(CAMERA_DRIVER_OBJECTS) \ + $(FITLERWHEEL_DRIVER_OBJECTS) \ + $(CPP_OBJECTS) \ + $(HELPER_OBJECTS) \ + $(SOCKET_OBJECTS) \ + $(LIVE_WINDOW_OBJECTS) \ + + $(LINK) \ + $(DRIVER_OBJECTS) \ + $(CAMERA_DRIVER_OBJECTS) \ + $(FITLERWHEEL_DRIVER_OBJECTS) \ + $(HELPER_OBJECTS) \ + $(SOCKET_OBJECTS) \ + $(LIVE_WINDOW_OBJECTS) \ + $(OPENCV_LINK) \ + $(ASI_CAMERA_OBJECTS) \ + -L$(PLAYERONE_LIB) \ + -lPlayerOnePW \ + -lPlayerOneCamera \ + -ludev \ + -lusb-1.0 \ + -lpthread \ + -lcfitsio \ + -o alpacapi + + +###################################################################################### +#pragma mark ogma +# make ogma +ogma : DEFINEFLAGS += -D_ENABLE_CAMERA_ +ogma : DEFINEFLAGS += -D_ENABLE_OGMA_ +ogma : DEFINEFLAGS += -D_ENABLE_FITS_ +ogma : DEFINEFLAGS += -D_USE_OPENCV_ +ogma : DEFINEFLAGS += -D_USE_OPENCV_CPP_ +ogma : INCLUDES += -I$(OGMA_INCLUDE_DIR) +ogma : \ + $(DRIVER_OBJECTS) \ + $(CAMERA_DRIVER_OBJECTS) \ + $(CPP_OBJECTS) \ + $(HELPER_OBJECTS) \ + $(SOCKET_OBJECTS) \ + $(LIVE_WINDOW_OBJECTS) \ + + $(LINK) \ + $(DRIVER_OBJECTS) \ + $(CAMERA_DRIVER_OBJECTS) \ + $(HELPER_OBJECTS) \ + $(SOCKET_OBJECTS) \ + $(LIVE_WINDOW_OBJECTS) \ + $(OPENCV_LINK) \ + -L$(OGMA_LIB_DIR) \ + -logmacam \ + -lpthread \ + -lcfitsio \ + -o alpacapi ###################################################################################### #pragama mark make client client @@ -3253,7 +3418,6 @@ SPECTROGRAPH_OBJECTS= \ $(OBJECT_DIR)windowtab_spectro.o \ -SRC_SPECTROGRAPH=./src_spectrograph/ ###################################################################################### @@ -3398,6 +3562,7 @@ skycv4 : DEFINEFLAGS += -D_ENABLE_CTRL_OBS_CONDITIONS_ skycv4 : DEFINEFLAGS += -D_ENABLE_CTRL_ROTATOR_ skycv4 : DEFINEFLAGS += -D_ENABLE_CTRL_SPECTROGRAPH_ skycv4 : DEFINEFLAGS += -D_ENABLE_CTRL_SWITCHES_ +skycv4 : DEFINEFLAGS += -D_ENABLE_CTRL_SPECTROGRAPH_ skycv4 : DEFINEFLAGS += -D_ENABLE_CTRL_TELESCOPE_ skycv4 : DEFINEFLAGS += -D_ENABLE_FITS_ skycv4 : DEFINEFLAGS += -D_CONTROLLER_USES_ALPACA_ @@ -3411,11 +3576,13 @@ skycv4 : INCLUDES += -I$(SRC_SKYTRAVEL) skycv4 : \ $(CONTROLLER_OBJECTS) \ $(SKYTRAVEL_OBJECTS) \ + $(SPECTROGRAPH_OBJECTS) \ $(HELPER_OBJECTS) \ $(LINK) \ $(CONTROLLER_OBJECTS) \ $(SKYTRAVEL_OBJECTS) \ + $(SPECTROGRAPH_OBJECTS) \ $(HELPER_OBJECTS) \ $(OPENCV_LINK) \ -lpthread \ @@ -3451,7 +3618,6 @@ sss : DEFINEFLAGS += -D_USE_OPENCV_CPP_ #sss : DEFINEFLAGS += -D_ENABLE_ASTEROIDS_ sss : DEFINEFLAGS += -D_SQL_$(SQL_VERSION) sss : INCLUDES += -I$(SRC_SKYTRAVEL) -sss : INCLUDES += -I$(SRC_SPECTROGRAPH) sss : \ $(CONTROLLER_OBJECTS) \ $(SKYTRAVEL_OBJECTS) \ @@ -3482,7 +3648,6 @@ spectro : DEFINEFLAGS += -D_ENABLE_FILTERWHEEL_USIS_ spectro : DEFINEFLAGS += -D_ENABLE_FOCUSER_ spectro : DEFINEFLAGS += -D_ENABLE_FOCUSER_USIS_ spectro : DEFINEFLAGS += -D_INCLUDE_MILLIS_ -spectro : INCLUDES += -I$(SRC_SPECTROGRAPH) spectro : \ $(DRIVER_OBJECTS) \ $(FITLERWHEEL_DRIVER_OBJECTS) \ @@ -3509,45 +3674,38 @@ spectro : \ #------------------------------------------------------------------------------------- $(OBJECT_DIR)spectrodriver.o : $(SRC_SPECTROGRAPH)spectrodriver.cpp \ - $(SRC_SPECTROGRAPH)spectrodriver.h \ - Makefile + $(SRC_SPECTROGRAPH)spectrodriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_SPECTROGRAPH)spectrodriver.cpp -o$(OBJECT_DIR)spectrodriver.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)spectrodrvr_usis.o : $(SRC_SPECTROGRAPH)spectrodrvr_usis.cpp \ $(SRC_SPECTROGRAPH)spectrodrvr_usis.h \ - $(SRC_SPECTROGRAPH)spectrodriver.h \ - Makefile + $(SRC_SPECTROGRAPH)spectrodriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_SPECTROGRAPH)spectrodrvr_usis.cpp -o$(OBJECT_DIR)spectrodrvr_usis.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)controller_spectrograph.o : $(SRC_SPECTROGRAPH)controller_spectrograph.cpp \ - $(SRC_SPECTROGRAPH)controller_spectrograph.h \ - Makefile + $(SRC_SPECTROGRAPH)controller_spectrograph.h $(COMPILEPLUS) $(INCLUDES) $(SRC_SPECTROGRAPH)controller_spectrograph.cpp -o$(OBJECT_DIR)controller_spectrograph.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)filterwheeldriver_usis.o : $(SRC_SPECTROGRAPH)filterwheeldriver_usis.cpp \ - $(SRC_SPECTROGRAPH)filterwheeldriver_usis.h \ - Makefile + $(SRC_SPECTROGRAPH)filterwheeldriver_usis.h $(COMPILEPLUS) $(INCLUDES) $(SRC_SPECTROGRAPH)filterwheeldriver_usis.cpp -o$(OBJECT_DIR)filterwheeldriver_usis.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)focuserdriver_USIS.o : $(SRC_SPECTROGRAPH)focuserdriver_USIS.cpp \ - $(SRC_SPECTROGRAPH)focuserdriver_USIS.h \ - Makefile + $(SRC_SPECTROGRAPH)focuserdriver_USIS.h $(COMPILEPLUS) $(INCLUDES) $(SRC_SPECTROGRAPH)focuserdriver_USIS.cpp -o$(OBJECT_DIR)focuserdriver_USIS.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)windowtab_spectro.o : $(SRC_SPECTROGRAPH)windowtab_spectro.cpp \ - $(SRC_SPECTROGRAPH)windowtab_spectro.h \ - Makefile + $(SRC_SPECTROGRAPH)windowtab_spectro.h $(COMPILEPLUS) $(INCLUDES) $(SRC_SPECTROGRAPH)windowtab_spectro.cpp -o$(OBJECT_DIR)windowtab_spectro.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)usis_communications.o : $(SRC_SPECTROGRAPH)usis_communications.cpp \ - $(SRC_SPECTROGRAPH)usis_communications.h \ - Makefile + $(SRC_SPECTROGRAPH)usis_communications.h $(COMPILEPLUS) $(INCLUDES) $(SRC_SPECTROGRAPH)usis_communications.cpp -o$(OBJECT_DIR)usis_communications.o ###################################################################################### @@ -3654,15 +3812,13 @@ net : $(NETTEST_OBJECTS) #------------------------------------------------------------------------------------- $(OBJECT_DIR)controller_nettest.o : $(SRC_NETTEST)controller_nettest.cpp \ - $(SRC_NETTEST)controller_nettest.h \ - Makefile + $(SRC_NETTEST)controller_nettest.h $(COMPILEPLUS) $(INCLUDES) $(SRC_NETTEST)controller_nettest.cpp -o$(OBJECT_DIR)controller_nettest.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)windowtab_nettest.o : $(SRC_NETTEST)windowtab_nettest.cpp \ $(SRC_NETTEST)windowtab_nettest.h \ - $(SRC_DIR)windowtab.h \ - Makefile + $(SRC_DIR)windowtab.h $(COMPILEPLUS) $(INCLUDES) $(SRC_NETTEST)windowtab_nettest.cpp -o$(OBJECT_DIR)windowtab_nettest.o @@ -3778,8 +3934,7 @@ $(OBJECT_DIR)readconfigfile.o : $(SRC_DIR)readconfigfile.c $(SRC_DIR)readconfigf #------------------------------------------------------------------------------------- $(OBJECT_DIR)alpacadriver.o : $(SRC_DIR)alpacadriver.cpp \ $(SRC_DIR)alpacadriver.h \ - $(SRC_DIR)alpaca_defs.h \ - Makefile + $(SRC_DIR)alpaca_defs.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)alpacadriver.cpp -o$(OBJECT_DIR)alpacadriver.o @@ -3792,110 +3947,95 @@ $(OBJECT_DIR)alpacadriver_gps.o : $(SRC_DIR)alpacadriver_gps.cpp \ #------------------------------------------------------------------------------------- $(OBJECT_DIR)alpacadriverConnect.o : $(SRC_DIR)alpacadriverConnect.cpp \ - $(SRC_DIR)alpaca_defs.h \ - Makefile + $(SRC_DIR)alpaca_defs.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)alpacadriverConnect.cpp -o$(OBJECT_DIR)alpacadriverConnect.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)alpacadriverThread.o : $(SRC_DIR)alpacadriverThread.cpp \ $(SRC_DIR)alpacadriver.h \ - $(SRC_DIR)alpaca_defs.h \ - Makefile + $(SRC_DIR)alpaca_defs.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)alpacadriverThread.cpp -o$(OBJECT_DIR)alpacadriverThread.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)alpacadriverSetup.o : $(SRC_DIR)alpacadriverSetup.cpp \ $(SRC_DIR)alpacadriver.h \ - $(SRC_DIR)alpaca_defs.h \ - Makefile + $(SRC_DIR)alpaca_defs.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)alpacadriverSetup.cpp -o$(OBJECT_DIR)alpacadriverSetup.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)alpacadriver_helper.o : $(SRC_DIR)alpacadriver_helper.c \ - $(SRC_DIR)alpacadriver_helper.h \ - Makefile + $(SRC_DIR)alpacadriver_helper.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)alpacadriver_helper.c -o$(OBJECT_DIR)alpacadriver_helper.o #------------------------------------------------------------------------------------- -$(OBJECT_DIR)alpaca_discovery.o : $(SRC_DIR)alpaca_discovery.cpp \ - $(SRC_DIR)alpacadriver.h \ - Makefile +$(OBJECT_DIR)alpaca_discovery.o : $(SRC_DIR)alpaca_discovery.cpp \ + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)alpaca_discovery.cpp -o$(OBJECT_DIR)alpaca_discovery.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)alpacadriver_templog.o : $(SRC_DIR)alpacadriver_templog.cpp \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)alpacadriver_templog.cpp -o$(OBJECT_DIR)alpacadriver_templog.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)alpacadriverLogging.o : $(SRC_DIR)alpacadriverLogging.cpp \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)alpacadriverLogging.cpp -o$(OBJECT_DIR)alpacadriverLogging.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver.o : $(SRC_DIR)cameradriver.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver.cpp -o$(OBJECT_DIR)cameradriver.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_readthread.o :$(SRC_DIR)cameradriver_readthread.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_readthread.cpp -o$(OBJECT_DIR)cameradriver_readthread.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriverAnalysis.o : $(SRC_DIR)cameradriverAnalysis.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriverAnalysis.cpp -o$(OBJECT_DIR)cameradriverAnalysis.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_fits.o : $(SRC_DIR)cameradriver_fits.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_fits.cpp -I$(SRC_MOONRISE) -o$(OBJECT_DIR)cameradriver_fits.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_gps.o : $(SRC_DIR)cameradriver_gps.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_gps.cpp -o$(OBJECT_DIR)cameradriver_gps.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_ASI.o : $(SRC_DIR)cameradriver_ASI.cpp \ $(SRC_DIR)cameradriver_ASI.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_ASI.cpp -o$(OBJECT_DIR)cameradriver_ASI.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_ATIK.o : $(SRC_DIR)cameradriver_ATIK.cpp \ $(SRC_DIR)cameradriver_ATIK.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_ATIK.cpp -o$(OBJECT_DIR)cameradriver_ATIK.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_overlay.o : $(SRC_DIR)cameradriver_overlay.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_overlay.cpp -o$(OBJECT_DIR)cameradriver_overlay.o @@ -3903,16 +4043,36 @@ $(OBJECT_DIR)cameradriver_overlay.o : $(SRC_DIR)cameradriver_overlay.cpp \ $(OBJECT_DIR)filterwheeldriver_ATIK.o : $(SRC_DIR)filterwheeldriver_ATIK.cpp \ $(SRC_DIR)filterwheeldriver_ATIK.h \ $(SRC_DIR)filterwheeldriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)filterwheeldriver_ATIK.cpp -o$(OBJECT_DIR)filterwheeldriver_ATIK.o +#------------------------------------------------------------------------------------- +$(OBJECT_DIR)filterwheeldriver_Play1.o : $(SRC_DIR)filterwheeldriver_Play1.cpp \ + $(SRC_DIR)filterwheeldriver_Play1.h \ + $(SRC_DIR)filterwheeldriver.h \ + $(SRC_DIR)alpacadriver.h + $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)filterwheeldriver_Play1.cpp -o$(OBJECT_DIR)filterwheeldriver_Play1.o + +#------------------------------------------------------------------------------------- +$(OBJECT_DIR)cameradriver_PlayerOne.o : $(SRC_DIR)cameradriver_PlayerOne.cpp \ + $(SRC_DIR)cameradriver_PlayerOne.h \ + $(SRC_DIR)cameradriver.h \ + $(SRC_DIR)alpacadriver.h + $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_PlayerOne.cpp -o$(OBJECT_DIR)cameradriver_PlayerOne.o + + +#------------------------------------------------------------------------------------- +$(OBJECT_DIR)cameradriver_OGMA.o : $(SRC_DIR)cameradriver_OGMA.cpp \ + $(SRC_DIR)cameradriver_OGMA.h \ + $(SRC_DIR)cameradriver.h \ + $(SRC_DIR)alpacadriver.h + $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_OGMA.cpp -o$(OBJECT_DIR)cameradriver_OGMA.o + #------------------------------------------------------------------------------------- $(OBJECT_DIR)filterwheeldriver_QHY.o : $(SRC_DIR)filterwheeldriver_QHY.cpp \ $(SRC_DIR)filterwheeldriver_QHY.h \ $(SRC_DIR)filterwheeldriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)filterwheeldriver_QHY.cpp -o$(OBJECT_DIR)filterwheeldriver_QHY.o @@ -3920,16 +4080,14 @@ $(OBJECT_DIR)filterwheeldriver_QHY.o : $(SRC_DIR)filterwheeldriver_QHY.cpp \ $(OBJECT_DIR)filterwheeldriver_sim.o : $(SRC_DIR)filterwheeldriver_sim.cpp \ $(SRC_DIR)filterwheeldriver_sim.h \ $(SRC_DIR)filterwheeldriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)filterwheeldriver_sim.cpp -o$(OBJECT_DIR)filterwheeldriver_sim.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_QHY.o : $(SRC_DIR)cameradriver_QHY.cpp \ $(SRC_DIR)cameradriver_QHY.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_QHY.cpp -o$(OBJECT_DIR)cameradriver_QHY.o @@ -3938,11 +4096,22 @@ $(OBJECT_DIR)ParseNMEA.o : $(MLS_LIB_DIR)ParseNMEA.c \ $(MLS_LIB_DIR)ParseNMEA.h $(COMPILEPLUS) $(INCLUDES) $(MLS_LIB_DIR)ParseNMEA.c -o$(OBJECT_DIR)ParseNMEA.o + +#------------------------------------------------------------------------------------- +$(OBJECT_DIR)web_graphics_opencv.o : $(MLS_LIB_DIR)web_graphics_opencv.cpp \ + $(MLS_LIB_DIR)web_graphics_opencv.h + $(COMPILEPLUS) $(INCLUDES) $(MLS_LIB_DIR)web_graphics_opencv.cpp -o$(OBJECT_DIR)web_graphics_opencv.o + #------------------------------------------------------------------------------------- $(OBJECT_DIR)gps_data.o : $(SRC_DIR)gps_data.cpp \ $(SRC_DIR)gps_data.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)gps_data.cpp -o$(OBJECT_DIR)gps_data.o +#------------------------------------------------------------------------------------- +$(OBJECT_DIR)GPS_graph.o : $(MLS_LIB_DIR)GPS_graph.c \ + $(MLS_LIB_DIR)GPS_graph.h + $(COMPILEPLUS) $(INCLUDES) $(MLS_LIB_DIR)GPS_graph.c -o$(OBJECT_DIR)GPS_graph.o + #------------------------------------------------------------------------------------- $(OBJECT_DIR)NMEA_helper.o : $(MLS_LIB_DIR)NMEA_helper.c \ @@ -3954,8 +4123,7 @@ $(OBJECT_DIR)NMEA_helper.o : $(MLS_LIB_DIR)NMEA_helper.c \ $(OBJECT_DIR)cameradriver_QSI.o : $(SRC_DIR)cameradriver_QSI.cpp \ $(SRC_DIR)cameradriver_QSI.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_QSI.cpp -o$(OBJECT_DIR)cameradriver_QSI.o @@ -3963,8 +4131,7 @@ $(OBJECT_DIR)cameradriver_QSI.o : $(SRC_DIR)cameradriver_QSI.cpp \ $(OBJECT_DIR)cameradriver_FLIR.o : $(SRC_DIR)cameradriver_FLIR.cpp \ $(SRC_DIR)cameradriver_FLIR.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_FLIR.cpp -o$(OBJECT_DIR)cameradriver_FLIR.o @@ -3972,70 +4139,61 @@ $(OBJECT_DIR)cameradriver_FLIR.o : $(SRC_DIR)cameradriver_FLIR.cpp \ #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_livewindow.o :$(SRC_DIR)cameradriver_livewindow.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_livewindow.cpp -o$(OBJECT_DIR)cameradriver_livewindow.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_PhaseOne.o :$(SRC_DIR)cameradriver_PhaseOne.cpp \ $(SRC_DIR)cameradriver_PhaseOne.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_PhaseOne.cpp -o$(OBJECT_DIR)cameradriver_PhaseOne.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_save.o : $(SRC_DIR)cameradriver_save.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_save.cpp -o$(OBJECT_DIR)cameradriver_save.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_sim.o : $(SRC_DIR)cameradriver_sim.cpp \ $(SRC_DIR)cameradriver_sim.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_sim.cpp -o$(OBJECT_DIR)cameradriver_sim.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_opencv.o : $(SRC_DIR)cameradriver_opencv.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_opencv.cpp -o$(OBJECT_DIR)cameradriver_opencv.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_TOUP.o : $(SRC_DIR)cameradriver_TOUP.cpp \ $(SRC_DIR)cameradriver_TOUP.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_TOUP.cpp -o$(OBJECT_DIR)cameradriver_TOUP.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_jpeg.o : $(SRC_DIR)cameradriver_jpeg.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_jpeg.cpp -o$(OBJECT_DIR)cameradriver_jpeg.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_png.o : $(SRC_DIR)cameradriver_png.cpp \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_png.cpp -o$(OBJECT_DIR)cameradriver_png.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)cameradriver_SONY.o : $(SRC_DIR)cameradriver_SONY.cpp \ $(SRC_DIR)cameradriver_SONY.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)cameradriver_SONY.cpp -o$(OBJECT_DIR)cameradriver_SONY.o @@ -4044,39 +4202,34 @@ $(OBJECT_DIR)cameradriver_SONY.o : $(SRC_DIR)cameradriver_SONY.cpp \ $(OBJECT_DIR)multicam.o : $(SRC_DIR)multicam.cpp \ $(SRC_DIR)multicam.h \ $(SRC_DIR)cameradriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)multicam.cpp -o$(OBJECT_DIR)multicam.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)domedriver.o : $(SRC_DIR)domedriver.cpp \ $(SRC_DIR)domedriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)domedriver.cpp -o$(OBJECT_DIR)domedriver.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)domedriver_sim.o : $(SRC_DIR)domedriver_sim.cpp \ $(SRC_DIR)domedriver_sim.h \ $(SRC_DIR)domedriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)domedriver_sim.cpp -o$(OBJECT_DIR)domedriver_sim.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)domeshutter.o : $(SRC_DIR)domeshutter.cpp \ $(SRC_DIR)domedriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)domeshutter.cpp -o$(OBJECT_DIR)domeshutter.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)domedriver_rpi.o : $(SRC_DIR)domedriver_rpi.cpp \ $(SRC_DIR)domedriver.h \ $(SRC_DIR)domedriver_rpi.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)domedriver_rpi.cpp -o$(OBJECT_DIR)domedriver_rpi.o @@ -4084,92 +4237,82 @@ $(OBJECT_DIR)domedriver_rpi.o : $(SRC_DIR)domedriver_rpi.cpp \ $(OBJECT_DIR)domedriver_ror_rpi.o : $(SRC_DIR)domedriver_ror_rpi.cpp \ $(SRC_DIR)domedriver_ror_rpi.h \ $(SRC_DIR)domedriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)domedriver_ror_rpi.cpp -o$(OBJECT_DIR)domedriver_ror_rpi.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)shutterdriver.o : $(SRC_DIR)shutterdriver.cpp \ $(SRC_DIR)shutterdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)shutterdriver.cpp -o$(OBJECT_DIR)shutterdriver.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)shutterdriver_arduino.o : $(SRC_DIR)shutterdriver_arduino.cpp \ $(SRC_DIR)shutterdriver_arduino.h \ $(SRC_DIR)shutterdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)shutterdriver_arduino.cpp -o$(OBJECT_DIR)shutterdriver_arduino.o + #------------------------------------------------------------------------------------- $(OBJECT_DIR)filterwheeldriver.o : $(SRC_DIR)filterwheeldriver.cpp \ $(SRC_DIR)filterwheeldriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)filterwheeldriver.cpp -o$(OBJECT_DIR)filterwheeldriver.o + #------------------------------------------------------------------------------------- $(OBJECT_DIR)filterwheeldriver_ZWO.o : $(SRC_DIR)filterwheeldriver_ZWO.cpp \ $(SRC_DIR)filterwheeldriver_ZWO.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)filterwheeldriver_ZWO.cpp -o$(OBJECT_DIR)filterwheeldriver_ZWO.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)focuserdriver.o : $(SRC_DIR)focuserdriver.cpp \ $(SRC_DIR)focuserdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)focuserdriver.cpp -o$(OBJECT_DIR)focuserdriver.o + #------------------------------------------------------------------------------------- $(OBJECT_DIR)focuserdriver_nc.o : $(SRC_DIR)focuserdriver_nc.cpp \ $(SRC_DIR)focuserdriver_nc.h \ $(SRC_DIR)focuserdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)focuserdriver_nc.cpp -o$(OBJECT_DIR)focuserdriver_nc.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)focuserdriver_sim.o : $(SRC_DIR)focuserdriver_sim.cpp \ $(SRC_DIR)focuserdriver_sim.h \ $(SRC_DIR)focuserdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)focuserdriver_sim.cpp -o$(OBJECT_DIR)focuserdriver_sim.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)rotatordriver.o : $(SRC_DIR)rotatordriver.cpp \ $(SRC_DIR)rotatordriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)rotatordriver.cpp -o$(OBJECT_DIR)rotatordriver.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)rotatordriver_nc.o : $(SRC_DIR)rotatordriver_nc.cpp \ $(SRC_DIR)rotatordriver_nc.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)rotatordriver_nc.cpp -o$(OBJECT_DIR)rotatordriver_nc.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)rotatordriver_sim.o : $(SRC_DIR)rotatordriver_sim.cpp \ $(SRC_DIR)rotatordriver_sim.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)rotatordriver_sim.cpp -o$(OBJECT_DIR)rotatordriver_sim.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)slittracker.o : $(SRC_DIR)slittracker.cpp \ $(SRC_DIR)slittracker.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)slittracker.cpp -o$(OBJECT_DIR)slittracker.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)telescopedriver.o : $(SRC_DIR)telescopedriver.cpp \ $(SRC_DIR)telescopedriver.h \ $(SRC_DIR)domedriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)telescopedriver.cpp -o$(OBJECT_DIR)telescopedriver.o @@ -4177,16 +4320,21 @@ $(OBJECT_DIR)telescopedriver.o : $(SRC_DIR)telescopedriver.cpp \ $(OBJECT_DIR)telescopedriver_comm.o : $(SRC_DIR)telescopedriver_comm.cpp \ $(SRC_DIR)telescopedriver_comm.h \ $(SRC_DIR)telescopedriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)telescopedriver_comm.cpp -o$(OBJECT_DIR)telescopedriver_comm.o +#------------------------------------------------------------------------------------- +$(OBJECT_DIR)telescopedriver_ExpSci.o : $(SRC_DIR)telescopedriver_ExpSci.cpp \ + $(SRC_DIR)telescopedriver_ExpSci.h \ + $(SRC_DIR)telescopedriver.h \ + $(SRC_DIR)alpacadriver.h + $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)telescopedriver_ExpSci.cpp -o$(OBJECT_DIR)telescopedriver_ExpSci.o + #------------------------------------------------------------------------------------- $(OBJECT_DIR)telescopedriver_lx200.o : $(SRC_DIR)telescopedriver_lx200.cpp \ $(SRC_DIR)telescopedriver_lx200.h \ $(SRC_DIR)telescopedriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)telescopedriver_lx200.cpp -o$(OBJECT_DIR)telescopedriver_lx200.o @@ -4218,8 +4366,7 @@ $(OBJECT_DIR)telescopedriver_sim.o : $(SRC_DIR)telescopedriver_sim.cpp \ $(OBJECT_DIR)telescopedriver_skywatch.o : $(SRC_DIR)telescopedriver_skywatch.cpp \ $(SRC_DIR)telescopedriver_skywatch.h \ $(SRC_DIR)telescopedriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)telescopedriver_skywatch.cpp -o$(OBJECT_DIR)telescopedriver_skywatch.o @@ -4227,14 +4374,12 @@ $(OBJECT_DIR)telescopedriver_skywatch.o : $(SRC_DIR)telescopedriver_skywatch.cpp #------------------------------------------------------------------------------------- $(OBJECT_DIR)managementdriver.o : $(SRC_DIR)managementdriver.cpp \ $(SRC_DIR)managementdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)managementdriver.cpp -o$(OBJECT_DIR)managementdriver.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)switchdriver.o : $(SRC_DIR)switchdriver.cpp \ $(SRC_DIR)switchdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)switchdriver.cpp -o$(OBJECT_DIR)switchdriver.o #------------------------------------------------------------------------------------- @@ -4242,16 +4387,14 @@ $(OBJECT_DIR)switchdriver_rpi.o : $(SRC_DIR)switchdriver_rpi.cpp \ $(SRC_DIR)raspberrypi_relaylib.h \ $(SRC_DIR)switchdriver_rpi.h \ $(SRC_DIR)switchdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)switchdriver_rpi.cpp -o$(OBJECT_DIR)switchdriver_rpi.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)switchdriver_sim.o : $(SRC_DIR)switchdriver_sim.cpp \ $(SRC_DIR)switchdriver_sim.h \ $(SRC_DIR)switchdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)switchdriver_sim.cpp -o$(OBJECT_DIR)switchdriver_sim.o @@ -4259,16 +4402,14 @@ $(OBJECT_DIR)switchdriver_sim.o : $(SRC_DIR)switchdriver_sim.cpp \ $(OBJECT_DIR)obsconditionsdriver.o : $(SRC_DIR)obsconditionsdriver.cpp \ $(SRC_DIR)obsconditionsdriver.h \ $(SRC_DIR)alpacadriver.h \ - $(SRC_DIR)alpaca_defs.h \ - Makefile + $(SRC_DIR)alpaca_defs.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)obsconditionsdriver.cpp -o$(OBJECT_DIR)obsconditionsdriver.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)obsconditionsdriver_rpi.o : $(SRC_DIR)obsconditionsdriver_rpi.cpp \ $(SRC_DIR)obsconditionsdriver.h \ $(SRC_DIR)alpacadriver.h \ - $(SRC_DIR)alpaca_defs.h \ - Makefile + $(SRC_DIR)alpaca_defs.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)obsconditionsdriver_rpi.cpp -o$(OBJECT_DIR)obsconditionsdriver_rpi.o #------------------------------------------------------------------------------------- @@ -4276,15 +4417,13 @@ $(OBJECT_DIR)obsconditionsdriver_sim.o : $(SRC_DIR)obsconditionsdriver_sim.cpp $(SRC_DIR)obsconditionsdriver_sim.h \ $(SRC_DIR)obsconditionsdriver.h \ $(SRC_DIR)alpacadriver.h \ - $(SRC_DIR)alpaca_defs.h \ - Makefile + $(SRC_DIR)alpaca_defs.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)obsconditionsdriver_sim.cpp -o$(OBJECT_DIR)obsconditionsdriver_sim.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)calibrationdriver.o : $(SRC_DIR)calibrationdriver.cpp \ $(SRC_DIR)calibrationdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)calibrationdriver.cpp -o$(OBJECT_DIR)calibrationdriver.o @@ -4292,43 +4431,37 @@ $(OBJECT_DIR)calibrationdriver.o : $(SRC_DIR)calibrationdriver.cpp \ $(OBJECT_DIR)calibrationdriver_rpi.o : $(SRC_DIR)calibrationdriver_rpi.cpp \ $(SRC_DIR)calibrationdriver_rpi.h \ $(SRC_DIR)calibrationdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)calibrationdriver_rpi.cpp -o$(OBJECT_DIR)calibrationdriver_rpi.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)calibration_sim.o : $(SRC_DIR)calibration_sim.cpp \ $(SRC_DIR)calibration_sim.h \ $(SRC_DIR)calibrationdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)calibration_sim.cpp -o$(OBJECT_DIR)calibration_sim.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)calibration_Alnitak.o : $(SRC_DIR)calibration_Alnitak.cpp \ $(SRC_DIR)calibration_Alnitak.h \ $(SRC_DIR)calibrationdriver.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)calibration_Alnitak.cpp -o$(OBJECT_DIR)calibration_Alnitak.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)usbmanager.o : $(SRC_DIR)usbmanager.cpp \ - $(SRC_DIR)usbmanager.h \ - Makefile + $(SRC_DIR)usbmanager.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)usbmanager.cpp -o$(OBJECT_DIR)usbmanager.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)discoverythread.o : $(SRC_DIR)discoverythread.c \ $(SRC_DIR)discoverythread.h \ - $(SRC_DIR)alpacadriver.h \ - Makefile + $(SRC_DIR)alpacadriver.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)discoverythread.c -o$(OBJECT_DIR)discoverythread.o #------------------------------------------------------------------------------------- $(OBJECT_DIR)HostNames.o : $(SRC_DIR)HostNames.c \ - $(SRC_DIR)HostNames.h \ - Makefile + $(SRC_DIR)HostNames.h $(COMPILEPLUS) $(INCLUDES) $(SRC_DIR)HostNames.c -o$(OBJECT_DIR)HostNames.o diff --git a/alpacapi_EditHistory.txt b/alpacapi_EditHistory.txt index 0938865..218fce9 100755 --- a/alpacapi_EditHistory.txt +++ b/alpacapi_EditHistory.txt @@ -1,4 +1,4 @@ -History Comments found =3305 in 498 files +History Comments found =3378 in 513 files PDS_ReadNASAfiles.c:28 //* Jan 26, 1992 Reading of PDS files into Mac program from CD working PDS_ReadNASAfiles.c:29 //* Mar 14, 1992 Starting on more detailed interpretation of label (header) PDS_ReadNASAfiles.c:30 //* Mar 16, 1992 Changed number of displayed bytes from 836 to 800 @@ -19,37 +19,38 @@ PDS_ReadNASAfiles.c:47 //* Jul 11, 1992 Added code to close window routine to PDS_ReadNASAfiles.c:48 //* Sep 7, 1992 Started implemented"Open PDS Database" menu, auto dim working PDS_ReadNASAfiles.c:49 //* Nov 6, 1992 Minor bugs fixed in voyager browse stuff PDS_ReadNASAfiles.c:50 //* Apr 15, 1993 Received 47 CD-ROMs from NASA -ParseNMEA.c:10 //* Apr 19, 1996 Separated NMEA and APRS Parse Routines +ParseNMEA.c:10 //* Apr 14, 1996 Put the boxes for the Heads-Up-Display into a Dialog Box template +ParseNMEA.c:11 //* Apr 19, 1996 Separated NMEA and APRS Parse Routines eph.c:10 //* May 2, 1996 (Mark Sproul) Starting on SkyTravel for Frank and Clif StarData.c:7 //* May 2, 1996 (Mark Sproul) Starting on SkyTravel for Frank and Clif -ParseNMEA.c:11 //* Dec 11, 1996 Removed UpdateHUDdisplay to a different file -ParseNMEA.c:12 //* Dec 26, 1996 Dave VanHorn dvanhron@cedar.net -ParseNMEA.c:13 //* Dec 26, 1996 PNI Compass, same as Jameco -ParseNMEA.c:14 //* Dec 26, 1996 Talked them into RAW data output +ParseNMEA.c:12 //* Dec 11, 1996 Removed UpdateHUDdisplay to a different file +ParseNMEA.c:13 //* Dec 26, 1996 Dave VanHorn dvanhron@cedar.net +ParseNMEA.c:14 //* Dec 26, 1996 PNI Compass, same as Jameco +ParseNMEA.c:15 //* Dec 26, 1996 Talked them into RAW data output StarData.c:8 //* Nov 18, 1999 restarting efforts eph.c:11 //* Nov 20, 1999 Minor formatting cleanup to improve readability StarData.c:9 //* Nov 20, 1999 major re-writing and re-organization -ParseNMEA.c:15 //* Feb 6, 2001 ReturnNMEAAltitude - Modified to use ATOF instead of ATOL -ParseNMEA.c:16 //* Jan 12, 2002 Started adding Magellan Proprietary Sentences -ParseNMEA.c:1725 //* Jan 12, 2002 Started adding Magellan Proprietary Sentenses -ParseNMEA.c:17 //* May 20, 2002 Started working on adaptive beaconing and corner pegging -ParseNMEA.c:18 //* Sep 16, 2004 Added support for $GPNVP for special Korean GPS, requested by customer -ParseNMEA.c:19 //* Nov 17, 2004 Started separating out NMEA parsing into smaller more manageable routines -ParseNMEA.c:20 //* Apr 30, 2012 Started on GPS support. -ParseNMEA.c:21 //* Apr 30, 2012 GPS parsing code implemented +ParseNMEA.c:16 //* Feb 6, 2001 ReturnNMEAAltitude - Modified to use ATOF instead of ATOL +ParseNMEA.c:17 //* Jan 12, 2002 Started adding Magellan Proprietary Sentences +ParseNMEA.c:1825 //* Jan 12, 2002 Started adding Magellan Proprietary Sentenses +ParseNMEA.c:18 //* May 20, 2002 Started working on adaptive beaconing and corner pegging +ParseNMEA.c:19 //* Sep 16, 2004 Added support for $GPNVP for special Korean GPS, requested by customer +ParseNMEA.c:20 //* Nov 17, 2004 Started separating out NMEA parsing into smaller more manageable routines +ParseNMEA.c:21 //* Apr 30, 2012 Started on GPS support. +ParseNMEA.c:22 //* Apr 30, 2012 GPS parsing code implemented ParseNMEA.h:10 //* Apr 30, 2012 Structures created to hold gps data for parsing ConsoleDebug.h:8 //* Jul 12, 2012 Created ConsoleDebug.h -ParseNMEA.c:22 //* Sep 11, 2012 Added Get_Actual_LatLon_Strings() for GPS display formatting +ParseNMEA.c:23 //* Sep 11, 2012 Added Get_Actual_LatLon_Strings() for GPS display formatting ParseNMEA.h:11 //* Sep 11, 2012 Added validDate to NMEA structure -ParseNMEA.c:23 //* Nov 21, 2012 Added GetCurrentLatLon_Strings() for metadata saving +ParseNMEA.c:24 //* Nov 21, 2012 Added GetCurrentLatLon_Strings() for metadata saving ConsoleDebug.h:9 //* Nov 30, 2012 Added CONSOLE_ERROR macros, same as CONSOLE_DEBUG but always print -ParseNMEA.c:24 //* Dec 5, 2012 Check for max SNR value from satellite GSV string -ParseNMEA.c:25 //* Dec 5, 2012 Added GetMaxSatSignalStrength() -ParseNMEA.c:1398 //* Dec 5, 2012 Check for max snr value from satellite GSV string -ParseNMEA.c:26 //* Jan 2, 2013 Added LatLonType argument to ReturnNMEALatLon() +ParseNMEA.c:25 //* Dec 5, 2012 Check for max SNR value from satellite GSV string +ParseNMEA.c:26 //* Dec 5, 2012 Added GetMaxSatSignalStrength() +ParseNMEA.c:1489 //* Dec 5, 2012 Check for max snr value from satellite GSV string +ParseNMEA.c:27 //* Jan 2, 2013 Added LatLonType argument to ReturnNMEALatLon() ParseNMEA.h:12 //* Jan 2, 2013 Added LatLonType to TYPE_NMEAInfoStruct -ParseNMEA.c:27 //* Mar 12, 2013 Added support for separate test program, -ParseNMEA.c:28 //* Mar 12, 2013 Fixed lat/lon bug in ReturnNMEALatLon (bug was introduced 1/2/13) +ParseNMEA.c:28 //* Mar 12, 2013 Added support for separate test program, +ParseNMEA.c:29 //* Mar 12, 2013 Fixed lat/lon bug in ReturnNMEALatLon (bug was introduced 1/2/13) VectorMath.h:3 //* Mar 14, 2014 Added more matrix support VectorMath.c:5 //* Mar 28, 2014 Started on Vector Math VectorMath.c:6 //* Apr 4, 2014 Added VectorScale() and VectorAdd() @@ -61,43 +62,69 @@ VectorMath.c:10 //* Mar 15, 2015 Added Matrix_Cofactor() VectorMath.c:11 //* Mar 15, 2015 Added Matrix_Determinant() VectorMath.c:12 //* Mar 15, 2015 Added Matrix_Inverse() VectorMath.c:13 //* Mar 15, 2015 Added Matrix_Transpose() -ParseNMEA.c:29 //* Oct 3, 2016 Updating to be a general purpose GPS parser -ParseNMEA.c:1278 //* Oct 3, 2016 TODO: Compare this with MacAPRS code +ParseNMEA.c:30 //* Oct 3, 2016 Updating to be a general purpose GPS parser +ParseNMEA.c:1369 //* Oct 3, 2016 TODO: Compare this with MacAPRS code ParseNMEA.h:13 //* Oct 3, 2016 Added TYPE_timeHHMMSS ParseNMEA.h:14 //* Oct 3, 2016 Added _ENABLE_SATELLITE_ALMANAC_ to save on memory if not needed NMEA_helper.c:9 //* Oct 4, 2016 Created NMEA_helper.c to avoid duplication -ParseNMEA.c:30 //* Oct 4, 2016 Moved checksum routines to helper file -ParseNMEA.c:31 //* Oct 6, 2016 Updated ReturnNMEAAltitude() to check for valid altitude -ParseNMEA.c:32 //* Oct 6, 2016 Updated ReturnNMEASpeed() to check for valid speed +ParseNMEA.c:31 //* Oct 4, 2016 Moved checksum routines to helper file +ParseNMEA.c:32 //* Oct 6, 2016 Updated ReturnNMEAAltitude() to check for valid altitude +ParseNMEA.c:33 //* Oct 6, 2016 Updated ReturnNMEASpeed() to check for valid speed ParseNMEA.h:15 //* Oct 6, 2016 Added _ENABLE_WAYPOINT_PARSING_ to save on memory if not needed ParseNMEA.h:16 //* Oct 6, 2016 Added _ENABLE_PROPRIETARY_PARSING_ to save on memory if not needed -ParseNMEA.c:33 //* Oct 10, 2016 Added ParseNMEA_init() -ParseNMEA.c:34 //* Apr 17, 2017 Moved GPS code to separate library directory. I need this for many projects -ParseNMEA.c:35 //* Apr 18, 2017 Removing MacAPRS specific code -ParseNMEA.c:36 //* Apr 20, 2017 Changing sat SNR data from char strings to shorts (int) -ParseNMEA.c:37 //* Apr 20, 2017 Cleaned up $GPGSV paring code +ParseNMEA.c:34 //* Oct 10, 2016 Added ParseNMEA_init() +Statistics.c:6 //* Nov 9, 2016 Started on Statistics.c +Statistics.c:7 //* Nov 9, 2016 Added STAT_Rand_SD() +Statistics.c:8 //* Nov 9, 2016 Added STAT_GenerateData_SD() +Statistics.c:9 //* Nov 9, 2016 Added STAT_CalcMean() +Statistics.c:10 //* Nov 9, 2016 Added STAT_CalcVariance() +Statistics.c:11 //* Nov 9, 2016 Added STAT_CalcStdDeviation() +Statistics.c:12 //* Dec 9, 2016 Added STAT_GetMinimum() & STAT_GetMaximum() +Statistics.c:13 //* Jan 26, 2017 Added STAT_CalcSigmaForX() & STAT_CalcSigmaCurve() +ParseNMEA.c:35 //* Apr 17, 2017 Moved GPS code to separate library directory. I need this for many projects +ParseNMEA.c:36 //* Apr 18, 2017 Removing MacAPRS specific code +GPS_graph.c:8 //* Apr 20, 2017 Added almanac graphing +ParseNMEA.c:37 //* Apr 20, 2017 Changing sat SNR data from char strings to shorts (int) +ParseNMEA.c:38 //* Apr 20, 2017 Cleaned up $GPGSV paring code ParseNMEA.h:17 //* Apr 20, 2017 Changing sat snr data from char strings to shorts (int) ParseNMEA.h:18 //* Apr 20, 2017 Increased sat count from 32 to 96 +GPS_graph.c:9 //* Apr 21, 2017 Added DrawGPS_AlmanacGrid() +GPS_graph.c:10 //* Apr 21, 2017 Added CreateSNRdistrbutionPlot() ParseNMEA.h:19 //* Apr 21, 2017 Added _ENABLE_PDOP_TRACKING_ -ParseNMEA.c:38 //* Apr 23, 2017 Added $PRWIZCH, Rockwell channel data -ParseNMEA.c:39 //* Apr 24, 2017 Added checksum error count +ParseNMEA.c:39 //* Apr 23, 2017 Added $PRWIZCH, Rockwell channel data +GPS_graph.c:11 //* Apr 24, 2017 Added NMEA sentence list +ParseNMEA.c:40 //* Apr 24, 2017 Added checksum error count ParseNMEA.h:20 //* Apr 24, 2017 Added _ENABLE_NMEA_SENTANCE_TRACKING_ -ParseNMEA.c:40 //* Apr 25, 2017 Added _ENABLE_PDOP_TRACKING_ -ParseNMEA.c:41 //* May 3, 2017 Added _ENABLE_ALTITUDE_TRACKING_ -ParseNMEA.c:1726 //* May 3, 2017 Copying Magellan code from MacAPRS -ParseNMEA.c:42 //* May 4, 2017 Added parsing for ($PMGLF), no documentation on what it is -ParseNMEA.c:43 //* May 4, 2017 Added parsing for GPS sensor temp ($PGRMT) +GPS_graph.c:12 //* Apr 25, 2017 Added Legend to satellite position plot +ParseNMEA.c:41 //* Apr 25, 2017 Added _ENABLE_PDOP_TRACKING_ +GPS_graph.c:13 //* May 3, 2017 Added plotting of altitude over time +ParseNMEA.c:42 //* May 3, 2017 Added _ENABLE_ALTITUDE_TRACKING_ +ParseNMEA.c:1826 //* May 3, 2017 Copying Magellan code from MacAPRS +ParseNMEA.c:43 //* May 4, 2017 Added parsing for ($PMGLF), no documentation on what it is +ParseNMEA.c:44 //* May 4, 2017 Added parsing for GPS sensor temp ($PGRMT) +GPS_graph.c:14 //* May 9, 2017 Added sat numbers on almanac ParseNMEA.h:21 //* May 9, 2017 Added gPGRME_exists to indicate that a PGRME sentance had been received -ParseNMEA.c:44 //* May 10, 2017 Altitude values now in double as well as int -ParseNMEA.c:45 //* May 10, 2017 Added lat lon tracking as double values -ParseNMEA.c:46 //* May 10, 2017 Added _ENABLE_LAT_LON_TRACKING_ -ParseNMEA.c:47 //* May 11, 2017 Added ParseNMEA_TimeString() -ParseNMEA.c:48 //* May 12, 2017 Setting system time working on Linux -ParseNMEA.c:49 //* May 12, 2017 Added Check_And_Set_System_Time() -ParseNMEA.c:50 //* May 15, 2017 Added satellites in use tracking -ParseNMEA.c:51 //* May 15, 2017 Added Mode tracking (1=no fix,2=2D,3=3D) -ParseNMEA.c:52 //* May 15, 2017 Added Magnetic variation tracking -ParseNMEA.c:53 //* May 25, 2017 Added parsing of $PRWIZCH sat signal data +ParseNMEA.c:45 //* May 10, 2017 Altitude values now in double as well as int +ParseNMEA.c:46 //* May 10, 2017 Added lat lon tracking as double values +ParseNMEA.c:47 //* May 10, 2017 Added _ENABLE_LAT_LON_TRACKING_ +ParseNMEA.c:48 //* May 11, 2017 Added ParseNMEA_TimeString() +ParseNMEA.c:49 //* May 12, 2017 Setting system time working on Linux +ParseNMEA.c:50 //* May 12, 2017 Added Check_And_Set_System_Time() +GPS_graph.c:15 //* May 15, 2017 Added CreateSatsInUseHistoryPlot() +ParseNMEA.c:51 //* May 15, 2017 Added satellites in use tracking +ParseNMEA.c:52 //* May 15, 2017 Added Mode tracking (1=no fix,2=2D,3=3D) +ParseNMEA.c:53 //* May 15, 2017 Added Magnetic variation tracking +ParseNMEA.c:54 //* May 25, 2017 Added parsing of $PRWIZCH sat signal data +GPS_graph.c:16 //* Jun 8, 2017 Moved graphing routines to separate file +GPS_graph.c:17 //* Jun 9, 2017 Added vertical line at the current time in the history plots +ParseNMEA.c:55 //* Jun 9, 2017 Added gTimeAdjustmentCount +GPS_graph.c:18 //* Jun 12, 2017 Added CreateSatelliteTrailsGraph() +ParseNMEA.c:56 //* Jun 12, 2017 Added _ENABLE_SATELLITE_TRAILS_ +ParseNMEA.c:57 //* Jun 12, 2017 Added SaveSatelliteTrails() +GPS_graph.c:19 //* Jun 13, 2017 Added CreateSatelliteElevationGraph() +ParseNMEA.c:58 //* Jun 15, 2017 Added min/max altitude tracking +ParseNMEA.c:59 //* Jul 11, 2017 Added logic in Check_And_Set_System_Time() to prevent setting time in the past +ParseNMEA.c:60 //* Jul 12, 2017 Time must be off by 2 or more seconds before update occurs ConsoleDebug.h:10 //* Sep 6, 2018 Re-arranged ifdefs such that stdio is not included if debuging not enabled json_parse.c:15 //* Nov 8, 2018 Started on json_parse library json_parse.c:16 //* Nov 13, 2018 Added support for escape chars (i.e. \t) @@ -146,8 +173,8 @@ JsonResponse.c:18 //* Apr 15, 2019 Change to send directly to the alpacadriver.cpp:50 //* Apr 16, 2019 Breaking up AlpacaCallback() to reduce complexity alpacadriver.cpp:51 //* Apr 16, 2019 Added ProcessGetPutRequest() JsonResponse.c:19 //* Apr 16, 2019 Added JsonResponse_CreateHeader() -cameradriver.cpp:37 //* Apr 17, 2019 Added Camera_OutputHTML() -cameradriver_ASI.cpp:35 //* Apr 17, 2019 Added Camera_OutputHTML() +cameradriver.cpp:37 //* Apr 17, 2019 Added OutputHTML() +cameradriver_ASI.cpp:35 //* Apr 17, 2019 Added OutputHTML() cameradriver_ASI.cpp:36 //* Apr 17, 2019 Read temperature working on ASI1600 alpacadriver.cpp:52 //* Apr 18, 2019 Downloaded ZWO Filter Wheel library filterwheeldriver.cpp:25 //* Apr 18, 2019 Created filterwheeldriver.c @@ -2379,7 +2406,7 @@ cameradriver.cpp:179 //* Sep 29, 2022 Added gImageDataDir for specify cameradriver.cpp:180 //* Sep 29, 2022 Added SetImageDataDirectory() windowtab_iplist.cpp:26 //* Sep 29, 2022 Added dynamic display CPU temp when mouse is moved over graph windowtab_iplist.cpp:27 //* Sep 30, 2022 Added HandleMouseMovedInGraph() -cameradriver_ASI.cpp:83 //* Oct 1, 2022 Changed CreateASI_CameraObjects() to return camera count +cameradriver_ASI.cpp:83 //* Oct 1, 2022 Changed CreateCameraObjects_ASI() to return camera count windowtab_skytravel.cpp:112 //* Oct 2, 2022 Cleaned up button setting code in SetupWindowControls() windowtab_skytravel.cpp:113 //* Oct 2, 2022 Added which SQL database in use to main display controller_obsconditions.cpp:22 //* Oct 3, 2022 Fixed connection status for observing conditions window @@ -2638,7 +2665,7 @@ rotatordriver_sim.cpp:26 //* Mar 2, 2023 CONFORMU-rotatordriver_sim -> P switchdriver_sim.cpp:25 //* Mar 2, 2023 Created switchdriver_sim.cpp switchdriver_sim.h:11 //* Mar 2, 2023 Created switchdriver_sim.h alpacadriver.cpp:157 //* Mar 3, 2023 Added ProcessAlpacaCommand() -alpacadriver.cpp:3984 //* Mar 3, 2023 Make CONFORMU happy, check for valid device number +alpacadriver.cpp:4022 //* Mar 3, 2023 Make CONFORMU happy, check for valid device number alpacadriver_helper.c:13 //* Mar 3, 2023 Added FindDeviceTypeByStringLowerCase() calibration_sim.cpp:20 //* Mar 3, 2023 Created calibration_sim.cpp cameradriver_SONY.cpp:1295 //* Mar 3, 2023 this line caused a compile err @@ -3057,8 +3084,8 @@ cameradriver_gps.cpp:29 //* Sep 1, 2023 Added lots of GPS data to FITS cameradriver_gps.cpp:30 //* Sep 5, 2023 Working on matching SharpCap FITS header cameradriver_QHY.cpp:43 //* Sep 5, 2023 More work on qhy image header ConsoleDebug.h:18 //* Sep 5, 2023 Added CONSOLE_DEBUG_W_SIZE() to quite mode -ParseNMEA.c:54 //* Sep 5, 2023 Removing global gNMEAdata, replacing with pointer -ParseNMEA.c:1356 //* Sep 5, 2023 Added NumSats from GPGSV +ParseNMEA.c:61 //* Sep 5, 2023 Removing global gNMEAdata, replacing with pointer +ParseNMEA.c:1447 //* Sep 5, 2023 Added NumSats from GPGSV ParseNMEA.h:22 //* Sep 5, 2023 Added currSatsInUse & currSatMode alpacadriver.cpp:178 //* Sep 6, 2023 Added all the device version info to Get_Readall_Common() cameradriver_overlay.cpp:25 //* Sep 6, 2023 Created cameradriver_overlay.cpp @@ -3077,8 +3104,8 @@ cameradriver_ASI.cpp:86 //* Sep 9, 2023 Deleted _USE_THREADS_FOR_ASI_CA cameradriver_readthread.cpp:25 //* Sep 9, 2023 Created cameradriver_readthread.cpp controller_remoteview.cpp:20 //* Sep 9, 2023 Created controller_remoteview.cpp controller_remoteview.h:2 //* Sep 9, 2023 Created controller_remoteview.h -ParseNMEA.c:55 //* Sep 9, 2023 Added GetLatLonDouble() -ParseNMEA.c:56 //* Sep 9, 2023 Added ParseNMEA_FormatLatLonStrings() +ParseNMEA.c:62 //* Sep 9, 2023 Added GetLatLonDouble() +ParseNMEA.c:63 //* Sep 9, 2023 Added ParseNMEA_FormatLatLonStrings() cameradriver_fits.cpp:95 //* Sep 10, 2023 Added FLIP mode to FITS camera info cameradriver_jpeg.cpp:32 //* Sep 10, 2023 Test lib jpeg routines again, working fine imu_lib.c:9 //* Sep 11, 2023 Added IMU_Print_Calibration() @@ -3190,7 +3217,7 @@ windowtab_sw_versions.cpp:21 //* Feb 10, 2024 Created windowtab_sw_version telescopedriver.cpp:70 //* Feb 11, 2024 Added IMU-Roll, IMU-Pitch, & IMU-Yaw to telescope readall telescope_AlpacaCmds.cpp:11 //* Feb 11, 2024 Added Roll, Pitch & Yaw to telescope extras command table windowtab_telescope.cpp:31 //* Feb 11, 2024 Added Roll, Pitch & Yaw to telescope control window -imu_lib.c:14 //* Feb 25, 2024 S Added IMU_GetIMUtypeString() +imu_lib.c:14 //* Feb 25, 2024 Added IMU_GetIMUtypeString() controller_skyimage.cpp:9 //* Mar 9, 2024 Created controller_skyimage.cpp controller_skyimage.h:2 //* Mar 9, 2024 Created controller_skyimage.h controller_skytravel.cpp:23 //* Mar 9, 2024 Fixed bug where Software Version screen was not getting updated @@ -3279,12 +3306,12 @@ alpacadriver.cpp:185 //* Apr 10, 2024 Started on global GPS support cameradriver_fits.cpp:104 //* Apr 10, 2024 FITS data now supports GPS from serial port cameradriver_gps.cpp:31 //* Apr 10, 2024 Added WriteFITS_GPSinfo() cameradriver_gps.cpp:32 //* Apr 10, 2024 Added WriteFITS_Global_GPSinfo() -ParseNMEA.c:57 //* Apr 10, 2024 Added ComputeLatLonAverage() +ParseNMEA.c:64 //* Apr 10, 2024 Added ComputeLatLonAverage() ParseNMEA.h:24 //* Apr 10, 2024 Added _ENABLE_GPS_AVERAGE_ ConsoleDebug.h:19 //* Apr 12, 2024 Added CONSOLE_DEBUG_W_INT64() helper_functions.c:21 //* Apr 12, 2024 Added FormatTimeStringISO8601_tm() -ParseNMEA.c:58 //* Apr 12, 2024 Added timing tests to ComputeLatLonAverage() -ParseNMEA.c:59 //* Apr 13, 2024 Added altitude to averaging logic +ParseNMEA.c:65 //* Apr 12, 2024 Added timing tests to ComputeLatLonAverage() +ParseNMEA.c:66 //* Apr 13, 2024 Added altitude to averaging logic discovery_lib.c:28 //* Apr 14, 2024 Added DumpAlpacaUnit() windowtab_image.cpp:39 //* Apr 14, 2024 Added RUN button to step through images windowtab_iplist.cpp:32 //* Apr 14, 2024 Added +/- to enable/disable graph display of selected device @@ -3292,8 +3319,54 @@ alpacadriver_gps.cpp:27 //* Apr 15, 2024 Created alpacadriver_gps.cpp alpacadriver_gps.cpp:28 //* Apr 15, 2024 Added SendHtml_GPS() alpaca_defs.h:96 //* Apr 15, 2024 Build 176 windowtab_sw_versions.cpp:23 //* Apr 15, 2024 Fixed buffer overflow bug in UpdateOnScreenWidgetList() -cameradriver.cpp:211 //* Jan 1, 2119 ---------------------------------------- -cameradriver.cpp:212 //* Jun 26, 2119 Add support for sub frames +cameradriver_ser.cpp:11 //* Apr 16, 2024 Created cameradriver_ser.cpp +ParseNMEA.c:67 //* Apr 16, 2024 Added GetGPSmodeString() +cameradriver_fits.cpp:105 //* Apr 18, 2024 Added filter wheel serial number to fits output if it exists +cameradriver_PlayerOne.cpp:28 //* Apr 18, 2024 Discussed Alpaca migration with Vanessa Zhang +filterwheeldriver_Play1.cpp:27 //* Apr 18, 2024 Borrowed Player-One filter wheel from Vanessa Zhang +filterwheeldriver_Play1.cpp:28 //* Apr 18, 2024 Created filterwheeldriver_Play1.cpp +filterwheeldriver_Play1.cpp:29 //* Apr 18, 2024 PlayerOne filterwheel working +cameradriver.cpp:210 //* Apr 19, 2024 Added check for flip enabled to Put_Flip() +cameradriver.h:31 //* Apr 19, 2024 Added kImageType_MONO8 +cameradriver_PlayerOne.cpp:29 //* Apr 19, 2024 Created cameradriver_PlayerOne.cpp +cameradriver_PlayerOne.h:11 //* Apr 19, 2024 Created cameradriver_PlayerOne.h +telescopedriver_ExpSci.cpp:33 //* Apr 20, 2024 Ordered Exlpore Scientific iEXOS-100-2 PMC-Eight Equatorial Tracker System +cameradriver_OGMA.cpp:30 //* Apr 21, 2024 Discussed Alpaca protocol with Juan Martinez at OGMA +cameradriver_OGMA.cpp:31 //* Apr 21, 2024 Juan told me that OGMA is almost identical to ToupTek, nearly identical SDK +cameradriver_OGMA.cpp:32 //* Apr 21, 2024 OGMA cameras gave me one of their low-end cameras https://getogma.com/ +cameradriver_PlayerOne.cpp:30 //* Apr 21, 2024 Purchased Player One Neptune-C II Camera (4 mega-pixels) +telescopedriver_ExpSci.cpp:34 //* Apr 21, 2024 Created telescopedriver_ExpSci.cpp +telescopedriver_ExpSci.h:18 //* Apr 21, 2024 Created telescopedriver_ExpSci.h +alpacadriver.cpp:186 //* Apr 22, 2024 Started working on multi-language support +cameradriverAnalysis.cpp:47 //* Apr 22, 2024 Added support for kImageType_MONO8 (8 bit image type) +cameradriver_fits.cpp:106 //* Apr 22, 2024 Added support for kImageType_MONO8 (8 bit image type) +cameradriver_OGMA.cpp:33 //* Apr 22, 2024 Downloaded SDK from https://github.com/OGMAvision/OGMAcamSDK +cameradriver_PlayerOne.cpp:31 //* Apr 22, 2024 PlayerOne camera reading images properly +cameradriver_PlayerOne.cpp:32 //* Apr 22, 2024 Finished Read/Write Gain +cameradriver_PlayerOne.cpp:33 //* Apr 22, 2024 Image flip working +cameradriver_PlayerOne.cpp:34 //* Apr 22, 2024 Finished Read/Write Offset +cameradriver_readthread.cpp:27 //* Apr 22, 2024 Added RunThread_CheckPictureStatus() +Makefile:67 #++ Apr 22, 2024 Added _INCLUDE_MULTI_LANGUAGE_SUPPORT_ +cameradriver_OGMA.cpp:34 //* Apr 23, 2024 Created cameradriver_OGMA.cpp +telescopedriver_ExpSci.cpp:35 //* Apr 23, 2024 Started on Explore Scientific setup web page +cameradriver_OGMA.h:11 //* Apr 24, 2024 Created cameradriver_OGMA.cpp +telescopedriver.cpp:71 //* Apr 24, 2024 Working on GPS input for telescope site location +telescopedriver.cpp:72 //* Apr 24, 2024 Added GPS_TelescopeThread() +telescopedriver.cpp:73 //* Apr 24, 2024 Added Set_SiteLatitude(), Set_SiteLongitude(), Set_SiteAltitude() +alpacadriver.cpp:187 //* Apr 25, 2024 Successfully got JavaScript to send HTTP PUT command +alpacadriver.cpp:188 //* Apr 25, 2024 Added ProcessOptionsCommand() +telescopedriver.cpp:74 //* Apr 25, 2024 Added averaging to Lat/Lon updates from GPS +gps_data.cpp:12 //* Apr 26, 2024 Started working on gps graph support +web_graphics_opencv.cpp:12 //* Apr 26, 2024 Created web_graphics_opencv.cpp +web_graphics_opencv.cpp:13 //* Apr 26, 2024 Started on opencv version of web_graphics librar +web_graphics_opencv.h:9 //* Apr 26, 2024 Created web_graphics_opencv.h +gps_data.cpp:13 //* Apr 27, 2024 GPS graph working from alpacapi driver +GPS_graph.c:20 //* Apr 27, 2024 Added _ENABLE_HTML_OUTPUT_ +alpacadriver.cpp:189 //* Apr 28, 2024 Fixed ProcessGetPutRequest() to properly handle image requests +telescopedriver.cpp:75 //* APr 28, 2024 Added DumpTelescopeDriverStruct() +alpaca_defs.h:97 //* Apr 29, 2024 Build 177 +cameradriver.cpp:212 //* Jan 1, 2119 ---------------------------------------- +cameradriver.cpp:213 //* Jun 26, 2119 Add support for sub frames cameradriver_png.cpp:33 //* Jan 31, 2120 Add support for libpng cameradriver_TOUP.cpp:48 //* Feb 4, 2120 Add 16 bit readout to Toupcam cameradriver_TOUP.cpp:49 //* Feb 16, 2120 Add gain setting to Toupcam @@ -3304,19 +3377,19 @@ controller_camera.cpp:79 //* Feb 6, 2121 Move downloading of images to cameradriver_QHY.cpp:52 //* Oct 10, 2122 Add support for percentcompleted to QHY camera driver spectrodriver.cpp:33 //* May 7, 2123 Add support for SlitID, SlitAngle, SlitWidth controller_dome.cpp:47 //* Jun 25, 2123 Add slaved to DeviceState -History Comments found = 3305 in 498 files -Total lines = 230219 -Total comment Lines = 37698 (16.4%) -Total comments = 42286 (18.4%) -Total history comments = 3305 (1.4%) -Total C files = 67 -Total C++ files = 186 -Total H files = 243 -Preprocssor cnt = 7276 -Total SLOC = 145995 -Total SLOC-Logical = 112548 +History Comments found = 3378 in 513 files +Total lines = 239476 +Total comment Lines = 39002 (16.3%) +Total comments = 43750 (18.3%) +Total history comments = 3378 (1.4%) +Total C files = 69 +Total C++ files = 192 +Total H files = 250 +Preprocssor cnt = 7681 +Total SLOC = 152125 +Total SLOC-Logical = 117254 Programmer comment summary -MLS = 2901 +MLS = 2974 TODO = 11 DDB = 1 JMH = 3 @@ -3324,5 +3397,5 @@ PDB = 6 ADD = 8 SCV = 1 RNS = 332 -KAS = 13 -ML = 1 +KAS = 14 +CRN = 1 diff --git a/docs/index.html b/docs/index.html index 509191a..f5659bf 100644 --- a/docs/index.html +++ b/docs/index.html @@ -29,6 +29,8 @@

AlpacaPi

AAVSO + + @@ -64,3 +66,23 @@

AlpacaPi

AlpacaPi is written in C/C++ and runs on Linux, it is open source. https://github.com/msproul/AlpacaPi + + + + + +

+ + + + + diff --git a/src/JsonResponse.c b/src/JsonResponse.c index e91c525..4227c6f 100755 --- a/src/JsonResponse.c +++ b/src/JsonResponse.c @@ -121,6 +121,8 @@ char lineBuff[64]; } strcat(jsonHdrBUffer, "Content-type: application/json; charset=utf-8\r\n"); strcat(jsonHdrBUffer, "Server: AlpacaPi\r\n"); + strcat(jsonHdrBUffer, "Access-Control-Allow-Origin: *\r\n"); + // strcat(jsonHdrBUffer, "Accept: text/html,application/json\r\n"); // strcat(jsonHdrBUffer, "Accept-Language:en-US,en;q=0.8\r\n"); diff --git a/src/alpaca_defs.h b/src/alpaca_defs.h index 311f677..0e086d3 100755 --- a/src/alpaca_defs.h +++ b/src/alpaca_defs.h @@ -94,6 +94,7 @@ //* Feb 10, 2024 Pushed Build 174 //* Mar 22, 2024 Build 175 //* Apr 15, 2024 Build 176 +//* Apr 29, 2024 Build 177 //***************************************************************************** //#include "alpaca_defs.h" @@ -113,7 +114,7 @@ #define kApplicationName "AlpacaPi" #define kVersionString "V0.7.2" -#define kBuildNumber 176 +#define kBuildNumber 177 #define kAlpacaDiscoveryPORT 32227 #define kAlpacaPiDefaultPORT 6800 @@ -582,6 +583,7 @@ typedef struct // TYPE_TelescopeProperties double IMU_Yaw; } TYPE_TelescopeProperties; +void DumpTelescopeDriverStruct(TYPE_TelescopeProperties *telescopeDriver); //***************************************************************************** //* Dome properties as described by ASCOM diff --git a/src/alpacadriver.cpp b/src/alpacadriver.cpp index c42edec..cf7827c 100644 --- a/src/alpacadriver.cpp +++ b/src/alpacadriver.cpp @@ -183,6 +183,10 @@ //* Nov 1, 2023 /management/v1/description?ClientID=1&ClientTransactionID=2 //* Nov 26, 2023 Removed links form HTML cmd table for cmds starting with "-" //* Apr 10, 2024 Started on global GPS support +//* Apr 22, 2024 Started working on multi-language support +//* Apr 25, 2024 Successfully got JavaScript to send HTTP PUT command +//* Apr 25, 2024 Added ProcessOptionsCommand() +//* Apr 28, 2024 Fixed ProcessGetPutRequest() to properly handle image requests //***************************************************************************** //* to install code blocks 20 //* Step 1: sudo add-apt-repository ppa:codeblocks-devs/release @@ -224,6 +228,7 @@ #include "helper_functions.h" #include "JsonResponse.h" #include "alpacadriver.h" +#include "alpacadriver_gps.h" #include "alpacadriver_helper.h" #include "eventlogging.h" #include "socket_listen.h" @@ -290,7 +295,6 @@ #ifdef _ENABLE_GLOBAL_GPS_ #include "gps_data.h" - #include "alpacadriver_gps.h" #endif #if defined(__arm__) && defined(_ENABLE_WIRING_PI_) @@ -327,7 +331,7 @@ bool gImageDownloadInProgress = false; char gHostName[48] = ""; char gUserAgentAlpacaPiStr[80] = ""; int gUserAgentCounters[kHTTPclient_last]; - +int gHTTP_OptionsRequestCnt = 0; #ifdef _ENABLE_BANDWIDTH_LOGGING_ int gTimeUnitsSinceTopOfHour = 0; @@ -1938,7 +1942,8 @@ const char gBadResponse400[] = "Connection: close\r\n" "\r\n" "\r\n" - "\r\n" + "\r\n" + "\r\n" "Invalid URL\r\n" "\r\n" "

Invalid URL

\r\n" @@ -1956,9 +1961,11 @@ const char gHtmlHeader[] = "User-Agent: AlpacaPi\r\n" "Content-Type: text/html\r\n" "Connection: close\r\n" + "Access-Control-Allow-Origin: *\r\n" "\r\n" "\r\n" - "\r\n" + "\r\n" + "\r\n" @@ -2014,6 +2021,12 @@ int returnCode; SocketWriteData(mySocketFD, "
    \r\n"); SocketWriteData(mySocketFD, "
  • AlpacaPi Settings for this server\r\n"); +#ifdef _ENABLE_GLOBAL_GPS_ + if (gEnableGlobalGPS) + { + SocketWriteData(mySocketFD, "
  • GPS Statistics for GPS connected to this server\r\n"); + } +#endif // _ENABLE_GLOBAL_GPS_ SocketWriteData(mySocketFD, "

    \r\n"); //* check to see if the docs folder and index file are present @@ -2083,6 +2096,30 @@ static const char gWatchDogHelpMsg[] = }; +//***************************************************************************** +static const char gLanguageSelection[] = +{ +// "" +// "" + + "

    \n" + "\n" + + "\n" +}; //***************************************************************************** static void SendHtml_MainPage(TYPE_GetPutRequestData *reqData) @@ -2108,6 +2145,9 @@ int iii; SocketWriteData(mySocketFD, lineBuffer); SocketWriteData(mySocketFD, "\r\n"); +#ifdef _INCLUDE_MULTI_LANGUAGE_SUPPORT_ + SocketWriteData(mySocketFD, gLanguageSelection); +#endif // _INCLUDE_MULTI_LANGUAGE_SUPPORT_ OutPutObservatoryInfoHTML(mySocketFD); @@ -2841,7 +2881,7 @@ int totalBytesWritten; bool keepGoing; char dataBuffer[1600]; - CONSOLE_DEBUG_W_STR("Sending file:", fileName); +// CONSOLE_DEBUG_W_STR("Sending file:", fileName); totalBytesWritten = 0; filePointer = fopen(fileName, "r"); if (filePointer != NULL) @@ -2906,30 +2946,26 @@ int returnCode; if (strcasestr(jpegFileName, ".png") != NULL) { - CONSOLE_DEBUG("Sending PNG file!!!!!!!!!!!!!!"); +// CONSOLE_DEBUG("Sending PNG file!!!!!!!!!!!!!!"); SocketWriteData(socket, gHTML_HeaderPNG); } else { - CONSOLE_DEBUG("Sending JPEG file!!!!!!!!!!!!!!"); +// CONSOLE_DEBUG("Sending JPEG file!!!!!!!!!!!!!!"); SocketWriteData(socket, gHTML_HeaderJpeg); } if (jpegFileName != NULL) { - CONSOLE_DEBUG_W_STR("jpegFileName\t=", jpegFileName); - //* check to see if the file is present - returnCode = stat(jpegFileName, &fileStatus); - CONSOLE_DEBUG_W_HEX("fileStatus.st_mode\t=", fileStatus.st_mode); - if (returnCode == 0) +// CONSOLE_DEBUG_W_STR("jpegFileName\t=", jpegFileName); + myFilenamePtr = (char *)jpegFileName; + if (*myFilenamePtr == '/') { - myFilenamePtr = (char *)jpegFileName; - if (*myFilenamePtr == '/') - { - myFilenamePtr++; - } - StrcpyUntilChar(myJpegFileName, jpegFileName, 0x20, sizeof(myJpegFileName)); + myFilenamePtr++; } - else + StrcpyUntilChar(myJpegFileName, myFilenamePtr, 0x20, sizeof(myJpegFileName)); + //* check to see if the file is present + returnCode = stat(myJpegFileName, &fileStatus); + if (returnCode != 0) { //* ok, the file is not there, lets look in docs StrcpyUntilChar(altJpegFileName, jpegFileName, 0x20, sizeof(altJpegFileName)); @@ -2945,9 +2981,9 @@ int returnCode; } } - CONSOLE_DEBUG_W_STR("myJpegFileName=", myJpegFileName); - +// CONSOLE_DEBUG_W_STR("myJpegFileName=", myJpegFileName); + //* make sure there is nothing past the extension myFilenamePtr = strstr(myJpegFileName, ".jpg"); if (myFilenamePtr != NULL) { @@ -2963,7 +2999,7 @@ int returnCode; { strcpy(myJpegFileName, "image.jpg"); } - CONSOLE_DEBUG_W_STR("myJpegFileName=", myJpegFileName); +// CONSOLE_DEBUG_W_STR("myJpegFileName=", myJpegFileName); totalBytesWritten = SendFileToSocket(socket, myJpegFileName); if (totalBytesWritten <= 0) { @@ -3744,17 +3780,17 @@ char *delimPtr; } } -// CONSOLE_DEBUG_W_NUM("slashCounter\t=", slashCounter); + //CONSOLE_DEBUG_W_NUM("slashCounter\t=", slashCounter); //--------------------------------------------------- if (slashCounter >= 3) { -// CONSOLE_DEBUG_W_STR("myAlpacaVersionString\t=", myAlpacaVersionString); + //CONSOLE_DEBUG_W_STR("myAlpacaVersionString\t=", myAlpacaVersionString); if (myAlpacaVersionString[0] == 'v') { reqData->alpacaVersion = myAlpacaVersionString[1] & 0x0f; } -// CONSOLE_DEBUG_W_NUM("reqData->alpacaVersion\t=", reqData->alpacaVersion); + //CONSOLE_DEBUG_W_NUM("reqData->alpacaVersion\t=", reqData->alpacaVersion); strcpy(reqData->deviceType, myDeviceString); } @@ -3814,8 +3850,7 @@ char *delimPtr; { strcpy(reqData->deviceType, "unknown"); reqData->deviceCommand[0] = 0; - CONSOLE_DEBUG_W_STR("Unknown device type:", reqData->cmdBuffer); -// CONSOLE_ABORT(__FUNCTION__); +// CONSOLE_DEBUG_W_STR("Unknown device type:", reqData->cmdBuffer); } //* figure out the base type of the request (see enum list above) @@ -3974,7 +4009,10 @@ int iii; parseChrPtr++; } -// DumpRequestStructure(__FUNCTION__, &reqData); +// if (requestType != kRequestType_API) +// { +// DumpRequestStructure(__FUNCTION__, &reqData); +// } alpacaErrCode = kASCOM_Err_Success; switch(requestType) @@ -4053,35 +4091,36 @@ int iii; //------------------------------------------------------------------- if (strncasecmp(parseChrPtr, "/favicon.ico", 12) == 0) { - CONSOLE_DEBUG("favicon.ico"); +// CONSOLE_DEBUG("favicon.ico"); SendJpegResponse(socket, "favicon.ico"); } //------------------------------------------------------------------- else if (strncasecmp(parseChrPtr, "/image.jpg", 10) == 0) { - CONSOLE_DEBUG("image.jpg"); +// CONSOLE_DEBUG("image.jpg"); SendJpegResponse(socket, NULL); } //------------------------------------------------------------------- else if (strstr(parseChrPtr, ".jpg") != NULL) { - CONSOLE_DEBUG(".....jpg"); +// CONSOLE_DEBUG(".....jpg"); SendJpegResponse(socket, parseChrPtr); } //------------------------------------------------------------------- else if (strstr(parseChrPtr, ".png") != NULL) { +// CONSOLE_DEBUG(".....png"); SendJpegResponse(socket, parseChrPtr); } else { - CONSOLE_DEBUG_W_STR("Incomplete alpaca command\t=", htmlData); +// CONSOLE_DEBUG_W_STR("Unknown http request\t=", htmlData); + CONSOLE_DEBUG_W_STR("parseChrPtr\t=", parseChrPtr); DumpRequestStructure(__FUNCTION__, &reqData); SocketWriteData(socket, gBadResponse400); } break; } - return(alpacaErrCode); } @@ -4114,6 +4153,30 @@ int bytesWritten; CONSOLE_DEBUG_W_NUM("bytesWritten\t=", bytesWritten); } +//***************************************************************************** +static void ProcessOptionsCommand(const int socket) +{ +char optionsResponse[2048]; +int bytesWritten; + + CONSOLE_DEBUG(__FUNCTION__); + gHTTP_OptionsRequestCnt++; + + strcpy(optionsResponse, "HTTP/1.0 200 OK\r\n"); + strcat(optionsResponse, "Content-Type: text/plain\r\n"); + strcat(optionsResponse, "Allow: OPTIONS, GET, PUT, HEAD, POST\r\n"); + strcat(optionsResponse, "Access-Control-Allow-Origin: *\r\n"); + strcat(optionsResponse, "Access-Control-Allow-Headers: *\r\n"); + strcat(optionsResponse, "Access-Control-Allow-Methods: GET, PUT, POST\r\n"); + strcat(optionsResponse, "Connection: close\r\n"); + +// CONSOLE_DEBUG_W_STR("Sending data:\r\n", optionsResponse); + + bytesWritten = SocketWriteData(socket, optionsResponse); +// CONSOLE_DEBUG_W_NUM("bytesWritten\t=", bytesWritten); +} + + //***************************************************************************** //* this function is called from the socket handler with the received data @@ -4151,15 +4214,17 @@ CONSOLE_DEBUG_W_STR("\r\n", htmlData); } else if (strncmp(htmlData, "POST", 4) == 0) { - CONSOLE_DEBUG("POST command not supported (yet)"); - CONSOLE_DEBUG_W_STR("htmlData\t=", htmlData); - CONSOLE_DEBUG_W_LONG("byteCount\t=", byteCount); ProcessPostCommand(socket); gServerTransactionID++; //* we are the "server" } + else if (strncmp(htmlData, "OPTIONS", 7) == 0) + { + ProcessOptionsCommand(socket); + gServerTransactionID++; //* we are the "server" + } else if (byteCount > 0) { - CONSOLE_DEBUG_W_STR("Invalid HTML get/put command\t=", htmlData); + CONSOLE_DEBUG_W_STR("Invalid HTML get/put command\t=\r\n", htmlData); CONSOLE_DEBUG_W_LONG("byteCount\t=", byteCount); } @@ -4201,6 +4266,8 @@ static void PrintHelp(const char *appName) printf("\t%-20s\t%s\r\n", "-g9", "Sets baud rate to 9600 (default)"); printf("\t%-20s\t%s\r\n", "-g4", "Sets baud rate to 4800"); printf("\t%-20s\t%s\r\n", "-g4/dev/ttyUSB0", "Sets baud rate to 4800 and port to /dev/ttyUSB0"); +#else + printf("\t%-20s\t%s\r\n", "-g...", "GPS support not enabled in this build"); #endif printf("\t%-20s\t%s\r\n", "-h", "This help message"); printf("\t%-20s\t%s\r\n", "-l", "Live mode"); @@ -4713,7 +4780,7 @@ struct tm *linuxTime; kASCOM_Err_Success, gFullVersionString); - DEBUG_TIMING(__FUNCTION__); + DEBUG_TIMING("Timing step 1"); gObservatorySettingsOK = ObservatorySettings_ReadFile(); #ifdef _ENABLE_IMU_ @@ -4737,15 +4804,15 @@ int imu_ReturnCode; } #endif - DEBUG_TIMING(__FUNCTION__); + DEBUG_TIMING("Timing step 2:"); //-------------------------------------------------------- //* create the various driver objects CreateDriverObjects(); - DEBUG_TIMING(__FUNCTION__); + DEBUG_TIMING("Timing step 3:"); //********************************************************* StartDiscoveryListenThread(gAlpacaListenPort); - DEBUG_TIMING(__FUNCTION__); + DEBUG_TIMING("Timing step 4:"); #ifdef _JETSON_ StartExtraListenThread(4520); #endif @@ -4768,7 +4835,7 @@ int imu_ReturnCode; CONSOLE_DEBUG_W_NUM("threadErr=", threadErr); } - DEBUG_TIMING(__FUNCTION__); + DEBUG_TIMING("Timing step 5:"); #ifdef _ENABLE_GLOBAL_GPS_ if (gEnableGlobalGPS) @@ -5331,7 +5398,7 @@ int mySocketFD; SocketWriteData(mySocketFD, gHtmlHeader); SocketWriteData(mySocketFD, "\r\n"); - SocketWriteData(mySocketFD, "\r\n"); + SocketWriteData(mySocketFD, "\r\n"); SocketWriteData(mySocketFD, "Form Testing\r\n"); SocketWriteData(mySocketFD, "
    \r\n"); SocketWriteData(mySocketFD, "

    Form Testing

    \r\n"); diff --git a/src/alpacadriver.h b/src/alpacadriver.h index 89f5ac7..78aa9de 100644 --- a/src/alpacadriver.h +++ b/src/alpacadriver.h @@ -258,7 +258,7 @@ class AlpacaDriver char cAlpacaName[32]; char cDeviceModel[kDeviceModelStrLen]; char cDeviceManufacturer[64]; - char cDeviceManufAbrev[8]; + char cDeviceManufAbrev[16]; char cDeviceSerialNum[kDeviceSerialNumStrLen]; char cDeviceVersion[kDeviceVersionStrLen]; char cDeviceFirmwareVersStr[64]; diff --git a/src/alpacadriverSetup.cpp b/src/alpacadriverSetup.cpp index f2486be..ac306c2 100644 --- a/src/alpacadriverSetup.cpp +++ b/src/alpacadriverSetup.cpp @@ -68,7 +68,7 @@ char lineBuff[256]; SocketWriteData(mySocketFD, gHtmlHeader); SocketWriteData(mySocketFD, "\r\n"); - SocketWriteData(mySocketFD, "\r\n"); + SocketWriteData(mySocketFD, "\r\n"); SocketWriteData(mySocketFD, "Form Testing\r\n"); SocketWriteData(mySocketFD, "
    \r\n"); SocketWriteData(mySocketFD, "

    Form Testing

    \r\n"); @@ -146,7 +146,7 @@ int mySocketFD; SocketWriteData(mySocketFD, gHtmlHeader); SocketWriteData(mySocketFD, "\r\n"); - SocketWriteData(mySocketFD, "\r\n"); + SocketWriteData(mySocketFD, "\r\n"); SocketWriteData(mySocketFD, "
    \r\n"); SocketWriteData(mySocketFD, "

    Saved succesfully

    \r\n"); SocketWriteData(mySocketFD, "
    \r\n"); diff --git a/src/alpacadriver_gps.cpp b/src/alpacadriver_gps.cpp new file mode 100644 index 0000000..e025bbe --- /dev/null +++ b/src/alpacadriver_gps.cpp @@ -0,0 +1,390 @@ +//************************************************************************** +//* Name: alpacadriver_gps.cpp +//* +//* Author: Mark Sproul (C) 2019-2023 +//* msproul@skychariot.com +//* +//* Description: C++ Driver for Alpaca protocol +//* +//***************************************************************************** +//* AlpacaPi is an open source project written in C/C++ +//* +//* Use of this source code for private or individual use is granted +//* Use of this source code, in whole or in part for commercial purpose requires +//* written agreement in advance. +//* +//* You may use or modify this source code in any way you find useful, provided +//* that you agree that the author(s) have no warranty, obligations or liability. You +//* must determine the suitability of this source code for your use. +//* +//* Re-distribution of this source code must retain this copyright notice. +//***************************************************************************** +//***************************************************************************** +//* Edit History +//***************************************************************************** +//* = Mark L Sproul msproul@skychariot.com +//***************************************************************************** +//* Apr 15, 2024 Created alpacadriver_gps.cpp +//* Apr 15, 2024 Added SendHtml_GPS() +//***************************************************************************** + +#include + + +#define _ENABLE_CONSOLE_DEBUG_ +#include "ConsoleDebug.h" + + +#ifndef _REQUESTDATA_H_ + #include "RequestData.h" +#endif + + +#include "alpacadriver.h" +#include "alpacadriver_gps.h" +#include "alpacadriver_helper.h" +#include "helper_functions.h" + +#include "gps_data.h" +#include "ParseNMEA.h" +#include "GPS_graph.h" + + +bool gEnableGlobalGPS = true; +char gGlobalGPSbaudrate = '9'; +char gGlobalGPSpath[64] = "/dev/ttyS0"; + +//***************************************************************************** +static void PrintHTMLtableEntry(int mySocketFD, const char *string1, const char *string2) +{ +char lineBuffer[256]; + + SocketWriteData(mySocketFD, "\r\n"); + sprintf(lineBuffer, "%s%s", string1, string2); + SocketWriteData(mySocketFD, lineBuffer); + SocketWriteData(mySocketFD, "\r\n"); +} + +//***************************************************************************** +static void PrintHTMLtableEntryINT(int mySocketFD, const char *string1, const int value) +{ +char string2[256]; + + sprintf(string2, "%d", value); + PrintHTMLtableEntry(mySocketFD, string1, string2); +} + +//***************************************************************************** +static void PrintHTMLtableEntryDBL(int mySocketFD, const char *string1, const double value) +{ +char string2[256]; + + sprintf(string2, "%f", value); + PrintHTMLtableEntry(mySocketFD, string1, string2); +} + +//***************************************************************************** +static void PrintHTMLgraphTableEntry( int mySocketFD, + const char *titleString, + const char *directoryString, + const char *fileNameString) +{ +char lineBuffer[256]; + +// CONSOLE_DEBUG(__FUNCTION__); +// CONSOLE_DEBUG_W_STR("titleString \t=", titleString); +// CONSOLE_DEBUG_W_STR("fileNameString \t=", fileNameString); +// CONSOLE_DEBUG_W_STR("directoryString\t=", directoryString); + + + sprintf(lineBuffer, "%s\r\n", titleString); + SocketWriteData(mySocketFD, lineBuffer); + SocketWriteData(mySocketFD, "\r\n"); + sprintf(lineBuffer, "\r\n", directoryString, fileNameString); + SocketWriteData(mySocketFD, lineBuffer); + SocketWriteData(mySocketFD, "\r\n"); +} + +//************************************************************************************** +void PrintHTMLtableCell(int mySocketFD, const char *cellText) +{ +char lineBuffer[256]; + + sprintf(lineBuffer, "\t\t%s\r\n\n", cellText); + SocketWriteData(mySocketFD, lineBuffer); +} + +//************************************************************************************** +//* from HTMLoutput.h +enum +{ + kFormat_6_0 = 0, + kFormat_6_1, + kFormat_6_2, + kFormat_6_3, + kFormat_6_4, +}; +//************************************************************************************** +enum +{ + kUnits_none = 0, + kUnits_degrees, + kUnits_feet +}; + +//***************************************************************************** +void PrintHTMLtableCellDouble(int mySocketFD, double argValue, int numFormat, int units) +{ +char lineBuffer[256]; + + switch(units) + { + case kUnits_none: + sprintf(lineBuffer, "\t\t
    %6.4f\r\n", argValue); + break; + case kUnits_degrees: + sprintf(lineBuffer, "\t\t
    %6.4f°\r\n", argValue); + break; + case kUnits_feet: + sprintf(lineBuffer, "\t\t
    %6.4f(ft)\r\n", argValue); + break; + + } + SocketWriteData(mySocketFD, lineBuffer); +} + +#ifdef _ENABLE_GLOBAL_GPS_ + +//***************************************************************************** +static void PrintLatLonStatsTable(int mySocketFD) +{ +double delataMiles; +double delataFeet; + +// CONSOLE_DEBUG(__FUNCTION__); + +// SocketWriteData(mySocketFD, lineBuffer); + SocketWriteData(mySocketFD, "
    \n"); + SocketWriteData(mySocketFD, "
    \n"); + SocketWriteData(mySocketFD, "\n"); + SocketWriteData(mySocketFD, " \n"); + PrintHTMLtableCell(mySocketFD, ""); + PrintHTMLtableCell(mySocketFD, "
    Avg"); + PrintHTMLtableCell(mySocketFD, "
    Std Dev"); + PrintHTMLtableCell(mySocketFD, "
    σ Miles"); + PrintHTMLtableCell(mySocketFD, "
    σ Feet"); + SocketWriteData(mySocketFD, "
    \n"); + + + delataMiles = (gNMEAdata.latitude_std / 360.0) * 24901.0; + delataFeet = delataMiles * 5280; + + SocketWriteData(mySocketFD, " \n"); + PrintHTMLtableCell(mySocketFD, "Latitude"); + PrintHTMLtableCellDouble(mySocketFD, gNMEAdata.latitude_avg, kFormat_6_4, kUnits_degrees); + PrintHTMLtableCellDouble(mySocketFD, gNMEAdata.latitude_std, kFormat_6_4, kUnits_degrees); + PrintHTMLtableCellDouble(mySocketFD, delataMiles, kFormat_6_4, kUnits_none); + PrintHTMLtableCellDouble(mySocketFD, delataFeet, kFormat_6_4, kUnits_feet); + SocketWriteData(mySocketFD, " \n"); + + delataMiles = (gNMEAdata.longitude_std / 360.0) * 24901.0; + delataFeet = delataMiles * 5280; + + SocketWriteData(mySocketFD, " \n"); + PrintHTMLtableCell(mySocketFD, "Longitude"); + PrintHTMLtableCellDouble(mySocketFD, gNMEAdata.longitude_avg, kFormat_6_4, kUnits_degrees); + PrintHTMLtableCellDouble(mySocketFD,gNMEAdata. longitude_std, kFormat_6_4, kUnits_degrees); + PrintHTMLtableCellDouble(mySocketFD, delataMiles, kFormat_6_4, kUnits_none); + PrintHTMLtableCellDouble(mySocketFD, delataFeet, kFormat_6_4, kUnits_feet); + SocketWriteData(mySocketFD, " \n"); + + + SocketWriteData(mySocketFD, "
    \n"); + SocketWriteData(mySocketFD, "
    \n"); + SocketWriteData(mySocketFD, "

    \n"); +} +#endif // _ENABLE_GLOBAL_GPS_ + +//***************************************************************************** +void SendHtml_GPS(TYPE_GetPutRequestData *reqData) +{ +char lineBuffer[512]; +char latString[256]; +char lonString[256]; +int mySocketFD; +char gpsWebTitle[] = "GPS Information"; +int returnCode; +struct stat fileStatus; + +#ifdef _ENABLE_GPS_GRAPHS_ + CreateGPSgraphics(); +#endif // _ENABLE_GPS_GRAPHS_ + + +// CONSOLE_DEBUG(__FUNCTION__); + if (reqData != NULL) + { + mySocketFD = reqData->socket; +// CONSOLE_DEBUG_W_NUM("mySocketFD\t=", mySocketFD); + SocketWriteData(mySocketFD, gHtmlHeader); +// SocketWriteData(mySocketFD, gHtmlNightMode); + sprintf(lineBuffer, "%s\r\n", gpsWebTitle); + SocketWriteData(mySocketFD, lineBuffer); + SocketWriteData(mySocketFD, "\r\n

    \r\n"); + SocketWriteData(mySocketFD, "

    Alpaca device driver Web server

    \r\n"); + sprintf(lineBuffer, "

    %s

    \r\n", gpsWebTitle); + SocketWriteData(mySocketFD, lineBuffer); + SocketWriteData(mySocketFD, "
    \r\n"); + + //==================================================== +#ifdef _ENABLE_GLOBAL_GPS_ + if (gEnableGlobalGPS) + { + SocketWriteData(mySocketFD, "
    \r\n"); + SocketWriteData(mySocketFD, "\r\n"); + + PrintHTMLtableEntry(mySocketFD, "Device", gGlobalGPSpath); + + sprintf(lineBuffer, "%d", (gGlobalGPSbaudrate == '4') ? 4800 : 9600); + PrintHTMLtableEntry(mySocketFD, "Baud rate", lineBuffer); + + SocketWriteData(mySocketFD, "
    \r\n"); + SocketWriteData(mySocketFD, "
    \r\n"); + + if (gNMEAdata.SequenceNumber > 0) + { + SocketWriteData(mySocketFD, "
    \r\n"); + SocketWriteData(mySocketFD, "\r\n"); + + //---------------------------------------------------------------------------- + GetGPSmodeString(gNMEAdata.currSatMode1, gNMEAdata.currSatMode2, lineBuffer); + PrintHTMLtableEntry(mySocketFD, "Mode", lineBuffer); + + //---------------------------------------------------------------------------- + #define ISLOCKED(myBoolvalue) (char *)(myBoolvalue ? "Locked" : "invalid") + + PrintHTMLtableEntry(mySocketFD, "GPS Status", ISLOCKED(gNMEAdata.validData)); + PrintHTMLtableEntry(mySocketFD, "Date Status", ISLOCKED(gNMEAdata.validDate)); + PrintHTMLtableEntry(mySocketFD, "Time Status", ISLOCKED(gNMEAdata.validTime)); + PrintHTMLtableEntry(mySocketFD, "Lat/Lon Status", ISLOCKED(gNMEAdata.validLatLon)); + PrintHTMLtableEntry(mySocketFD, "Altitude Status", ISLOCKED(gNMEAdata.validAlt)); + + + //-------------------------------------------------------------- + //* Sequence number + PrintHTMLtableEntryINT(mySocketFD, "Sequence number", gNMEAdata.SequenceNumber); + PrintHTMLtableEntryINT(mySocketFD, "Satellites in view", gNMEAdata.numSats); + PrintHTMLtableEntryDBL(mySocketFD, "Latitude", gNMEAdata.lat_double); + PrintHTMLtableEntryDBL(mySocketFD, "Longitude", gNMEAdata.lon_double); + + ParseNMEA_FormatLatLonStrings( gNMEAdata.lat_average, + latString, + gNMEAdata.lon_average, + lonString); + PrintHTMLtableEntry(mySocketFD, "Latitude", latString); + PrintHTMLtableEntry(mySocketFD, "Longitude", lonString); + + FormatTimeStringISO8601_tm(&gNMEAdata.linuxTime, lineBuffer); + PrintHTMLtableEntry(mySocketFD, "Date/Time", lineBuffer); + + + SocketWriteData(mySocketFD, "
    \r\n"); + SocketWriteData(mySocketFD, "
    \r\n"); + + } + else + { + SocketWriteData(mySocketFD, "
    \r\n"); + SocketWriteData(mySocketFD, "

    No data has been received from the GPS

    \r\n"); + SocketWriteData(mySocketFD, "
    \r\n"); + } + //-------------------------------------------------------- + //* output links to images + + + returnCode = stat(kGPSimageDirectory, &fileStatus); //* fstat - check for existence of file + if (returnCode == 0) + { + SocketWriteData(mySocketFD, "
    \r\n"); + SocketWriteData(mySocketFD, "\r\n"); + //-------------------------------------------------------- + #ifdef _ENABLE_SATELLITE_TRAILS_ + PrintHTMLgraphTableEntry( mySocketFD, + "Satellite Tracking", + kGPSimageDirectory, + "satelliteTrails.jpg"); + PrintHTMLgraphTableEntry( mySocketFD, + "Satellite Elevation", + kGPSimageDirectory, + elevationGraphFileName); + #endif // _ENABLE_SATELLITE_TRAILS_ + + #ifdef _ENABLE_LAT_LON_TRACKING_ + PrintHTMLgraphTableEntry( mySocketFD, + "Lat Lon Tracking", + kGPSimageDirectory, + "latlonGraph.jpg"); + SocketWriteData(mySocketFD, "\r\n"); + #endif // _ENABLE_LAT_LON_TRACKING_ + + #ifdef _ENABLE_ALTITUDE_TRACKING_ + PrintHTMLgraphTableEntry( mySocketFD, + "Altitude Tracking", + kGPSimageDirectory, + altGraphFileName); + #endif // _ENABLE_ALTITUDE_TRACKING_ + + #ifdef _ENABLE_PDOP_TRACKING_ + PrintHTMLgraphTableEntry( mySocketFD, + "PDOP Tracking", + kGPSimageDirectory, + pdopGraphFileName); + #endif // _ENABLE_PDOP_TRACKING_ + + #ifdef _ENABLE_NMEA_POSITION_ERROR_TRACKING_ + if (gNMEAdata.gPGRME_exists) + { + PrintHTMLgraphTableEntry( mySocketFD, + "Position Error Tracking", + kGPSimageDirectory, + posErrGraphFileName); + } + #endif // _ENABLE_NMEA_POSITION_ERROR_TRACKING_ + + #ifdef _ENABLE_SATELLITE_ALMANAC_ + PrintHTMLgraphTableEntry( mySocketFD, + "Satellite SNR distribution", + kGPSimageDirectory, + snrGraphFileName); + + PrintHTMLgraphTableEntry( mySocketFD, + "Satellites in Use", + kGPSimageDirectory, + satsInUseGraphFileName); + #endif // _ENABLE_SATELLITE_ALMANAC_ + + SocketWriteData(mySocketFD, "
    \r\n"); + PrintLatLonStatsTable(mySocketFD); + SocketWriteData(mySocketFD, "
    \r\n"); + SocketWriteData(mySocketFD, "
    \r\n"); + } + } + else + { + SocketWriteData(mySocketFD, "
    \r\n"); + SocketWriteData(mySocketFD, "

    GPS input is not enabled

    \r\n"); + SocketWriteData(mySocketFD, "
    \r\n"); + } +#else + SocketWriteData(mySocketFD, "
    \r\n"); + SocketWriteData(mySocketFD, "

    Global GPS support is not enabled on this server

    \r\n"); + SocketWriteData(mySocketFD, "
    \r\n"); +#endif + SocketWriteData(mySocketFD, "\r\n"); + } + else + { + // CONSOLE_DEBUG("reqData is NULL"); + } +} + diff --git a/src/alpacadriver_gps.h b/src/alpacadriver_gps.h new file mode 100644 index 0000000..c59a7dc --- /dev/null +++ b/src/alpacadriver_gps.h @@ -0,0 +1,20 @@ +//***************************************************************************** +//#include "alpacadriver_gps.h" + + + +#ifndef _ALPACADRIVER_GPS_H_ +#define _ALPACADRIVER_GPS_H_ + +#ifndef _REQUESTDATA_H_ + #include "RequestData.h" +#endif + +void SendHtml_GPS(TYPE_GetPutRequestData *reqData); + + +extern bool gEnableGlobalGPS; +extern char gGlobalGPSbaudrate; +extern char gGlobalGPSpath[]; + +#endif // _ALPACADRIVER_GPS_H_ diff --git a/src/calibration_Alnitak.cpp b/src/calibration_Alnitak.cpp index 32f4b19..8a435d5 100644 --- a/src/calibration_Alnitak.cpp +++ b/src/calibration_Alnitak.cpp @@ -167,7 +167,7 @@ CalibrationDriverAlnitak::CalibrationDriverAlnitak(const char *argUSBpath) cTurnOff = false; cCalibrationIsOn = false; cForceUpdate = false; - cLastUpdate_ms = 0; + cLastThreadUpdate_ms = 0; cLastUpdate_milliSecs = 0; StartDriverThread(); @@ -238,14 +238,14 @@ uint32_t deltaTime_ms; cTurnOn = false; } currentTime_ms = millis(); - deltaTime_ms = currentTime_ms - cLastUpdate_ms; + deltaTime_ms = currentTime_ms - cLastThreadUpdate_ms; if ((deltaTime_ms > 2000) || cForceUpdate) { -// CONSOLE_DEBUG("Updating.........."); + CONSOLE_DEBUG_W_BOOL("Updating.......... cForceUpdate\t=", cForceUpdate); Alnitak_Cover_GetStatus(alpacaErrMsg); Alnitak_GetBrightness(alpacaErrMsg); - cLastUpdate_ms = millis(); - cForceUpdate = false; + cLastThreadUpdate_ms = millis(); + cForceUpdate = false; } //* if we are moving, delay for a short time if (cCoverCalibrationProp.CoverState == kCover_Moving) diff --git a/src/calibration_Alnitak.h b/src/calibration_Alnitak.h index f4b3ec0..1fb7cb7 100644 --- a/src/calibration_Alnitak.h +++ b/src/calibration_Alnitak.h @@ -53,7 +53,7 @@ class CalibrationDriverAlnitak: public CalibrationDriver bool cTurnOn; bool cTurnOff; int cNewBrightnessValue; - uint32_t cLastUpdate_ms; + uint32_t cLastThreadUpdate_ms; bool cForceUpdate; //* these are the routines that actually talk to the hardware diff --git a/src/cameradriver.cpp b/src/cameradriver.cpp index 81ebeff..93b1119 100755 --- a/src/cameradriver.cpp +++ b/src/cameradriver.cpp @@ -34,7 +34,7 @@ //***************************************************************************** //* Apr 14, 2019 Created cameradriver.cpp //* Apr 15, 2019 Added command table for camera -//* Apr 17, 2019 Added Camera_OutputHTML() +//* Apr 17, 2019 Added OutputHTML() //* Aug 26, 2019 Started on C++ version of alpaca camera driver //* Sep 3, 2019 Added initialization to class constructor //* Sep 26, 2019 Working on organizing camera C++ class @@ -207,6 +207,7 @@ //* Sep 1, 2023 16 bit binary transfer working AlpacaPi client //* Sep 9, 2023 Added _USE_CAMERA_READ_THREAD_ //* Mar 25, 2024 Read NASA Moon Phase on creation of camera objects +//* Apr 19, 2024 Added check for flip enabled to Put_Flip() //***************************************************************************** //* Jan 1, 2119 ---------------------------------------- //* Jun 26, 2119 Add support for sub frames @@ -284,10 +285,18 @@ #include "cameradriver_FLIR.h" #endif +#ifdef _ENABLE_OGMA_ + #include "cameradriver_OGMA.h" +#endif + #ifdef _ENABLE_PHASEONE_ #include "cameradriver_PhaseOne.h" #endif +#ifdef _ENABLE_CAMERA_PLAYERONE_ + #include "cameradriver_PlayerOne.h" +#endif + #ifdef _ENABLE_QHY_ #include "cameradriver_QHY.h" #endif @@ -330,20 +339,24 @@ int cameraCnt; //----------------------------------------------------------- //* ATIK needs to be before ASI for multiple camera starts #ifdef _ENABLE_ATIK_ - cameraCnt += CreateATIK_CameraObjects(); + cameraCnt += CreateCameraObjects_ATIK(); #endif //----------------------------------------------------------- #ifdef _ENABLE_ASI_ - cameraCnt += CreateASI_CameraObjects(); + cameraCnt += CreateCameraObjects_ASI(); #endif //----------------------------------------------------------- //#ifdef _ENABLE_FLIR_) && (__GNUC__ > 5) #ifdef _ENABLE_FLIR_ - cameraCnt += CreateFLIR_CameraObjects(); + cameraCnt += CreateCameraObjects_FLIR(); #endif //----------------------------------------------------------- #ifdef _ENABLE_PHASEONE_ - cameraCnt += CreatePhaseOne_CameraObjects(); + cameraCnt += CreateCameraObjects_PhaseOne(); +#endif +//----------------------------------------------------------- +#ifdef _ENABLE_CAMERA_PLAYERONE_ + cameraCnt += CreateCameraObjects_PlayerOne(); #endif //----------------------------------------------------------- #ifdef _ENABLE_QHY_ @@ -351,17 +364,21 @@ int cameraCnt; #endif //----------------------------------------------------------- #ifdef _ENABLE_QSI_ - cameraCnt += CreateQSI_CameraObjects(); + cameraCnt += CreateCameraObjects_QSI(); #endif //----------------------------------------------------------- #ifdef _ENABLE_TOUP_ - cameraCnt += CreateTOUP_CameraObjects(); + cameraCnt += CreateCameraObjects_TOUP(); +#endif +//----------------------------------------------------------- +#ifdef _ENABLE_OGMA_ + cameraCnt += CreateCameraObjects_OGMA(); #endif //----------------------------------------------------------- #ifdef _ENABLE_SONY_ - CreateSONY_CameraObjects(); + cameraCnt += CreateCameraObjects_SONY(); #endif - +//----------------------------------------------------------- #ifdef _ENABLE_CAMERA_SIMULATOR_ cameraCnt += CreateCameraObjects_Sim(); #endif @@ -409,6 +426,11 @@ CameraDriver::CameraDriver(void) int mkdirErrCode; CONSOLE_DEBUG(__FUNCTION__); + + //* set everything to false first + memset(&cCameraProp, 0, sizeof(TYPE_CameraProperties)); + memset(&cROIinfo, 0, sizeof(TYPE_IMAGE_ROI_Info)); + //* set all of the class data to known states SetImageDataDirectory("/media/pi/rpdata/imagedata"); @@ -422,8 +444,6 @@ int mkdirErrCode; cDriverCmdTablePtr = gCameraCmdTable; TemperatureLog_SetDescription("Camera Temperature"); - //* set everything to false first - memset(&cCameraProp, 0, sizeof(TYPE_CameraProperties)); cUUID.part3 = 'CA'; //* model number cCameraProp.SensorType = kSensorType_Monochrome; @@ -3501,8 +3521,8 @@ TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_InternalError; alpacaErrCode = Read_SensorTargetTemp(); if (alpacaErrCode != kASCOM_Err_Success) { - CONSOLE_DEBUG_W_NUM("alpacaErrCode\t=", alpacaErrCode); - CONSOLE_DEBUG_W_DBL("SetCCDTemperature\t=", cCameraProp.SetCCDTemperature); +// CONSOLE_DEBUG_W_NUM("alpacaErrCode\t=", alpacaErrCode); +// CONSOLE_DEBUG_W_DBL("SetCCDTemperature\t=", cCameraProp.SetCCDTemperature); } cBytesWrittenForThisCmd += JsonResponse_Add_Double(reqData->socket, reqData->jsonTextBuffer, @@ -4433,6 +4453,7 @@ bool xmit16BitAs32Bit = false; { case kImageType_RAW8: case kImageType_Y8: + case kImageType_MONO8: CONSOLE_DEBUG("kImageType_RAW8"); binaryImageHdr.Dimension3 = 0; // (0 for 2D array) if (reqData->cHTTPclientType == kHTTPclient_AlpacaPi) @@ -4555,6 +4576,7 @@ bool xmit16BitAs32Bit = false; { case kImageType_RAW8: case kImageType_Y8: + case kImageType_MONO8: CONSOLE_DEBUG("kImageType_RAW8"); switch (binaryImageHdr.TransmissionElementType) { @@ -4790,6 +4812,7 @@ char httpHeader[500]; case kImageType_RAW8: case kImageType_Y8: case kImageType_RAW16: + case kImageType_MONO8: default: imgRank = 2; break; @@ -4814,6 +4837,7 @@ char httpHeader[500]; { case kImageType_RAW8: case kImageType_Y8: + case kImageType_MONO8: CONSOLE_DEBUG("kImageType_RAW8"); Send_imagearray_raw8( mySocket, cCameraDataBuffer, @@ -5295,6 +5319,7 @@ TYPE_ASCOM_STATUS tempSensorErr; //==================================================================== case kImageType_RAW8: + case kImageType_MONO8: CONSOLE_DEBUG("kImageType_RAW8"); Send_RGBarray_raw8(mySocket, pixelPtr, pixelCount); break; @@ -6979,7 +7004,7 @@ TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; } //***************************************************************************** -TYPE_ASCOM_STATUS CameraDriver::Write_Gain(const int newBinYvalue) +TYPE_ASCOM_STATUS CameraDriver::Write_Gain(const int newGainValue) { TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; @@ -7047,6 +7072,10 @@ TYPE_IMAGE_TYPE myImageType; { myImageType = kImageType_Y8; } + else if (strcasecmp(imageTypeString, "MONO8") == 0) + { + myImageType = kImageType_MONO8; + } else { myImageType = kImageType_Invalid; @@ -7252,7 +7281,8 @@ char myImageTypeStr[16]; case kImageType_RAW8: strcpy(myImageTypeStr, "RAW8"); break; case kImageType_RAW16: strcpy(myImageTypeStr, "RAW16"); break; case kImageType_RGB24: strcpy(myImageTypeStr, "RGB24"); break; - case kImageType_Y8: strcpy(myImageTypeStr, "Y8"); break; + case kImageType_Y8: strcpy(myImageTypeStr, "Y8"); break; + case kImageType_MONO8: strcpy(myImageTypeStr, "MONO8"); break; case kImageType_Invalid: case kImageType_last: @@ -7276,7 +7306,7 @@ TYPE_ASCOM_STATUS CameraDriver::Read_SensorTemp(void) TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; GENERATE_ALPACAPI_ERRMSG(cLastCameraErrMsg, "Not implemented"); - CONSOLE_DEBUG(cLastCameraErrMsg); +// CONSOLE_DEBUG(cLastCameraErrMsg); return(alpacaErrCode); } @@ -7286,7 +7316,7 @@ TYPE_ASCOM_STATUS CameraDriver::Read_SensorTargetTemp(void) TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; GENERATE_ALPACAPI_ERRMSG(cLastCameraErrMsg, "Not implemented"); - CONSOLE_DEBUG(cLastCameraErrMsg); +// CONSOLE_DEBUG(cLastCameraErrMsg); return(alpacaErrCode); } @@ -7444,7 +7474,7 @@ int CameraDriver::RunStateMachine_TakingPicture(void) int exposureState; TYPE_ASCOM_STATUS alpacaErrCode; -// CONSOLE_DEBUG(__FUNCTION__); + CONSOLE_DEBUG(__FUNCTION__); exposureState = Check_Exposure(true); if (cVerboseDebug) @@ -7454,7 +7484,7 @@ TYPE_ASCOM_STATUS alpacaErrCode; switch(exposureState) { case kExposure_Idle: - CONSOLE_DEBUG("Reseting to idle"); + CONSOLE_DEBUG("Resetting to idle"); cInternalCameraState = kCameraState_Idle; cWorkingLoopCnt = 0; break; @@ -7466,7 +7496,7 @@ TYPE_ASCOM_STATUS alpacaErrCode; { // CONSOLE_DEBUG("kExposure_Working"); Check_Exposure(true); - // CONSOLE_DEBUG_W_STR("Aborting.... Reseting to idle-", cDeviceManufAbrev); + // CONSOLE_DEBUG_W_STR("Aborting.... Resetting to idle-", cDeviceManufAbrev); // cInternalCameraState = kCameraState_Idle; cWorkingLoopCnt = 0; } @@ -7477,6 +7507,7 @@ TYPE_ASCOM_STATUS alpacaErrCode; break; case kExposure_Success: + CONSOLE_DEBUG("kExposure_Success"); cFramesRead++; if (gVerbose) { @@ -7801,8 +7832,6 @@ char fileNameDateString[64]; // CONSOLE_DEBUG_W_STR("cFileNameRoot\t=", cFileNameRoot); } - - #pragma mark - @@ -8235,52 +8264,63 @@ TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_Success; //***************************************************************************** TYPE_ASCOM_STATUS CameraDriver::Put_Flip(TYPE_GetPutRequestData *reqData, char *alpacaErrMsg) { -TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_MethodNotImplemented; char argumentString[32]; bool foundKeyWord; int newFlipMode; CONSOLE_DEBUG(__FUNCTION__); - CONSOLE_DEBUG(reqData->contentData); - if (reqData != NULL) + if (cCanFlipImage) { - //* look for filter - foundKeyWord = GetKeyWordArgument( reqData->contentData, - "flip", - argumentString, - (sizeof(argumentString) -1)); - if (foundKeyWord) + CONSOLE_DEBUG(reqData->contentData); + if (reqData != NULL) { - newFlipMode = atoi(argumentString); - if ((newFlipMode >= kFlip_None) && (newFlipMode <= kFlip_Both)) + //* look for filter + foundKeyWord = GetKeyWordArgument( reqData->contentData, + "flip", + argumentString, + (sizeof(argumentString) -1)); + if (foundKeyWord) { - alpacaErrCode = SetFlipMode(newFlipMode); - if (alpacaErrCode != kASCOM_Err_Success) + newFlipMode = atoi(argumentString); + if ((newFlipMode >= kFlip_None) && (newFlipMode <= kFlip_Both)) { - GENERATE_ALPACAPI_ERRMSG(alpacaErrMsg, cLastCameraErrMsg); + alpacaErrCode = SetFlipMode(newFlipMode); + if (alpacaErrCode == kASCOM_Err_Success) + { + cFlipMode = newFlipMode; + } + else + { + GENERATE_ALPACAPI_ERRMSG(alpacaErrMsg, cLastCameraErrMsg); + } + } + else + { + alpacaErrCode = kASCOM_Err_InvalidValue; + GENERATE_ALPACAPI_ERRMSG(alpacaErrMsg, "Invalid flip value"); } } else { - alpacaErrCode = kASCOM_Err_InvalidValue; - GENERATE_ALPACAPI_ERRMSG(alpacaErrMsg, "Invalid flip value"); + GENERATE_ALPACAPI_ERRMSG(alpacaErrMsg, "Keyword 'flip' not found"); } } else { - GENERATE_ALPACAPI_ERRMSG(alpacaErrMsg, "Keyword 'flip' not found"); + alpacaErrCode = kASCOM_Err_InternalError; } } else { - alpacaErrCode = kASCOM_Err_InternalError; + GENERATE_ALPACAPI_ERRMSG(alpacaErrMsg, "flip not supported"); } return(alpacaErrCode); } //***************************************************************************** -TYPE_ASCOM_STATUS CameraDriver::SetFlipMode(int newFlipMode) +TYPE_ASCOM_STATUS CameraDriver::SetFlipMode(const int newFlipMode) { //* this routine needs to be over ridden if you want to enable flip mode //* IT IS THE RESPONSIBILITY OF THIS ROUTINE TO ACTUALLY SET cFlipMode @@ -9357,7 +9397,7 @@ bool checkedFlag; SocketWriteData(mySocketFD, gHtmlHeader); SocketWriteData(mySocketFD, "\r\n"); - SocketWriteData(mySocketFD, "\r\n"); + SocketWriteData(mySocketFD, "\r\n"); sprintf(lineBuff, "%s\r\n", cameraTitle); SocketWriteData(mySocketFD, lineBuff); SocketWriteData(mySocketFD, "
    \r\n"); diff --git a/src/cameradriver.h b/src/cameradriver.h index 13ca476..05afec6 100644 --- a/src/cameradriver.h +++ b/src/cameradriver.h @@ -28,6 +28,7 @@ //* Oct 9, 2022 Added cCameraIsSiumlated flag //* Jun 4, 2023 Added cSaveAsFITS, cSaveAsJPEG, cSaveAsPNG, cSaveAsRAW //* Aug 31, 2023 Adding support for GPS, specifically the QHY174-GPS +//* Apr 19, 2024 Added kImageType_MONO8 //***************************************************************************** //#include "cameradriver.h" @@ -168,6 +169,7 @@ typedef enum kImageType_RAW16, kImageType_RGB24, kImageType_Y8, + kImageType_MONO8, kImageType_last } TYPE_IMAGE_TYPE; @@ -586,7 +588,7 @@ class CameraDriver: public AlpacaDriver virtual TYPE_ASCOM_STATUS Stop_Video(void); virtual TYPE_ASCOM_STATUS Take_Video(void); - virtual TYPE_ASCOM_STATUS SetFlipMode(int newFlipMode); + virtual TYPE_ASCOM_STATUS SetFlipMode(const int newFlipMode); virtual TYPE_ALPACA_CAMERASTATE Read_AlapcaCameraState(void); @@ -811,6 +813,7 @@ class CameraDriver: public AlpacaDriver protected: virtual void RunThread_Startup(void); virtual void RunThread_Loop(void); + virtual void RunThread_CheckPictureStatus(void); public: #endif // _USE_CAMERA_READ_THREAD_ diff --git a/src/cameradriverAnalysis.cpp b/src/cameradriverAnalysis.cpp index ab05db7..7406684 100755 --- a/src/cameradriverAnalysis.cpp +++ b/src/cameradriverAnalysis.cpp @@ -44,6 +44,7 @@ //* Dec 26, 2019 Added SaveHistogramFile() //* Jan 12, 2020 Added better limit checking to AutoAdjustExposure() //* Feb 15, 2020 Fixed negative exposure bug in AutoAdjustExposure() +//* Apr 22, 2024 Added support for kImageType_MONO8 (8 bit image type) //************************************************************************** #ifdef _ENABLE_CAMERA_ @@ -92,6 +93,7 @@ uint32_t bluValue; switch(cROIinfo.currentROIimageType) { case kImageType_RAW8: + case kImageType_MONO8: case kImageType_Y8: imageDataPtr8bit = (uint8_t *)cCameraDataBuffer; for (ii=0; ii Started on camera code //* Apr 15, 2019 Added command table for camera -//* Apr 17, 2019 Added Camera_OutputHTML() +//* Apr 17, 2019 Added OutputHTML() //* Apr 17, 2019 Read temperature working on ASI1600 //* Apr 27, 2019 Added error messages for ASI failures //* Apr 29, 2019 Reading images from ASI camera @@ -80,7 +80,7 @@ //* Mar 26, 2021 Offset value read/write working in ASI cameras //* Oct 13, 2021 Added Write_BinX() & Write_BinY() to ASI driver //* May 17, 2022 Changed the way power level is reported -//* Oct 1, 2022 Changed CreateASI_CameraObjects() to return camera count +//* Oct 1, 2022 Changed CreateCameraObjects_ASI() to return camera count //* Apr 30, 2023 Added Read_SensorTargetTemp() & Write_SensorTargetTemp() //* Sep 9, 2023 Moved read thread stuff to parent class //* Sep 9, 2023 Deleted _USE_THREADS_FOR_ASI_CAMERA_ @@ -139,7 +139,7 @@ static void Get_ASI_ImageTypeString(ASI_IMG_TYPE imageType, char *typeString); //************************************************************************************** //* returns the number of camera objects created //************************************************************************************** -int CreateASI_CameraObjects(void) +int CreateCameraObjects_ASI(void) { int devNum; char driverVersionString[64]; @@ -1951,6 +1951,7 @@ ASI_BOOL bAuto; } else { + alpacaErrCode = kASCOM_Err_UnspecifiedError; strcpy(cLastCameraErrMsg, "Failed to set gain"); CONSOLE_DEBUG(cLastCameraErrMsg); } @@ -2654,6 +2655,7 @@ char asiErrorMsgString[64]; } else { + alpacaErrCode = kASCOM_Err_UnspecifiedError; strcpy(cLastCameraErrMsg, "Failed to allocate buffer"); CONSOLE_DEBUG(cLastCameraErrMsg); } @@ -2692,7 +2694,7 @@ char asiErrorMsgString[64]; } //***************************************************************************** -TYPE_ASCOM_STATUS CameraDriverASI::SetFlipMode(int newFlipMode) +TYPE_ASCOM_STATUS CameraDriverASI::SetFlipMode(const int newFlipMode) { TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_Success; ASI_ERROR_CODE asiErrorCode; diff --git a/src/cameradriver_ASI.h b/src/cameradriver_ASI.h index 86eeec7..ffed7e5 100755 --- a/src/cameradriver_ASI.h +++ b/src/cameradriver_ASI.h @@ -24,7 +24,7 @@ #include "ASICamera2.h" #endif -int CreateASI_CameraObjects(void); +int CreateCameraObjects_ASI(void); //************************************************************************************** @@ -76,7 +76,7 @@ class CameraDriverASI: public CameraDriver // virtual TYPE_ASCOM_STATUS Read_Readoutmodes(char *readOutModeString, bool includeQuotes=false); virtual TYPE_ASCOM_STATUS Read_Fastreadout(void); virtual TYPE_ASCOM_STATUS Read_ImageData(void); - virtual TYPE_ASCOM_STATUS SetFlipMode(int newFlipMode); + virtual TYPE_ASCOM_STATUS SetFlipMode(const int newFlipMode); diff --git a/src/cameradriver_ATIK.cpp b/src/cameradriver_ATIK.cpp index e1de2f7..9f0eb0a 100755 --- a/src/cameradriver_ATIK.cpp +++ b/src/cameradriver_ATIK.cpp @@ -85,7 +85,7 @@ //************************************************************************************** //* returns the number of camera objects created //************************************************************************************** -int CreateATIK_CameraObjects(void) +int CreateCameraObjects_ATIK(void) { int devNum; int atikDeviceCount; diff --git a/src/cameradriver_ATIK.h b/src/cameradriver_ATIK.h index f059313..9f61fc0 100755 --- a/src/cameradriver_ATIK.h +++ b/src/cameradriver_ATIK.h @@ -23,7 +23,7 @@ #include "AtikCameras.h" -int CreateATIK_CameraObjects(void); +int CreateCameraObjects_ATIK(void); //************************************************************************************** diff --git a/src/cameradriver_FLIR.cpp b/src/cameradriver_FLIR.cpp index 8a6fdbc..757a5ce 100755 --- a/src/cameradriver_FLIR.cpp +++ b/src/cameradriver_FLIR.cpp @@ -75,7 +75,7 @@ static void GetSpinnakerErrorString(_spinError errorCode, char *errorString); //************************************************************************************** -int CreateFLIR_CameraObjects(void) +int CreateCameraObjects_FLIR(void) { int cameraCreatedCount; char rulesFileName[] = "40-flir-spinnaker.rules"; diff --git a/src/cameradriver_FLIR.h b/src/cameradriver_FLIR.h index a6af578..5d8daf6 100755 --- a/src/cameradriver_FLIR.h +++ b/src/cameradriver_FLIR.h @@ -39,7 +39,7 @@ #include "cameradriver.h" #endif -int CreateFLIR_CameraObjects(void); +int CreateCameraObjects_FLIR(void); //************************************************************************************** class CameraDriverFLIR: public CameraDriver diff --git a/src/cameradriver_OGMA.cpp b/src/cameradriver_OGMA.cpp new file mode 100644 index 0000000..74a17ad --- /dev/null +++ b/src/cameradriver_OGMA.cpp @@ -0,0 +1,1228 @@ +//************************************************************************** +//* Name: cameradriver_OGMA.cpp +//* +//* Author: Mark Sproul (C) 2024 +//* +//* Description: C++ Driver for Alpaca protocol +//* +//***************************************************************************** +//* AlpacaPi is an open source project written in C/C++ +//* +//* Use of this source code for private or individual use is granted +//* Use of this source code, in whole or in part for commercial purpose requires +//* written agreement in advance. +//* +//* You may use or modify this source code in any way you find useful, provided +//* that you agree that the author(s) have no warranty, obligations or liability. You +//* must determine the suitability of this source code for your use. +//* +//* Re-distributions of this source code must retain this copyright notice. +//***************************************************************************** +//* +//* References: +//* https://getogma.com/ +//* https://getogma.com/download +//***************************************************************************** +//* Edit History +//***************************************************************************** +//* = Mark L Sproul +//***************************************************************************** +//* Apr 21, 2024 Discussed Alpaca protocol with Juan Martinez at OGMA +//* Apr 21, 2024 Juan told me that OGMA is almost identical to ToupTek, nearly identical SDK +//* Apr 21, 2024 OGMA cameras gave me one of their low-end cameras https://getogma.com/ +//* Apr 22, 2024 Downloaded SDK from https://github.com/OGMAvision/OGMAcamSDK +//* Apr 23, 2024 Created cameradriver_OGMA.cpp +//***************************************************************************** + + +#if defined(_ENABLE_CAMERA_) && defined(_ENABLE_OGMA_) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _ENABLE_CONSOLE_DEBUG_ +#include "ConsoleDebug.h" + +#define _USE_PDB_ADDITIONS_ + +#include "JsonResponse.h" +#include "eventlogging.h" + + +#define OGMACAM_HRESULT_ERRORCODE_NEEDED +#include "../OGMAcamSDK/inc/ogmacam.h" +#include "alpacadriver.h" +#include "alpacadriver_helper.h" +#include "cameradriver.h" +#include "cameradriver_OGMA.h" + +#ifndef S_OK +// //* these are not defined in toupcam.h, they should be +// #define S_OK 0x00000000 // Operation successful +// #define S_FALSE 0x00000001 // +// #define E_FAIL 0x80004005 // Unspecified failure +// #define E_ACCESSDENIED 0x80070005 // General access denied error +// #define E_INVALIDARG 0x80070057 // One or more arguments are not valid +// #define E_NOTIMPL 0x80004001 // Not supported or not implemented +// #define E_NOINTERFACE 0x80004002 // Interface not supported +// #define E_POINTER 0x80004003 // Pointer that is not valid +// #define E_UNEXPECTED 0x8000FFFF // Unexpected failure +// #define E_OUTOFMEMORY 0x8007000E // Out of memory +// #define E_WRONG_THREAD 0x8001010E // call function in the wrong thread +// #define E_GEN_FAILURE 0x8007001F // device not functioning +#endif // S_OK + + +#define kMaxCameraCnt 5 + + + +//************************************************************************************** +int CreateCameraObjects_OGMA(void) +{ +int cameraCount; +int ii; +bool rulesFileOK; +int ogmaCameraCnt; +OgmacamDeviceV2 ogmaCamList[OGMACAM_MAX]; +char rulesFileName[] = "99-toupcam.rules"; +char driverVersionString[64]; + + CONSOLE_DEBUG(__FUNCTION__); + cameraCount = 0; + strcpy(driverVersionString, Ogmacam_Version()); + CONSOLE_DEBUG_W_STR("Ogmacam_Version", driverVersionString); + LogEvent( "camera", + "Library version (TOUP)", + NULL, + kASCOM_Err_Success, + driverVersionString); + AddLibraryVersion("camera", "TOUP", driverVersionString); + + + ogmaCameraCnt = Ogmacam_EnumV2(ogmaCamList); + CONSOLE_DEBUG_W_NUM("ogmaCameraCnt\t=", ogmaCameraCnt); + + //* check to make sure the rules file is present + rulesFileOK = Check_udev_rulesFile(rulesFileName); + if (rulesFileOK) + { + CONSOLE_DEBUG_W_STR("rules is present:", rulesFileName); + } + else + { + CONSOLE_DEBUG_W_STR("rules is MISSING:", rulesFileName); + LogEvent( "camera", + "Problem with TOUP rules", + NULL, + kASCOM_Err_Success, + rulesFileName); + } + + + if (ogmaCameraCnt > 0) + { + for (ii=0; ii < ogmaCameraCnt; ii++) + { + new CameraDriverOGMA(ii); + cameraCount++; + } +// CONSOLE_ABORT(__FUNCTION__); + } + return(cameraCount); +} + + + + +//************************************************************************************** +static void __stdcall EventCallback(unsigned nEvent, void* pCallbackCtx) +{ +CameraDriverOGMA *thisPtr; + +// CONSOLE_DEBUG(__FUNCTION__); + + thisPtr = (CameraDriverOGMA *)pCallbackCtx; + if (thisPtr != NULL) + { + thisPtr->HandleOGMAcallbackEvent(nEvent); + } +} + + +//************************************************************************************** +CameraDriverOGMA::CameraDriverOGMA(const int deviceNum) + :CameraDriver() +{ +HRESULT ogmaResult; + +// CONSOLE_DEBUG(__FUNCTION__); + strcpy(cDeviceManufAbrev, "OGMA"); + + + cCameraID = deviceNum; + cOGMApicReady = false; + cIsTriggerCam = false; + cCameraProp.ExposureMin_us = 400; //* 0.4 ms + cCameraProp.ExposureMax_us = 800 * 1000 *1000; //* 800 seconds + + ReadCameraInfo(); + + strcpy(cCommonProp.Description, cDeviceManufacturer); + strcat(cCommonProp.Description, " - Model:"); + strcat(cCommonProp.Description, cCommonProp.Name); + +#ifdef _USE_OPENCV_ + sprintf(cOpenCV_ImgWindowName, "%s-%d", cCommonProp.Name, cCameraID); +#endif // _USE_OPENCV_ + + if (cOGMAcamH != NULL) + { + ogmaResult = Ogmacam_StartPullModeWithCallback(cOGMAcamH, EventCallback, this); + if (FAILED(ogmaResult)) + { + CONSOLE_DEBUG("FAILED PULLBACK"); + } + } + +} + + +//************************************************************************************** +// Destructor +//************************************************************************************** +CameraDriverOGMA::~CameraDriverOGMA(void) +{ + CONSOLE_DEBUG(__FUNCTION__); +} + +//************************************************************************************** +typedef struct +{ + uint64_t flag; + char description[64]; +} TYPE_FLAGtable; + +TYPE_FLAGtable gCameraFlagTable[] = +{ + + { OGMACAM_FLAG_CMOS, "OGMACAM_FLAG_CMOS" }, + { OGMACAM_FLAG_CCD_PROGRESSIVE, "OGMACAM_FLAG_CCD_PROGRESSIVE" }, + { OGMACAM_FLAG_CCD_INTERLACED, "OGMACAM_FLAG_CCD_INTERLACED" }, + { OGMACAM_FLAG_ROI_HARDWARE, "OGMACAM_FLAG_ROI_HARDWARE" }, + { OGMACAM_FLAG_MONO, "OGMACAM_FLAG_MONO" }, + { OGMACAM_FLAG_BINSKIP_SUPPORTED, "OGMACAM_FLAG_BINSKIP_SUPPORTED" }, + { OGMACAM_FLAG_USB30, "OGMACAM_FLAG_USB30" }, + { OGMACAM_FLAG_TEC, "OGMACAM_FLAG_TEC" }, + { OGMACAM_FLAG_USB30_OVER_USB20, "OGMACAM_FLAG_USB30_OVER_USB20" }, + { OGMACAM_FLAG_ST4, "OGMACAM_FLAG_ST4" }, + { OGMACAM_FLAG_GETTEMPERATURE, "OGMACAM_FLAG_GETTEMPERATURE" }, + { OGMACAM_FLAG_HIGH_FULLWELL, "OGMACAM_FLAG_HIGH_FULLWELL" }, + { OGMACAM_FLAG_RAW10, "OGMACAM_FLAG_RAW10" }, + { OGMACAM_FLAG_RAW12, "OGMACAM_FLAG_RAW12" }, + { OGMACAM_FLAG_RAW14, "OGMACAM_FLAG_RAW14" }, + { OGMACAM_FLAG_RAW16, "OGMACAM_FLAG_RAW16" }, + { OGMACAM_FLAG_FAN, "OGMACAM_FLAG_FAN" }, + { OGMACAM_FLAG_TEC_ONOFF, "OGMACAM_FLAG_TEC_ONOFF" }, + { OGMACAM_FLAG_ISP, "OGMACAM_FLAG_ISP" }, + { OGMACAM_FLAG_TRIGGER_SOFTWARE, "OGMACAM_FLAG_TRIGGER_SOFTWARE" }, + { OGMACAM_FLAG_TRIGGER_EXTERNAL, "OGMACAM_FLAG_TRIGGER_EXTERNAL" }, + { OGMACAM_FLAG_TRIGGER_SINGLE, "OGMACAM_FLAG_TRIGGER_SINGLE" }, + { OGMACAM_FLAG_BLACKLEVEL, "OGMACAM_FLAG_BLACKLEVEL" }, + { OGMACAM_FLAG_AUTO_FOCUS, "OGMACAM_FLAG_AUTO_FOCUS" }, + { OGMACAM_FLAG_BUFFER, "OGMACAM_FLAG_BUFFER" }, + { OGMACAM_FLAG_DDR, "OGMACAM_FLAG_DDR" }, + { OGMACAM_FLAG_CG, "OGMACAM_FLAG_CG" }, + { OGMACAM_FLAG_YUV411, "OGMACAM_FLAG_YUV411" }, + { OGMACAM_FLAG_VUYY, "OGMACAM_FLAG_VUYY" }, + { OGMACAM_FLAG_YUV444, "OGMACAM_FLAG_YUV444" }, + { OGMACAM_FLAG_RGB888, "OGMACAM_FLAG_RGB888" }, + { OGMACAM_FLAG_RAW8, "OGMACAM_FLAG_RAW8" }, + { OGMACAM_FLAG_GMCY8, "OGMACAM_FLAG_GMCY8" }, + { OGMACAM_FLAG_GMCY12, "OGMACAM_FLAG_GMCY12" }, + { OGMACAM_FLAG_UYVY, "OGMACAM_FLAG_UYVY" }, + { OGMACAM_FLAG_CGHDR, "OGMACAM_FLAG_CGHDR" }, + { OGMACAM_FLAG_GLOBALSHUTTER, "OGMACAM_FLAG_GLOBALSHUTTER" }, + { OGMACAM_FLAG_FOCUSMOTOR, "OGMACAM_FLAG_FOCUSMOTOR" }, + { OGMACAM_FLAG_PRECISE_FRAMERATE, "OGMACAM_FLAG_PRECISE_FRAMERATE" }, + { OGMACAM_FLAG_HEAT, "OGMACAM_FLAG_HEAT" }, + { OGMACAM_FLAG_LOW_NOISE, "OGMACAM_FLAG_LOW_NOISE" }, + { OGMACAM_FLAG_LEVELRANGE_HARDWARE, "OGMACAM_FLAG_LEVELRANGE_HARDWARE" }, + { OGMACAM_FLAG_EVENT_HARDWARE, "OGMACAM_FLAG_EVENT_HARDWARE" }, + { OGMACAM_FLAG_LIGHTSOURCE, "OGMACAM_FLAG_LIGHTSOURCE" }, + { OGMACAM_FLAG_FILTERWHEEL, "OGMACAM_FLAG_FILTERWHEEL" }, + { OGMACAM_FLAG_GIGE, "OGMACAM_FLAG_GIGE" }, + { OGMACAM_FLAG_10GIGE, "OGMACAM_FLAG_10GIGE" }, + { OGMACAM_FLAG_5GIGE, "OGMACAM_FLAG_5GIGE" }, + { OGMACAM_FLAG_25GIGE, "OGMACAM_FLAG_25GIGE" }, + { OGMACAM_FLAG_AUTOFOCUSER, "OGMACAM_FLAG_AUTOFOCUSER" }, + { OGMACAM_FLAG_LIGHT_SOURCE, "OGMACAM_FLAG_LIGHT_SOURCE" }, + { OGMACAM_FLAG_CAMERALINK, "OGMACAM_FLAG_CAMERALINK" }, + { OGMACAM_FLAG_CXP, "OGMACAM_FLAG_CXP" }, + { OGMACAM_FLAG_RAW12PACK, "OGMACAM_FLAG_RAW12PACK" }, + { OGMACAM_FLAG_SELFTRIGGER, "OGMACAM_FLAG_SELFTRIGGER" }, + { OGMACAM_FLAG_RAW11, "OGMACAM_FLAG_RAW11" }, + { OGMACAM_FLAG_GHOPTO, "OGMACAM_FLAG_GHOPTO" }, + { 0, "foo" } +}; + +//***************************************************************************** +static void DumpCameraFlags(uint64_t flags) +{ +int iii; + + iii = 0; + while (gCameraFlagTable[iii].flag != 0) + { + printf("%-48s\t%s\r\n", gCameraFlagTable[iii].description, + ((flags & gCameraFlagTable[iii].flag) ? "True" : "False")); + iii++; + } +} + + +//***************************************************************************** +void CameraDriverOGMA::ReadCameraInfo(void) +{ +unsigned int ii; +int ogmaCameraCnt; +OgmacamDeviceV2 ogmaCamList[OGMACAM_MAX]; +HRESULT ogmaResult; +char hardwareVer[16]; +char productionDate[10]; +char fpgaVersion[32]; +int bAutoExposure; +int rgbMode; + +// CONSOLE_DEBUG(__FUNCTION__); + strcpy(cDeviceVersion, Ogmacam_Version()); + CONSOLE_DEBUG_W_STR("Ogmacam_Version", cDeviceVersion); + ogmaCameraCnt = Ogmacam_EnumV2(ogmaCamList); + + if (cCameraID < ogmaCameraCnt) + { + cOGMAdeviceInfo = ogmaCamList[cCameraID]; + + strcpy(cDeviceManufacturer, "OGMA"); + strcpy(cDeviceManufAbrev, "OGMA"); + strcpy(cDeviceSerialNum, cOGMAdeviceInfo.id); + + SetCommonPropertyName(NULL, cOGMAdeviceInfo.displayname); + + cCameraProp.CameraXsize = cOGMAdeviceInfo.model->res[0].width; + cCameraProp.CameraYsize = cOGMAdeviceInfo.model->res[0].height; + cCameraProp.NumX = cCameraProp.CameraXsize; + cCameraProp.NumY = cCameraProp.CameraYsize; + cCameraProp.PixelSizeY = cOGMAdeviceInfo.model->xpixsz; + cCameraProp.PixelSizeX = cOGMAdeviceInfo.model->ypixsz; + cIsColorCam = true; + + if ((cCameraProp.CameraXsize > 0) && (cCameraProp.CameraYsize > 0)) + { + AllocateImageBuffer(0); + } + + CONSOLE_DEBUG_W_STR("Display name\t=", cOGMAdeviceInfo.displayname); + CONSOLE_DEBUG_W_STR("ID\t\t\t=", cOGMAdeviceInfo.id); + + CONSOLE_DEBUG_W_STR("name\t\t=", cOGMAdeviceInfo.model->name); + + CONSOLE_DEBUG_W_HEX("flag\t\t=", (int)cOGMAdeviceInfo.model->flag); + CONSOLE_DEBUG_W_HEX("flag\t\t=", (int)(cOGMAdeviceInfo.model->flag >> 32)); + CONSOLE_DEBUG_W_NUM("preview\t\t=", cOGMAdeviceInfo.model->preview); + CONSOLE_DEBUG_W_NUM("still\t\t=", cOGMAdeviceInfo.model->still); + CONSOLE_DEBUG_W_NUM("ioctrol\t\t=", cOGMAdeviceInfo.model->ioctrol); + CONSOLE_DEBUG_W_NUM("maxfanspeed\t=", cOGMAdeviceInfo.model->maxfanspeed); + DumpCameraFlags(cOGMAdeviceInfo.model->flag); + + for (ii=0; iipreview; ii++) + { + CONSOLE_DEBUG_W_NUM("width\t\t=", cOGMAdeviceInfo.model->res[ii].width); + CONSOLE_DEBUG_W_NUM("height\t\t=", cOGMAdeviceInfo.model->res[ii].height); + } + + //* check these in this order to make sure we record the highest value + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_RAW8) + { + CONSOLE_DEBUG("OGMACAM_FLAG_RAW8"); + cBitDepth = 8; + cOGMAcamFormat = OGMACAM_FLAG_RAW8; + AddReadoutModeToList(kImageType_RAW8); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_RAW10) + { + CONSOLE_DEBUG("OGMACAM_FLAG_RAW10"); + cBitDepth = 10; + cOGMAcamFormat = OGMACAM_FLAG_RAW16; + AddReadoutModeToList(kImageType_RAW16); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_RAW12) + { + CONSOLE_DEBUG("OGMACAM_FLAG_RAW12"); + cBitDepth = 12; + cOGMAcamFormat = OGMACAM_FLAG_RAW16; + AddReadoutModeToList(kImageType_RAW16); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_RAW14) + { + CONSOLE_DEBUG("OGMACAM_FLAG_RAW14"); + cBitDepth = 14; + cOGMAcamFormat = OGMACAM_FLAG_RAW16; + AddReadoutModeToList(kImageType_RAW16); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_RAW16) + { + CONSOLE_DEBUG("OGMACAM_FLAG_RAW16"); + cBitDepth = 16; + cOGMAcamFormat = OGMACAM_FLAG_RAW16; + AddReadoutModeToList(kImageType_RAW16); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_RGB888) + { + CONSOLE_DEBUG("OGMACAM_FLAG_RGB888"); + cBitDepth = 8; + cOGMAcamFormat = OGMACAM_FLAG_RGB888; + AddReadoutModeToList(kImageType_RGB24); + } + AddReadoutModeToList(kImageType_RGB24); + + //------------------------------------------------------------- + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_ST4) + { + cSt4Port = true; + CONSOLE_DEBUG("OGMACAM_FLAG_ST4"); + } + + + //--------------------------------------------- + cOGMAcamH = Ogmacam_Open(cOGMAdeviceInfo.id); + if (cOGMAcamH != NULL) + { + unsigned int nFourCC; + unsigned int bitsperpixel; + char fourCCstring[8]; + char serialNumberStr[64]; +// int finalWidth; +// int finalHeight; + char firmWareVersion[32]; + + CONSOLE_DEBUG("Ogmacam_Open OK"); +#ifdef _USE_PDB_ADDITIONS_ + ogmaResult = Ogmacam_put_Option(cOGMAcamH, OGMACAM_OPTION_RAW, 1); + CONSOLE_DEBUG_W_HEX("ogmaResult\t\t=", ogmaResult); + if (FAILED(ogmaResult)) + { + CONSOLE_DEBUG("Failed RAW"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_TRIGGER_SOFTWARE) + { + cIsTriggerCam = true; //* 1/25/2021 + CONSOLE_DEBUG("OGMACAM_FLAG_TRIGGER_SOFTWARE"); + ogmaResult = Ogmacam_put_Option(cOGMAcamH, OGMACAM_OPTION_TRIGGER, 1); + } + ogmaResult = Ogmacam_get_RawFormat(cOGMAcamH, &nFourCC, &bitsperpixel); +#endif + + + ogmaResult = Ogmacam_get_RawFormat(cOGMAcamH, &nFourCC, &bitsperpixel); + CONSOLE_DEBUG_W_HEX("ogmaResult\t\t=", ogmaResult); + CONSOLE_DEBUG_W_NUM("bitsperpixel\t=", bitsperpixel); + CONSOLE_DEBUG_W_HEX("nFourCC\t\t=", nFourCC); + + if (nFourCC == 'GRBG') + { + CONSOLE_DEBUG("nFourCC == 'GRBG'"); + AddReadoutModeToList(kImageType_RGB24); + } + fourCCstring[0] = (nFourCC >> 24) & 0x0ff; + fourCCstring[1] = (nFourCC >> 16) & 0x0ff; + fourCCstring[2] = (nFourCC >> 8) & 0x0ff; + fourCCstring[3] = (nFourCC) & 0x0ff; + fourCCstring[4] = 0; + CONSOLE_DEBUG_W_STR("nFourCC\t\t=", fourCCstring); + + cBitDepth = Ogmacam_get_MaxBitDepth(cOGMAcamH); + CONSOLE_DEBUG_W_NUM("cBitDepth\t\t=", cBitDepth); + + ogmaResult = Ogmacam_get_SerialNumber(cOGMAcamH, serialNumberStr); + CONSOLE_DEBUG_W_STR("serialNumber\t=", serialNumberStr); + + ogmaResult = Ogmacam_get_FwVersion(cOGMAcamH, firmWareVersion); + CONSOLE_DEBUG_W_STR("firmWareVersion\t=", firmWareVersion); + if (SUCCEEDED(ogmaResult)) + { + strcpy(cDeviceFirmwareVersStr, firmWareVersion); + } + + //* get the camera hardware version, such as: 3.12 + ogmaResult = Ogmacam_get_HwVersion(cOGMAcamH, hardwareVer); + CONSOLE_DEBUG_W_STR("hardware version\t=", hardwareVer); + + //* get the production date, such as: 20150327, YYYYMMDD, (YYYY: year, MM: month, DD: day) + ogmaResult = Ogmacam_get_ProductionDate(cOGMAcamH, productionDate); + if (SUCCEEDED(ogmaResult)) + { + CONSOLE_DEBUG_W_STR("production date\t=", productionDate); + strcpy(cCameraProp.ProductionDate, productionDate); + } + //* get the FPGA version, such as: 1.13 + ogmaResult = Ogmacam_get_FpgaVersion(cOGMAcamH, fpgaVersion); + if (SUCCEEDED(ogmaResult)) + { + CONSOLE_DEBUG_W_STR("FPGA version\t=", fpgaVersion); + strcpy(cCameraProp.FPGAversion, fpgaVersion); + } + //----------------------------------------------------------- + ogmaResult = Ogmacam_get_Option(cOGMAcamH, OGMACAM_OPTION_RGB, &rgbMode); + if (SUCCEEDED(ogmaResult)) + { + CONSOLE_DEBUG_W_NUM( "rgbMode\t=", rgbMode); + CONSOLE_DEBUG( " 0 => RGB24;"); + CONSOLE_DEBUG( " 1 => enable RGB48 format when bitdepth > 8;"); + CONSOLE_DEBUG( " 2 => RGB32;"); + CONSOLE_DEBUG( " 3 => 8 Bits Gray (only for mono camera"); + CONSOLE_DEBUG( " 4 => 16 Bits Gray (only for mono camera when bitdepth > 8)"); + CONSOLE_DEBUG( " 5 => 64(RGB64)"); + } + else + { + CONSOLE_DEBUG_W_HEX("Ogmacam_get_Option failed, ogmaResult\t=", ogmaResult); + } + + //----------------------------------------------------------- + //----------------------------------------------------------- + ogmaResult = Ogmacam_get_MonoMode(cOGMAcamH); + if (SUCCEEDED(ogmaResult)) + { + //* S_FALSE: color mode + //* S_OK: mono mode, such as EXCCD00300KMA and UHCCD01400KMA + if (ogmaResult == S_OK) + { + CONSOLE_DEBUG("Ogmacam_get_MonoMode() returned S_OK"); + cIsColorCam = false; + } + else if (ogmaResult == S_FALSE) + { + CONSOLE_DEBUG("Ogmacam_get_MonoMode() returned S_FALSE"); + cIsColorCam = true; + } + CONSOLE_DEBUG_W_BOOL("cIsColorCam\t=", cIsColorCam); + } + else + { + CONSOLE_DEBUG_W_HEX("Ogmacam_get_MonoMode() failed, ogmaResult\t=", ogmaResult); + } + + // Disable AutoExposure + ogmaResult = Ogmacam_put_AutoExpoEnable(cOGMAcamH, false); + + ogmaResult = Ogmacam_get_AutoExpoEnable(cOGMAcamH, &bAutoExposure); + if (SUCCEEDED(ogmaResult)) + { + CONSOLE_DEBUG_W_NUM("Auto Exposure enabled\t=", bAutoExposure); + if (bAutoExposure != 0) + { + cCameraAutoExposure = true; + } + else + { + cCameraAutoExposure = false; + } + } + + // CONSOLE_DEBUG("Calling Ogmacam_get_FinalSize"); + // ogmaResult = Ogmacam_get_FinalSize(cOGMAcamH, &finalWidth, &finalHeight); + // CONSOLE_DEBUG_W_NUM("finalWidth\t=", finalWidth); + // CONSOLE_DEBUG_W_NUM("finalHeight\t=", finalHeight); + // int testPattern; + // ogmaResult = Ogmacam_get_Option(cOGMAcamH, Ogmacam_OPTION_TESTPATTERN, &testPattern); + // if (SUCCEEDED(ogmaResult)) + // { + // CONSOLE_DEBUG_W_NUM("testPattern\t=", testPattern); + // ogmaResult = Ogmacam_put_Option(cOGMAcamH, Ogmacam_OPTION_TESTPATTERN, 9); + // } + // else + // { + // CONSOLE_DEBUG_W_HEX("Ogmacam_get_Option() failed, ogmaResult = ", ogmaResult); + // } + + + } + else + { + CONSOLE_DEBUG("Ogmacam_Open FAILED!!!!"); + } + //--------------------------------------------- + + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_CMOS) + { + CONSOLE_DEBUG("OGMACAM_FLAG_CMOS"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_CCD_PROGRESSIVE) + { + CONSOLE_DEBUG("OGMACAM_FLAG_CCD_PROGRESSIVE"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_CCD_INTERLACED) + { + CONSOLE_DEBUG("OGMACAM_FLAG_CCD_INTERLACED"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_ROI_HARDWARE) + { + CONSOLE_DEBUG("OGMACAM_FLAG_ROI_HARDWARE"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_MONO) + { + CONSOLE_DEBUG("OGMACAM_FLAG_MONO"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_BINSKIP_SUPPORTED) + { + CONSOLE_DEBUG("OGMACAM_FLAG_BINSKIP_SUPPORTED"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_USB30) + { + CONSOLE_DEBUG("OGMACAM_FLAG_USB30"); + cIsUSB3Camera = true; + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_TEC) + { + CONSOLE_DEBUG("OGMACAM_FLAG_TEC"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_USB30_OVER_USB20) + { + CONSOLE_DEBUG("OGMACAM_FLAG_USB30_OVER_USB20"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_GETTEMPERATURE) + { + CONSOLE_DEBUG("OGMACAM_FLAG_GETTEMPERATURE"); + } +#ifdef OGMACAM_FLAG_PUTTEMPERATURE + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_PUTTEMPERATURE) + { + CONSOLE_DEBUG("OGMACAM_FLAG_PUTTEMPERATURE"); + } +#endif + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_FAN) + { + CONSOLE_DEBUG("OGMACAM_FLAG_FAN"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_TEC_ONOFF) + { + CONSOLE_DEBUG("OGMACAM_FLAG_TEC_ONOFF"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_ISP) + { + CONSOLE_DEBUG("OGMACAM_FLAG_ISP"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_TRIGGER_SOFTWARE) + { + CONSOLE_DEBUG("OGMACAM_FLAG_TRIGGER_SOFTWARE"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_TRIGGER_EXTERNAL) + { + CONSOLE_DEBUG("OGMACAM_FLAG_TRIGGER_EXTERNAL"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_TRIGGER_SINGLE) + { + CONSOLE_DEBUG("OGMACAM_FLAG_TRIGGER_SINGLE"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_BLACKLEVEL) + { + CONSOLE_DEBUG("OGMACAM_FLAG_BLACKLEVEL"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_AUTO_FOCUS) + { + CONSOLE_DEBUG("OGMACAM_FLAG_AUTO_FOCUS"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_BUFFER) + { + CONSOLE_DEBUG("OGMACAM_FLAG_BUFFER"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_DDR) + { + CONSOLE_DEBUG("OGMACAM_FLAG_DDR"); + } + + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_CG) + { + CONSOLE_DEBUG("OGMACAM_FLAG_CG"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_YUV411) + { + CONSOLE_DEBUG("OGMACAM_FLAG_YUV411"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_VUYY) + { + CONSOLE_DEBUG("OGMACAM_FLAG_VUYY"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_YUV444) + { + CONSOLE_DEBUG("OGMACAM_FLAG_YUV444"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_RGB888) + { + CONSOLE_DEBUG("OGMACAM_FLAG_RGB888"); + AddReadoutModeToList(kImageType_RGB24); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_GMCY8) + { + CONSOLE_DEBUG("OGMACAM_FLAG_GMCY8"); + AddReadoutModeToList(kImageType_Y8); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_GMCY12) + { + CONSOLE_DEBUG("OGMACAM_FLAG_GMCY12"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_UYVY) + { + CONSOLE_DEBUG("OGMACAM_FLAG_UYVY"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_CGHDR) + { + CONSOLE_DEBUG("OGMACAM_FLAG_CGHDR"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_GLOBALSHUTTER) + { + CONSOLE_DEBUG("OGMACAM_FLAG_GLOBALSHUTTER"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_FOCUSMOTOR) + { + CONSOLE_DEBUG("OGMACAM_FLAG_FOCUSMOTOR"); + } + if (cOGMAdeviceInfo.model->flag & OGMACAM_FLAG_PRECISE_FRAMERATE) + { + CONSOLE_DEBUG("OGMACAM_FLAG_PRECISE_FRAMERATE"); + } + } +} + +//***************************************************************************** +//* the camera must already be open when this is called +//***************************************************************************** +bool CameraDriverOGMA::GetImage_ROI_info(void) +{ + +// memset(&cROIinfo, 0, sizeof(TYPE_IMAGE_ROI_Info)); + +// cROIinfo.currentROIimageType = kImageType_RAW8; // PDB kImageType_RGB24; + cROIinfo.currentROIwidth = cCameraProp.CameraXsize; + cROIinfo.currentROIheight = cCameraProp.CameraYsize; + cROIinfo.currentROIbin = 1; + + return(true); +} + + +//***************************************************************************** +//* http://192.168.0.201:6800/api/v1.0.0-oas3/camera/0/startexposure Content-Type: -dDuration=0.001&Light=true +//***************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Start_CameraExposure(int32_t exposureMicrosecs, const bool lightFrame) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; +HRESULT ogmaResult; + + //* this camera is a bit different, it is ALWAYS exposing, + //* istrigger + + cInternalCameraState = kCameraState_TakingPicture; + alpacaErrCode = kASCOM_Err_Success; + + gettimeofday(&cCameraProp.Lastexposure_StartTime, NULL); + + // Still to add some error checking --PDB-- + Ogmacam_put_ExpoTime(cOGMAcamH, exposureMicrosecs); + + // Trigger an exposure if triggercam + + // Still to add some error checking --PDB-- + if (cIsTriggerCam == true) + { + ogmaResult = Ogmacam_Trigger(cOGMAcamH, 1); + if (FAILED(ogmaResult)) + { + CONSOLE_DEBUG_W_NUM("Ogmacam_Trigger() returned error code:", ogmaResult); + } + } + + return(alpacaErrCode); +} + +//***************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Stop_Exposure(void) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; + +// CONSOLE_DEBUG(__FUNCTION__); + strcpy(cLastCameraErrMsg, "Not finished-"); + strcat(cLastCameraErrMsg, __FILE__); + strcat(cLastCameraErrMsg, ":"); + strcat(cLastCameraErrMsg, __FUNCTION__); + + CONSOLE_DEBUG(cLastCameraErrMsg); + + alpacaErrCode = kASCOM_Err_Success; + + return(alpacaErrCode); +} + + +//***************************************************************************** +TYPE_EXPOSURE_STATUS CameraDriverOGMA::Check_Exposure(bool verboseFlag) +{ +TYPE_EXPOSURE_STATUS exposureState; + + CONSOLE_DEBUG_W_STR("cInternalCameraState\t=", gCameraStateStrings[cInternalCameraState]); + switch(cInternalCameraState) + { + case kCameraState_Idle: + exposureState = kExposure_Idle; + break; + + case kCameraState_TakingPicture: + if (cOGMApicReady) + { + exposureState = kExposure_Success; + cOGMApicReady = false; + } + else + { + exposureState = kExposure_Working; + } + break; + + case kCameraState_StartVideo: + exposureState = kExposure_Idle; + break; + + case kCameraState_TakingVideo: + exposureState = kExposure_Idle; + break; + + default: + exposureState = kExposure_Idle; + break; + } + return(exposureState); +} + +//***************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::SetImageType(TYPE_IMAGE_TYPE newImageType) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; +int ogma_bitDepth; +int ofma_pixelFormat; +int rgbMode; +HRESULT ogmaResult; + + CONSOLE_DEBUG(__FUNCTION__); + if (cOGMAcamH != NULL) + { + ogma_bitDepth = -1; + ogmaResult = Ogmacam_get_Option(cOGMAcamH, OGMACAM_OPTION_BITDEPTH, &ogma_bitDepth); + if (SUCCEEDED(ogmaResult)) + { + CONSOLE_DEBUG_W_NUM("ogma_bitDepth (0 = 8 bits mode, 1 = 16 bits mode)\t=", ogma_bitDepth); +#define OGMACAM_PIXELFORMAT_RAW8 0x00 +#define OGMACAM_PIXELFORMAT_RAW10 0x01 +#define OGMACAM_PIXELFORMAT_RAW12 0x02 +#define OGMACAM_PIXELFORMAT_RAW14 0x03 +#define OGMACAM_PIXELFORMAT_RAW16 0x04 +#define OGMACAM_PIXELFORMAT_YUV411 0x05 +#define OGMACAM_PIXELFORMAT_VUYY 0x06 +#define OGMACAM_PIXELFORMAT_YUV444 0x07 +#define OGMACAM_PIXELFORMAT_RGB888 0x08 + switch(newImageType) + { + case kImageType_RAW8: + case kImageType_Y8: + ogma_bitDepth = 0; + ofma_pixelFormat = OGMACAM_PIXELFORMAT_RAW8; + break; + + case kImageType_RGB24: + ogma_bitDepth = 0; + ofma_pixelFormat = OGMACAM_PIXELFORMAT_RGB888; + break; + + case kImageType_RAW16: + ogma_bitDepth = 1; + ofma_pixelFormat = OGMACAM_PIXELFORMAT_RAW16; + break; + + default: + ogma_bitDepth = 0; + ofma_pixelFormat = OGMACAM_PIXELFORMAT_RAW8; + break; + } + //-------------------------------------------------------------------------------------- + //* set bit depth + ogmaResult = Ogmacam_put_Option(cOGMAcamH, OGMACAM_OPTION_BITDEPTH, ogma_bitDepth); + if (SUCCEEDED(ogmaResult)) + { + cROIinfo.currentROIimageType = newImageType; + cDesiredImageType = newImageType; + alpacaErrCode = kASCOM_Err_Success; + } + else + { + CONSOLE_DEBUG_W_HEX("Ogmacam_put_Option failed, ogmaResult\t=", ogmaResult); + } + ogmaResult = Ogmacam_get_Option(cOGMAcamH, OGMACAM_OPTION_BITDEPTH, &ogma_bitDepth); + CONSOLE_DEBUG_W_NUM("bitDepth (0 = 8 bits mode, 1 = 16 bits mode)\t=", ogma_bitDepth); + + ogmaResult = Ogmacam_get_Option(cOGMAcamH, OGMACAM_OPTION_RGB, &rgbMode); + if (SUCCEEDED(ogmaResult)) + { + CONSOLE_DEBUG_W_NUM( "rgbMode\t=", rgbMode); + CONSOLE_DEBUG( " 0 => RGB24;"); + CONSOLE_DEBUG( " 1 => enable RGB48 format when bitdepth > 8;"); + CONSOLE_DEBUG( " 2 => RGB32;"); + CONSOLE_DEBUG( " 3 => 8 Bits Gray (only for mono camera"); + CONSOLE_DEBUG( " 4 => 16 Bits Gray (only for mono camera when bitdepth > 8)"); + CONSOLE_DEBUG( " 5 => 64(RGB64)"); + } + else + { + CONSOLE_DEBUG_W_HEX("Ogmacam_get_Option failed, ogmaResult\t=", ogmaResult); + } + //-------------------------------------------------------------------------------------- + //* set pixel format + ogmaResult = Ogmacam_put_Option(cOGMAcamH, OGMACAM_OPTION_PIXEL_FORMAT, ofma_pixelFormat); + if (SUCCEEDED(ogmaResult)) + { + + } + else + { + CONSOLE_DEBUG_W_HEX("OGMACAM_OPTION_PIXEL_FORMAT failed, ogmaResult\t=", ogmaResult); + } + + + } + else if ((unsigned int)ogmaResult == E_NOTIMPL) + { + alpacaErrCode = kASCOM_Err_NotImplemented; + strcpy(cLastCameraErrMsg, "Camera does not support specified pixel depth"); + } + else + { + alpacaErrCode = kASCOM_Err_FailedUnknown; + } + } + else + { + alpacaErrCode = kASCOM_Err_NotConnected; + } + + CONSOLE_DEBUG_W_NUM("alpacaErrCode\t=", alpacaErrCode); + return(alpacaErrCode); +} + +#pragma mark - +#pragma mark Virtual functions + +//***************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Read_Gain(int *cameraGainValue) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_Success; +unsigned short gain; +HRESULT ogmaResult; + +// CONSOLE_DEBUG(__FUNCTION__); + if (cOGMAcamH != NULL) + { +// CONSOLE_DEBUG("reading gain"); + ogmaResult = Ogmacam_get_ExpoAGain(cOGMAcamH, &gain); + if (SUCCEEDED(ogmaResult)) + { +// CONSOLE_DEBUG("found gain"); + *cameraGainValue = gain; + alpacaErrCode = kASCOM_Err_Success; + } + else + { + if ((unsigned int)ogmaResult == E_NOTIMPL) + { + alpacaErrCode = kASCOM_Err_NotImplemented; + strcpy(cLastCameraErrMsg, "Camera does not support gain"); + } + else + { + alpacaErrCode = kASCOM_Err_FailedUnknown; + } + } + } + else + { + alpacaErrCode = kASCOM_Err_NotConnected; + } +// CONSOLE_DEBUG(cLastCameraErrMsg); + return(alpacaErrCode); +} + + +//***************************************************************************** +// Set Cooling: +// int ArtemisSetCooling(ArtemisHandle hCam, int setpoint); +// This function is used to set the temperature of the camera. The setpoint is in 1/100 of a degree +// (Celcius). So, to set the cooling to -10C, you need to call the function with setpoint = -1000. +//***************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Cooler_TurnOn(void) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; + +// CONSOLE_DEBUG(__FUNCTION__); + strcpy(cLastCameraErrMsg, "Not finished-"); + strcat(cLastCameraErrMsg, __FILE__); + strcat(cLastCameraErrMsg, ":"); + strcat(cLastCameraErrMsg, __FUNCTION__); + + CONSOLE_DEBUG(cLastCameraErrMsg); + return(alpacaErrCode); +} + + +//***************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Cooler_TurnOff(void) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; + +// CONSOLE_DEBUG(__FUNCTION__); + + strcpy(cLastCameraErrMsg, "Not finished-"); + strcat(cLastCameraErrMsg, __FILE__); + strcat(cLastCameraErrMsg, ":"); + strcat(cLastCameraErrMsg, __FUNCTION__); + CONSOLE_DEBUG(cLastCameraErrMsg); + + return(alpacaErrCode); +} + + +//************************************************************************** +//* returns error code, +//* sets class varible to current temp +//************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Read_SensorTemp(void) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; +short temperature; +HRESULT ogmaResult; + +// CONSOLE_DEBUG(__FUNCTION__); + if (cOGMAcamH != NULL) + { + ogmaResult = Ogmacam_get_Temperature(cOGMAcamH, &temperature); + if (SUCCEEDED(ogmaResult)) + { + cCameraProp.CCDtemperature = (temperature * 1.0) / 10.0; + } + else if ((unsigned int)ogmaResult == E_NOTIMPL) + { + alpacaErrCode = kASCOM_Err_NotImplemented; + strcpy(cLastCameraErrMsg, "Camera does not support tempeature"); + } + else + { + alpacaErrCode = kASCOM_Err_FailedUnknown; + } + } + else + { + alpacaErrCode = kASCOM_Err_NotConnected; + } + + return(alpacaErrCode); +} + +//***************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Read_CoolerState(bool *coolerOnOff) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; + +// CONSOLE_DEBUG(__FUNCTION__); + strcpy(cLastCameraErrMsg, "Not finished-"); + strcat(cLastCameraErrMsg, __FILE__); + strcat(cLastCameraErrMsg, ":"); + strcat(cLastCameraErrMsg, __FUNCTION__); +// CONSOLE_DEBUG(cLastCameraErrMsg); + + return(alpacaErrCode); +} + +//***************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Read_CoolerPowerLevel(void) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; + +// CONSOLE_DEBUG(__FUNCTION__); + strcpy(cLastCameraErrMsg, "Not finished-"); + strcat(cLastCameraErrMsg, __FILE__); + strcat(cLastCameraErrMsg, ":"); + strcat(cLastCameraErrMsg, __FUNCTION__); + CONSOLE_DEBUG(cLastCameraErrMsg); + + return(alpacaErrCode); +} + + +//***************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Read_Fastreadout(void) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; + +// CONSOLE_DEBUG(__FUNCTION__); + + strcpy(cLastCameraErrMsg, "Not finished-"); + strcat(cLastCameraErrMsg, __FILE__); + strcat(cLastCameraErrMsg, ":"); + strcat(cLastCameraErrMsg, __FUNCTION__); +// CONSOLE_DEBUG(cLastCameraErrMsg); + return(alpacaErrCode); +} + +//************************************************************************** +TYPE_ASCOM_STATUS CameraDriverOGMA::Read_ImageData(void) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_Success; +//OgmacamFrameInfoV2 ogmaFrameInfo; + + CONSOLE_DEBUG(__FUNCTION__); + +// memset((void*)&ogmaFrameInfo, 0, sizeof(OgmacamFrameInfoV2)); + + GetImage_ROI_info(); + + if ((cOGMAcamH != NULL) && (cCameraDataBuffer != NULL)) + { + cNewImageReadyToDisplay = true; + cOGMApicReady = false; + } + else + { + CONSOLE_DEBUG("Invalid device number or camera buffer failed to allocate"); + } + return(alpacaErrCode); +} + +//************************************************************************** +void CameraDriverOGMA::HandleOGMAcallbackEvent(unsigned nEvent) +{ +OgmacamFrameInfoV2 ogmaFrameInfo; +HRESULT ogmaResult; + + memset((void*)&ogmaFrameInfo, 0, sizeof(OgmacamFrameInfoV2)); + + switch(nEvent) + { + case OGMACAM_EVENT_EXPOSURE: //* exposure time changed + CONSOLE_DEBUG("OGMACAM_EVENT_EXPOSURE"); + if (cOGMAcamH != NULL) + { + ogmaResult = Ogmacam_get_ExpoTime(cOGMAcamH, &cOGMAautoExpTime_us); //* in microseconds + if (SUCCEEDED(ogmaResult)) + { + CONSOLE_DEBUG_W_NUM("expTime_us\t=", cOGMAautoExpTime_us); + cCurrentExposure_us = cOGMAautoExpTime_us; + cCameraProp.Lastexposure_duration_us = cOGMAautoExpTime_us; + } + else + { + CONSOLE_DEBUG_W_HEX("Ogmacam_get_ExpoTime() failed, ogmaResult = ", ogmaResult); + } + } + break; + + case OGMACAM_EVENT_TEMPTINT: //* white balance changed, Temp/Tint mode + CONSOLE_DEBUG_W_NUM(__FUNCTION__, nEvent); + break; + + case OGMACAM_EVENT_IMAGE: //* live image arrived, use Toupcam_PullImage to get this image +// CONSOLE_DEBUG("OGMACAM_EVENT_IMAGE"); +// Think it is better move this code out of the call back function +// Probable better place is read_imagedata function, but then some +// indicator should be set here that read_imageda should handle the pull_image +// +// PDB + + if ((cOGMAcamH != NULL) && (cCameraDataBuffer != NULL)) + { + //* we do not want to read the image if an image save is in progress + + // Hardcoded 16bit for now. Must be changed to the proper value based on camerasetting + // To be done -PDB- + ogmaResult = Ogmacam_PullImageV2(cOGMAcamH, cCameraDataBuffer, 16, &ogmaFrameInfo); + if (SUCCEEDED(ogmaResult)) + { + // CONSOLE_DEBUG_W_HEX("ogmaFrameInfo.flag\t\t=", ogmaFrameInfo.flag); + // CONSOLE_DEBUG_W_NUM("ogmaFrameInfo.timestamp\t=", ogmaFrameInfo.timestamp); + if (cCameraAutoExposure) + { + cCurrentExposure_us = cOGMAautoExpTime_us; + cCameraProp.Lastexposure_duration_us = cOGMAautoExpTime_us; + } + + cNewImageReadyToDisplay = true; + if (cInternalCameraState == kCameraState_TakingPicture) + { + cOGMApicReady = true; + } + //* get the frame rate: framerate (fps) = Frame * 1000.0 / nTime + unsigned nFrame; + unsigned nTime; + unsigned nTotalFrame; + // double myFrameRate; + ogmaResult = Ogmacam_get_FrameRate(cOGMAcamH, &nFrame, &nTime, &nTotalFrame); + if (SUCCEEDED(ogmaResult)) + { + // myFrameRate = (nFrame * 1000.0) / nTime; + // CONSOLE_DEBUG_W_NUM("nFrame\t=", nFrame); + // CONSOLE_DEBUG_W_NUM("nTime\t\t=", nTime); + // CONSOLE_DEBUG_W_NUM("nTotalFrame\t=", nTotalFrame); +// CONSOLE_DEBUG_W_DBL("myFrameRate\t=", myFrameRate); + } + } + else + { + CONSOLE_DEBUG_W_HEX("failed to pull image, ogmaResult = ", ogmaResult); + } + } + else + { + CONSOLE_DEBUG("Internal error"); + CONSOLE_ABORT(__FUNCTION__); + } + break; + + case OGMACAM_EVENT_STILLIMAGE: //* snap (still) frame arrived, use Toupcam_PullStillImage to get this frame + case OGMACAM_EVENT_WBGAIN: //* white balance changed, RGB Gain mode + case OGMACAM_EVENT_TRIGGERFAIL: //* trigger failed + case OGMACAM_EVENT_BLACK : //* black balance changed + case OGMACAM_EVENT_FFC: //* flat field correction status changed + case OGMACAM_EVENT_DFC: //* dark field correction status changed + case OGMACAM_EVENT_ROI: //* roi changed + case OGMACAM_EVENT_ERROR: //* generic error + case OGMACAM_EVENT_DISCONNECTED: //* camera disconnected + case OGMACAM_EVENT_NOFRAMETIMEOUT: //* no frame timeout error +// case OGMACAM_EVENT_AFFEEDBACK: //* auto focus feedback information +// case OGMACAM_EVENT_AFPOSITION: //* auto focus sensor board position + case OGMACAM_EVENT_NOPACKETTIMEOUT: //* no packet timeout + case OGMACAM_EVENT_FACTORY: //* restore factory settings + + default: + CONSOLE_DEBUG_W_NUM(__FUNCTION__, nEvent); + break; + } +} + + + + +#endif // defined(_ENABLE_CAMERA_) && defined(_ENABLE_OGMA_) + diff --git a/src/cameradriver_OGMA.h b/src/cameradriver_OGMA.h new file mode 100644 index 0000000..8c6bcb2 --- /dev/null +++ b/src/cameradriver_OGMA.h @@ -0,0 +1,83 @@ +//************************************************************************** +//* Name: cameradriver_OGMA.h +//* +//* Author: Mark Sproul +//* +//***************************************************************************** +//* Edit History +//***************************************************************************** +//* = Mark L Sproul +//***************************************************************************** +//* Apr 24, 2024 Created cameradriver_OGMA.cpp +//***************************************************************************** +//#include "cameradriver_OGMA.h" + + +#ifndef _CAMERA_DRIVER_OGMA_H_ +#define _CAMERA_DRIVER_OGMA_H_ + +#ifndef _CAMERA_DRIVER_H_ + #include "cameradriver.h" +#endif + +#ifndef __ogmacam_h__ + #include "../OGMAcamSDK/inc/ogmacam.h" +#endif + +int CreateCameraObjects_OGMA(void); + + +//************************************************************************************** +class CameraDriverOGMA: public CameraDriver +{ + public: + + // + // Construction + // + CameraDriverOGMA(const int deviceNum); + virtual ~CameraDriverOGMA(void); + + + //***************************************************************************** + //* Camera specific routines + virtual TYPE_ASCOM_STATUS Start_CameraExposure(int32_t exposureMicrosecs, const bool lightFrame=true); + virtual TYPE_ASCOM_STATUS Stop_Exposure(void); + virtual TYPE_EXPOSURE_STATUS Check_Exposure(bool verboseFlag = false); + virtual TYPE_ASCOM_STATUS SetImageType(TYPE_IMAGE_TYPE newImageType); + + virtual bool GetImage_ROI_info(void); + + virtual TYPE_ASCOM_STATUS Cooler_TurnOn(void); + virtual TYPE_ASCOM_STATUS Cooler_TurnOff(void); + virtual TYPE_ASCOM_STATUS Read_Gain(int *cameraGainValue); + virtual TYPE_ASCOM_STATUS Read_SensorTemp(void); + virtual TYPE_ASCOM_STATUS Read_CoolerState(bool *coolerOnOff); + virtual TYPE_ASCOM_STATUS Read_CoolerPowerLevel(void); + virtual TYPE_ASCOM_STATUS Read_Fastreadout(void); + virtual TYPE_ASCOM_STATUS Read_ImageData(void); + + + void HandleOGMAcallbackEvent(unsigned nEvent); + + + protected: + void ReadCameraInfo(void); + + + OgmacamDeviceV2 cOGMAdeviceInfo; + HOgmacam cOGMAcamH; + bool cOGMApicReady; + unsigned int cOGMAautoExpTime_us; + + unsigned int cOGMAcamFormat; + + bool cIsTriggerCam; +}; + + + +#endif // _CAMERA_DRIVER_OGMA_H_ + + + diff --git a/src/cameradriver_QSI.cpp b/src/cameradriver_QSI.cpp index 45b19c7..998421b 100644 --- a/src/cameradriver_QSI.cpp +++ b/src/cameradriver_QSI.cpp @@ -66,7 +66,7 @@ #define _ENABLE_CAMERA_SIMULATOR_ //************************************************************************************** -int CreateQSI_CameraObjects(void) +int CreateCameraObjects_QSI(void) { int cameraCreatedCount; unsigned int qsi_Result; diff --git a/src/cameradriver_QSI.h b/src/cameradriver_QSI.h index 5af47fa..7df0881 100644 --- a/src/cameradriver_QSI.h +++ b/src/cameradriver_QSI.h @@ -35,7 +35,7 @@ #include "qsiapi.h" #endif -int CreateQSI_CameraObjects(void); +int CreateCameraObjects_QSI(void); //************************************************************************************** diff --git a/src/cameradriver_SONY.cpp b/src/cameradriver_SONY.cpp index 6416695..c69fc20 100755 --- a/src/cameradriver_SONY.cpp +++ b/src/cameradriver_SONY.cpp @@ -115,7 +115,7 @@ void LogFunctionCall( const char *callingFunc, //***************************************************************************** -int CreateSONY_CameraObjects(void) +int CreateCameraObjects_SONY(void) { int cameraCreatedCount; CrInt32u versionNumber; @@ -2728,7 +2728,7 @@ struct sigaction signalAction; sigaction(SIGSEGV, &signalAction, NULL); - CreateSONY_CameraObjects(); + CreateCameraObjects_SONY(); if (gSonyCameraObj != NULL) { diff --git a/src/cameradriver_SONY.h b/src/cameradriver_SONY.h index 01c09de..649256d 100755 --- a/src/cameradriver_SONY.h +++ b/src/cameradriver_SONY.h @@ -36,7 +36,7 @@ #include "IDeviceCallback.h" #endif -int CreateSONY_CameraObjects(void); +int CreateCameraObjects_SONY(void); #ifndef _CAMERA_DRIVER_H_ diff --git a/src/cameradriver_TOUP.cpp b/src/cameradriver_TOUP.cpp index 2600c8b..413cc6b 100755 --- a/src/cameradriver_TOUP.cpp +++ b/src/cameradriver_TOUP.cpp @@ -97,7 +97,7 @@ //************************************************************************************** -int CreateTOUP_CameraObjects(void) +int CreateCameraObjects_TOUP(void) { int cameraCount; int ii; diff --git a/src/cameradriver_TOUP.h b/src/cameradriver_TOUP.h index 3a00a45..ab87518 100755 --- a/src/cameradriver_TOUP.h +++ b/src/cameradriver_TOUP.h @@ -25,7 +25,7 @@ #include "toupcam.h" #endif -int CreateTOUP_CameraObjects(void); +int CreateCameraObjects_TOUP(void); //************************************************************************************** diff --git a/src/cameradriver_fits.cpp b/src/cameradriver_fits.cpp index d3a5625..e0385fa 100644 --- a/src/cameradriver_fits.cpp +++ b/src/cameradriver_fits.cpp @@ -102,6 +102,8 @@ //* Mar 25, 2024 Now using NASA Moon Phase info if available //* Mar 27, 2024 Added lunar polar axis to moon fits info //* Apr 10, 2024 FITS data now supports GPS from serial port +//* Apr 18, 2024 Added filter wheel serial number to fits output if it exists +//* Apr 22, 2024 Added support for kImageType_MONO8 (8 bit image type) //***************************************************************************** #if defined(_ENABLE_CAMERA_) && defined(_ENABLE_FITS_) @@ -246,6 +248,8 @@ void GetImageTypeString(TYPE_IMAGE_TYPE imageType, char *imageTypeString) case kImageType_RAW16: strcpy(imageTypeString, "RAW16"); break; case kImageType_RGB24: strcpy(imageTypeString, "RGB24"); break; case kImageType_Y8: strcpy(imageTypeString, "Y8"); break; + case kImageType_MONO8: strcpy(imageTypeString, "MONO8"); break; + default: strcpy(imageTypeString, "unknown"); break; } } @@ -440,6 +444,7 @@ int iii; switch(cROIinfo.currentROIimageType) { case kImageType_RAW8: + case kImageType_MONO8: // CONSOLE_DEBUG("kImageType_RAW8"); fits_bitpix = BYTE_IMG; fitsDataType = TBYTE; @@ -636,6 +641,7 @@ int iii; { case kImageType_RAW8: case kImageType_RAW16: + case kImageType_MONO8: fitsRetCode = fits_write_pix( fitsFilePtr, fitsDataType, fpixelArray, @@ -1359,6 +1365,14 @@ int fitsStatus; "Filter wheel used", &fitsStatus); } + //---------------------------------------------------------------------- + if (strlen(cConnectedFilterWheel->cDeviceSerialNum) > 0) + { + fitsStatus = 0; + fits_write_key(fitsFilePtr, TSTRING, "COMMENT", + cConnectedFilterWheel->cDeviceSerialNum, + "Serial Number", &fitsStatus); + } fwAlpacaErr = cConnectedFilterWheel->Read_CurrentFilterPositon(&filterPosition); if (fwAlpacaErr == kASCOM_Err_Success) @@ -1714,19 +1728,6 @@ struct tm myLocalTime; stringBuf, "Local Sidereal Time start of exposure", &fitsStatus); - modifiedJulianDate = Julian_CalcMJD(&cCameraProp.Lastexposure_StartTime); - fitsStatus = 0; - fits_write_key(fitsFilePtr, TDOUBLE, "MJD-OBS", - &modifiedJulianDate, - "MJD of observation", &fitsStatus); - if (cCameraProp.Lastexposure_EndTime.tv_sec > cCameraProp.Lastexposure_StartTime.tv_sec) - { - modifiedJulianDate = Julian_CalcMJD(&cCameraProp.Lastexposure_EndTime); - fitsStatus = 0; - fits_write_key(fitsFilePtr, TDOUBLE, "MJDEND", - &modifiedJulianDate, - "MJD at end of exposure", &fitsStatus); - } //============================================================== //* include the local time as well localTime = localtime(&cCameraProp.Lastexposure_StartTime.tv_sec); @@ -1746,6 +1747,19 @@ struct tm myLocalTime; "Time Zone", &fitsStatus); + //============================================================== + modifiedJulianDate = Julian_CalcMJD(&cCameraProp.Lastexposure_StartTime); + fitsStatus = 0; + fits_write_key(fitsFilePtr, TDOUBLE, "MJD-OBS", + &modifiedJulianDate, + "MJD of observation", &fitsStatus); + + modifiedJulianDate = Julian_CalcMJD(&cCameraProp.Lastexposure_EndTime); + fitsStatus = 0; + fits_write_key(fitsFilePtr, TDOUBLE, "MJDEND", + &modifiedJulianDate, + "MJD at end of exposure", &fitsStatus); + //============================================================== fitsStatus = 0; exposureTime_Secs = (cCameraProp.Lastexposure_duration_us * 1.0) / 1000000.0; @@ -1910,7 +1924,7 @@ void CameraDriver::WriteFITS_RotatorInfo(fitsfile *fitsFilePtr) //* model cConnectedRotator->GetRotatorModel(dataBuff); - if (strlen(lineBuff) > 0) + if (strlen(dataBuff) > 0) { strcpy(lineBuff, "Rotator Model: "); strcat(lineBuff, dataBuff); @@ -1922,7 +1936,7 @@ void CameraDriver::WriteFITS_RotatorInfo(fitsfile *fitsFilePtr) //* serial number cConnectedRotator->GetRotatorSerialNumber(dataBuff); - if (strlen(lineBuff) > 0) + if (strlen(dataBuff) > 0) { strcpy(lineBuff, "Rotator Serial Number: "); strcat(lineBuff, dataBuff); @@ -2304,7 +2318,7 @@ TYPE_MoonPhase moonPhaseInfo; (char *)"Calculated WRT UTC time and location (Greenwich, UK)", NULL, &fitsStatus); fitsStatus = 0; - fits_write_key(fitsFilePtr, TSTRING, "COMMENT", + fits_write_key(fitsFilePtr, TSTRING, "MOONDATE", timeString, NULL, &fitsStatus); diff --git a/src/cameradriver_gps.cpp b/src/cameradriver_gps.cpp index a33323b..1b3224a 100644 --- a/src/cameradriver_gps.cpp +++ b/src/cameradriver_gps.cpp @@ -75,20 +75,25 @@ //***************************************************************************** //* does not write anything if no GPS present //* QHY GPS takes priority over global GPS +//***************************************************************************** void CameraDriver::WriteFITS_GPSinfo(fitsfile *fitsFilePtr) { if (cGPS.Present) { WriteFITS_QHY_GPSinfo(fitsFilePtr); } +#ifdef _ENABLE_GLOBAL_GPS_ else if (gNMEAdata.SequenceNumber > 0) { WriteFITS_Global_GPSinfo(fitsFilePtr); } +#endif } + +#ifndef _ENABLE_GLOBAL_GPS_ //***************************************************************************** -static void GetGPSmodeString(char gpsMode1, char gpsMode2, char *modeString) +void GetGPSmodeString(char gpsMode1, char gpsMode2, char *modeString) { modeString[0] = 0; switch (gpsMode1) @@ -106,7 +111,58 @@ static void GetGPSmodeString(char gpsMode1, char gpsMode2, char *modeString) default: strcat(modeString, "Unknown: "); break; } } +//************************************************************************************** +void ParseNMEA_FormatLatLonStrings(double latValue, char *latString, double lonValue, char *lonString) +{ +int degrees; +int minutes; +double seconds; +char signChar; +double myLatLonValue; +int myLatLonValueMinutes; + + //* first do the lat + if (latValue < 0) + { + signChar = 'S'; + myLatLonValue = -latValue; + } + else + { + signChar = 'N'; + myLatLonValue = latValue; + } + degrees = myLatLonValue; + myLatLonValueMinutes = myLatLonValue * 60; + minutes = myLatLonValueMinutes % 60; + seconds = (myLatLonValue * 3600) - (degrees * 3600) - (minutes * 60); + + sprintf(latString, "%03d:%02d:%05.3f %c", degrees, minutes, seconds, signChar); +// CONSOLE_DEBUG_W_STR("latString\t=", latString); + + //* now do the lon + if (lonValue < 0) + { + signChar = 'W'; + myLatLonValue = -lonValue; + } + else + { + signChar = 'E'; + myLatLonValue = lonValue; + } + degrees = myLatLonValue; + myLatLonValueMinutes = myLatLonValue * 60; + minutes = myLatLonValueMinutes % 60; + seconds = (myLatLonValue * 3600) - (degrees * 3600) - (minutes * 60); + + sprintf(lonString, "%03d:%02d:%05.3f %c", degrees, minutes, seconds, signChar); +// CONSOLE_DEBUG_W_STR("lonString\t=", lonString); +} +#endif // _ENABLE_GLOBAL_GPS_ + +#ifdef _ENABLE_GLOBAL_GPS_ //***************************************************************************** void CameraDriver::WriteFITS_Global_GPSinfo(fitsfile *fitsFilePtr) @@ -260,6 +316,7 @@ char tempstring[100]; //$GPGSV,3,2,11,13,29,048,14,05,22,093,16,10,17,289,16,27,13,313,16*72 //$GPGSV,3,3,11,29,09,200,14,32,02,233,14,37,,,*7C //$GPRMC,023427.000,A,4121.6634,N,07458.8293,W,0.24,70.83,110424,,,A*4B +#endif // _ENABLE_GLOBAL_GPS_ diff --git a/src/cameradriver_readthread.cpp b/src/cameradriver_readthread.cpp index c92a638..8a018da 100644 --- a/src/cameradriver_readthread.cpp +++ b/src/cameradriver_readthread.cpp @@ -24,6 +24,7 @@ //***************************************************************************** //* Sep 9, 2023 Created cameradriver_readthread.cpp //* Sep 23, 2023 Moved camera temp logging to CameraDriver::RunThread_Loop() +//* Apr 22, 2024 Added RunThread_CheckPictureStatus() //***************************************************************************** #ifdef _ENABLE_CAMERA_ @@ -58,7 +59,7 @@ void CameraDriver::RunThread_Loop(void) time_t deltaSeconds; time_t currentSeconds; - CONSOLE_DEBUG_W_STR(__FUNCTION__, "Camera"); +// CONSOLE_DEBUG_W_STR(__FUNCTION__, "Camera"); switch(cInternalCameraState) { case kCameraState_Idle: @@ -66,6 +67,7 @@ time_t currentSeconds; break; case kCameraState_TakingPicture: + RunThread_CheckPictureStatus(); break; case kCameraState_StartVideo: @@ -101,8 +103,17 @@ time_t currentSeconds; usleep(25000); } - +//***************************************************************************** +void CameraDriver::RunThread_CheckPictureStatus(void) +{ +// CONSOLE_DEBUG(__FUNCTION__); +} #endif // _USE_CAMERA_READ_THREAD_ #endif // _ENABLE_CAMERA_ + + + + + diff --git a/src/cameradriver_save.cpp b/src/cameradriver_save.cpp index 1d33647..aa57746 100755 --- a/src/cameradriver_save.cpp +++ b/src/cameradriver_save.cpp @@ -230,6 +230,7 @@ int imageDataLen; switch(cROIinfo.currentROIimageType) { case kImageType_RAW8: + case kImageType_MONO8: CONSOLE_DEBUG("kImageType_RAW8"); // 9/20/2022 //cOpenCV_ImagePtr = new cv::Mat(height, width, CV_8UC3); @@ -428,10 +429,10 @@ int openCVimageWidth; int bytesPerPixel; int bytesPerPixel2; //* calculated 2 different ways + CONSOLE_DEBUG(__FUNCTION__); SETUP_TIMING(); -// CONSOLE_DEBUG(__FUNCTION__); GenerateFileNameRoot(); if (cOpenCV_ImagePtr != NULL) diff --git a/src/cameradriver_sim.cpp b/src/cameradriver_sim.cpp index bff99e0..6ea4ad8 100644 --- a/src/cameradriver_sim.cpp +++ b/src/cameradriver_sim.cpp @@ -368,6 +368,10 @@ TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_Success; cROIinfo.currentROIimageType = kImageType_Y8; break; + case kImageType_MONO8: + cROIinfo.currentROIimageType = kImageType_MONO8; + break; + case kImageType_Invalid: case kImageType_last: break; diff --git a/src/cameradriver_sim.h b/src/cameradriver_sim.h index 39c5f28..4c1ee1b 100644 --- a/src/cameradriver_sim.h +++ b/src/cameradriver_sim.h @@ -76,7 +76,7 @@ class CameraDriverSIM: public CameraDriver // virtual TYPE_ASCOM_STATUS Stop_Video(void); // virtual TYPE_ASCOM_STATUS Take_Video(void); // -// virtual TYPE_ASCOM_STATUS SetFlipMode(int newFlipMode); +// virtual TYPE_ASCOM_STATUS SetFlipMode(const int newFlipMode); // // virtual TYPE_ALPACA_CAMERASTATE Read_AlapcaCameraState(void); // diff --git a/src/controller_image.cpp b/src/controller_image.cpp index 2635ca9..641dc66 100755 --- a/src/controller_image.cpp +++ b/src/controller_image.cpp @@ -1659,10 +1659,12 @@ void ControllerImage::ProcessFitsHeader(const char *imageFilePath) fitsfile *fptr; char card[FLEN_CARD]; char valueString[FLEN_CARD]; +char statusString[64]; int status; int nkeys; int iii; int fitsKeyWordEnum; +double ccdTemperature; // CONSOLE_DEBUG(__FUNCTION__); // CONSOLE_DEBUG_W_STR(__FUNCTION__, imageFilePath); @@ -1706,8 +1708,11 @@ int fitsKeyWordEnum; case kFitsKeyword_CCDTEMP: GetDataFromFitsLine(card, valueString); - strcat(valueString, " deg C"); - SetWidgetText( kTab_Image, kImageDisplay_CameraTemp, valueString); + ccdTemperature = atof(valueString); + sprintf(statusString, "%3.1f deg C", ccdTemperature); + CONSOLE_DEBUG_W_DBL("ccdTemperature\t=", ccdTemperature); + CONSOLE_DEBUG_W_STR("statusString \t=", statusString); + SetWidgetText( kTab_Image, kImageDisplay_CameraTemp, statusString); break; case kFitsKeyword_Date: @@ -1715,6 +1720,7 @@ int fitsKeyWordEnum; case kFitsKeyword_EXPTIME: GetDataFromFitsLine(card, valueString); + cFitsHeaderData.Exposure_Secs = atof(valueString); SetWidgetText( kTab_Image, kImageDisplay_Exposure, valueString); break; @@ -1917,6 +1923,13 @@ char theString[128]; DrawTextString2(xxLoc1, xxLoc2, yyLoc, "Camera:", cFitsHeaderData.Camera); yyLoc += cDeltaYloc; } + if (cFitsHeaderData.Exposure_Secs > 0.0) + { + sprintf(theString, "%3.6f seconds", cFitsHeaderData.Exposure_Secs); + DrawTextString2(xxLoc1, xxLoc2, yyLoc, "Exposure:", theString); + yyLoc += cDeltaYloc; + } + if (strlen(cFitsHeaderData.Filter) > 0) { if (strcasecmp(cFitsHeaderData.Filter, "None") != 0) diff --git a/src/controller_image.h b/src/controller_image.h index 280df8f..e77e5bc 100755 --- a/src/controller_image.h +++ b/src/controller_image.h @@ -42,6 +42,7 @@ typedef struct { double ApertureDiam; char Camera[64]; + double Exposure_Secs; char Date[64]; char Filter[64]; double FocalLength; diff --git a/src/domedriver.cpp b/src/domedriver.cpp index 0a3d449..632481d 100755 --- a/src/domedriver.cpp +++ b/src/domedriver.cpp @@ -2547,7 +2547,7 @@ const char domeTitle[] = "AlpacaPi Dome Driver setup"; SocketWriteData(mySocketFD, gHtmlHeader); SocketWriteData(mySocketFD, "\r\n"); - SocketWriteData(mySocketFD, "\r\n"); + SocketWriteData(mySocketFD, "\r\n"); sprintf(lineBuff, "%s\r\n", domeTitle); SocketWriteData(mySocketFD, lineBuff); SocketWriteData(mySocketFD, "
    \r\n"); diff --git a/src/eventlogging.c b/src/eventlogging.c index e11ff62..e000d08 100755 --- a/src/eventlogging.c +++ b/src/eventlogging.c @@ -157,7 +157,8 @@ const char gHtmlHeaderLog[] = "Connection: close\r\n" "\r\n" "\r\n" - "\r\n" + "\r\n" + "\r\n" }; diff --git a/src/filterwheeldriver.cpp b/src/filterwheeldriver.cpp index 8cc5062..5f10283 100755 --- a/src/filterwheeldriver.cpp +++ b/src/filterwheeldriver.cpp @@ -69,6 +69,9 @@ #ifdef _ENABLE_FILTERWHEEL_ATIK_ #include "filterwheeldriver_ATIK.h" #endif +#ifdef _ENABLE_FILTERWHEEL_PLAYERONE_ + #include "filterwheeldriver_Play1.h" +#endif #ifdef _ENABLE_FILTERWHEEL_QHY_ #include "filterwheeldriver_QHY.h" #endif @@ -92,6 +95,10 @@ void CreateFilterWheelObjects(void) CreateFilterWheelObjects_ATIK(); #endif +#ifdef _ENABLE_FILTERWHEEL_PLAYERONE_ + CreateFilterWheelObjects_PlayerOne(); +#endif + #ifdef _ENABLE_FILTERWHEEL_QHY_ CreateFilterWheelObjects_QHY(); #endif @@ -536,8 +543,8 @@ bool positionFound; char poisitonString[32]; char commentString[128]; - CONSOLE_DEBUG_W_STR("contentData\t=", reqData->contentData); - CONSOLE_DEBUG_W_NUM("max positions\t=", cNumberOfPositions); +// CONSOLE_DEBUG_W_STR("contentData\t=", reqData->contentData); +// CONSOLE_DEBUG_W_NUM("max positions\t=", cNumberOfPositions); positionFound = GetKeyWordArgument( reqData->contentData, "Position", diff --git a/src/filterwheeldriver.h b/src/filterwheeldriver.h index 6f29572..8558ba6 100755 --- a/src/filterwheeldriver.h +++ b/src/filterwheeldriver.h @@ -16,6 +16,9 @@ #ifndef _FILTERWHEELDRIVER_H_ #define _FILTERWHEELDRIVER_H_ +#ifndef _ALPACA_DEFS_H_ + #include "alpaca_defs.h" +#endif #ifndef _ALPACA_DRIVER_H_ #include "alpacadriver.h" #endif diff --git a/src/filterwheeldriver_Play1.cpp b/src/filterwheeldriver_Play1.cpp new file mode 100644 index 0000000..e9da298 --- /dev/null +++ b/src/filterwheeldriver_Play1.cpp @@ -0,0 +1,454 @@ +//************************************************************************** +//* Name: filterwheeldriver_Play1.cpp +//* +//* Author: Mark Sproul (C) 2024 +//* +//* Description: C++ Driver for Alpaca protocol +//* +//***************************************************************************** +//* AlpacaPi is an open source project written in C/C++ +//* +//* Use of this source code for private or individual use is granted +//* Use of this source code, in whole or in part for commercial purpose requires +//* written agreement in advance. +//* +//* You may use or modify this source code in any way you find useful, provided +//* that you agree that the author(s) have no warranty, obligations or liability. You +//* must determine the suitability of this source code for your use. +//* +//* Re-distributions of this source code must retain this copyright notice. +//***************************************************************************** +//* +//***************************************************************************** +//* Edit History +//***************************************************************************** +//* = Mark L Sproul +//***************************************************************************** +//* Apr 18, 2024 Borrowed Player-One filter wheel from Vanessa Zhang +//* Apr 18, 2024 Created filterwheeldriver_Play1.cpp +//* Apr 18, 2024 PlayerOne filterwheel working +//***************************************************************************** + +#ifdef _ENABLE_FILTERWHEEL_PLAYERONE_ + +#include +#include +#include +#include +#include +#include + +#include "eventlogging.h" + +#define _ENABLE_CONSOLE_DEBUG_ +#include "ConsoleDebug.h" + +#include "PlayerOnePW.h" + +#include "alpaca_defs.h" +#include "alpacadriver.h" +#include "alpacadriver_helper.h" +#include "filterwheeldriver.h" +#include "filterwheeldriver_Play1.h" + + +//************************************************************************************** +//************************************************************************************** +void CreateFilterWheelObjects_PlayerOne(void) +{ +int devNum; +int payerOneFilterWheelCount; +bool rulesOK; +char driverVersionString[64]; +int playerOneAPIversionNum; +char rulesFileName[] = "99-player_one_astronomy.rules"; + + CONSOLE_DEBUG(__FUNCTION__); + + playerOneAPIversionNum = POAGetPWAPIVer(); + CONSOLE_DEBUG_W_NUM("playerOneAPIversionNum\t=", playerOneAPIversionNum); + strcpy(driverVersionString, POAGetPWSDKVer()); + LogEvent( "filterwheel", + "Library version (PlayerOne)", + NULL, + kASCOM_Err_Success, + driverVersionString); + + AddLibraryVersion("camera", "PlayerOne", driverVersionString); + CONSOLE_DEBUG_W_STR("PlayerOne driver version:", driverVersionString); + + //* check to make sure the rules file is present + // /lib/udev/rules.d/99-atik.rules + rulesOK = Check_udev_rulesFile(rulesFileName); + if (rulesOK != true) + { + CONSOLE_DEBUG("Problem with ATIK rules"); + LogEvent( "filterwheel", + "Problem with ATIK rules", + NULL, + kASCOM_Err_Success, + rulesFileName); + } + + payerOneFilterWheelCount = POAGetPWCount(); + CONSOLE_DEBUG_W_NUM("payerOneFilterWheelCount\t=", payerOneFilterWheelCount); + for (devNum=0; devNum < payerOneFilterWheelCount; devNum++) + { + new FilterwheelPlayerOne(devNum); + } +} + + +//************************************************************************************** +FilterwheelPlayerOne::FilterwheelPlayerOne(const int argPlayerDeviceNumber) + :FilterwheelDriver(argPlayerDeviceNumber) +{ +bool rulesFileOK; +char rulesFileName[] = "99-player_one_astronomy.rules"; +int playerOneAPIversionNum; + + CONSOLE_DEBUG(__FUNCTION__); + cFilterWheelDevNum = argPlayerDeviceNumber; + cNumberOfPositions = 0; + cForceReadPosition = true; + cActualPosReadCout = 0; + cPWindex = argPlayerDeviceNumber; + + strcpy(cDeviceManufacturer, "PlayerOne"); +// strcpy(cDeviceManufAbrev, "PlayerOne"); +// strcpy(cDeviceVersion, "PlayerOne"); + playerOneAPIversionNum = POAGetPWAPIVer(); + sprintf(cDeviceFirmwareVersStr, "API Version#%d", playerOneAPIversionNum); + + strcpy(cCommonProp.Name, "PlayerOne Filterwheel"); //* put something there in case of failure to open + strcpy(cCommonProp.Description, "PlayerOne filterwheel"); + + rulesFileOK = Check_udev_rulesFile(rulesFileName); + if (rulesFileOK == false) + { + CONSOLE_DEBUG("PlayerOne Rules file does not appear to be installed properly"); + } + ReadFilterWheelInfo(); + + //* on startup we need to know the current position + Read_CurrentFilterPositon(NULL); //* we dont care about a return value +} + +//************************************************************************************** +// Destructor +//************************************************************************************** +FilterwheelPlayerOne::~FilterwheelPlayerOne(void) +{ + CONSOLE_DEBUG(__FUNCTION__); + +} + +//************************************************************************************** +//* this opens the connection +bool FilterwheelPlayerOne::AlpacaConnect(void) +{ + CONSOLE_DEBUG(__FUNCTION__); + + return(false); +} + +//************************************************************************************** +void FilterwheelPlayerOne::ReadFilterWheelInfo(void) +{ +PWErrors pwError; + + CONSOLE_DEBUG_W_NUM("cPWindex \t=", cPWindex); + pwError = POAGetPWProperties(cPWindex, &cPWProperties); + CONSOLE_DEBUG_W_NUM("pwError \t=", pwError); + if (pwError == PW_OK) + { + CONSOLE_DEBUG_W_STR("Name \t=", cPWProperties.Name); + CONSOLE_DEBUG_W_NUM("PositionCount\t=", cPWProperties.PositionCount); + CONSOLE_DEBUG_W_STR("Serial Number\t=", cPWProperties.SN); + + //* save the info where it belongs + cNumberOfPositions = cPWProperties.PositionCount; + strcpy(cDeviceModel, cPWProperties.Name); + strcpy(cCommonProp.Name, cPWProperties.Name); + strcpy(cDeviceSerialNum, cPWProperties.SN); + } + else + { + CONSOLE_DEBUG_W_NUM("POAGetPWProperties returned ", pwError); + CONSOLE_DEBUG(POAGetPWErrorString(pwError)); + CONSOLE_DEBUG_W_NUM("POAGetPWProperties() returned error\t=", pwError); + } + pwError = POAOpenPW(cPWProperties.Handle); + if (pwError == PW_OK) + { + CONSOLE_DEBUG("POAOpenPW() worked"); + } + else + { + CONSOLE_DEBUG_W_NUM("POAGetPWState returned ", pwError); + CONSOLE_DEBUG(POAGetPWErrorString(pwError)); + } + +// //------------------------------------------- +// //* get the various names +//char customName[64]; +//char aliasName[64]; +// pwError = POAGetPWCustomName(cPWProperties.Handle, customName, sizeof(customName)); +// CONSOLE_DEBUG_W_STR("customName\t=", customName); +// for (iii=0; iii< cNumberOfPositions; iii++) +// { +// pwError = POAGetPWFilterAlias(cPWProperties.Handle, iii, aliasName, sizeof(aliasName)); +// CONSOLE_DEBUG_W_STR("aliasName \t=", aliasName); +// } +} + +//***************************************************************************** +int FilterwheelPlayerOne::Read_CurrentFWstate(void) +{ + + return(kFilterWheelState_OK); +} + +//***************************************************************************** +//* this returns a position starting with 0 +//* return -1 if unable to determine position +//***************************************************************************** +TYPE_ASCOM_STATUS FilterwheelPlayerOne::Read_CurrentFilterPositon(int *rtnCurrentPosition) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_Success; +int currentPos = 0; +bool isMoving; +PWErrors pwError; + +// CONSOLE_DEBUG(__FUNCTION__); + + isMoving = false; + pwError = POAGetPWState(cPWProperties.Handle, &cPWstate); + if (pwError == PW_OK) + { + switch(cPWstate) + { + case PW_STATE_CLOSED: ///< PW was closed +// CONSOLE_DEBUG("State is closed"); + pwError = POAOpenPW(cPWProperties.Handle); + if (pwError == PW_OK) + { + CONSOLE_DEBUG("POAOpenPW() worked"); + } + else + { + CONSOLE_DEBUG_W_NUM("POAGetPWState returned ", pwError); + CONSOLE_DEBUG(POAGetPWErrorString(pwError)); + } + break; + + case PW_STATE_OPENED: ///< PW was opened, but not moving(Idle) +// CONSOLE_DEBUG("State is open"); + break; + + case PW_STATE_MOVING: ///< PW is moving + CONSOLE_DEBUG("PW_STATE_MOVING"); + isMoving = true; + break; + + } + //* alpaca specs say to do it this way, return -1 when moving + if (isMoving) + { + cFilterWheelProp.Position = -1; + alpacaErrCode = kASCOM_Err_Success; + } + else + { + currentPos = 0; + pwError = POAGetCurrentPosition(cPWProperties.Handle, ¤tPos); + if (pwError == PW_OK) + { + cFilterWheelProp.Position = currentPos; + alpacaErrCode = kASCOM_Err_Success; + } + } + //* if the caller wants the value returned + if (rtnCurrentPosition != NULL) + { + *rtnCurrentPosition = cFilterWheelProp.Position; + } + } + else + { + CONSOLE_DEBUG_W_NUM("POAGetPWState returned ", pwError); + CONSOLE_DEBUG(POAGetPWErrorString(pwError)); + alpacaErrCode = kASCOM_Err_UnspecifiedError; + } + return(alpacaErrCode); +} + +//***************************************************************************** +//* this accepts a position starting with 0 +//***************************************************************************** +TYPE_ASCOM_STATUS FilterwheelPlayerOne::Set_CurrentFilterPositon(const int newPosition) +{ +TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_Success; +PWErrors pwError; + +// CONSOLE_DEBUG(__FUNCTION__); + pwError = POAGotoPosition(cPWProperties.Handle, newPosition); + if (pwError == PW_OK) + { + } + else + { + CONSOLE_DEBUG_W_NUM("POAGotoPosition returned ", pwError); + CONSOLE_DEBUG(POAGetPWErrorString(pwError)); + alpacaErrCode = kASCOM_Err_UnspecifiedError; + } + return(alpacaErrCode); +} +#endif // _ENABLE_FILTERWHEEL_PLAYERONE_ + +#ifdef _INCLUDE_PLAYERONE_MAIN_ +//***************************************************************************** +int main(int argc, char *argv[]) +{ + int PW_count = POAGetPWCount(); + + printf("PW count: %d\n", PW_count); + if(PW_count <= 0) + { + printf("there is no Player One filter wheel! \n"); + + getchar(); + + return 0; + } + + //malloc pointer memory first + PWProperties **ppPOA_PW_Prop = (PWProperties **)malloc(sizeof(PWProperties *) * PW_count); + + int i; + for(i = 0; i < PW_count; i++) + { + ppPOA_PW_Prop[i] = (PWProperties *)malloc(sizeof (PWProperties)); //malloc the PWProperties memory + + PWErrors error = POAGetPWProperties(i, ppPOA_PW_Prop[i]); + + if(error == PW_OK) + { + //print PW Handle and Name + printf("PW Handle: %d, PW name: %s \n", ppPOA_PW_Prop[i]->Handle, ppPOA_PW_Prop[i]->Name); + //print PW SN and PW position count + printf("PW SN: %s \n PW Position Count: %d \n", ppPOA_PW_Prop[i]->SN, ppPOA_PW_Prop[i]->PositionCount); + } + else + { + free(ppPOA_PW_Prop[i]); + ppPOA_PW_Prop[i] = NULL; + printf("get PW properties failed, index: %d, error code: %s \n", i, POAGetPWErrorString(error)); + } + } + + //operate the first PW + + int handle, position_count, goto_position; + + handle = ppPOA_PW_Prop[0]->Handle; + + position_count = ppPOA_PW_Prop[0]->PositionCount; + + // open PW + PWErrors error; + error = POAOpenPW(handle); + + if(error != PW_OK) + { + printf("Open PW Failed, error code: %s \n", POAGetPWErrorString(error)); + + //free the memory + for(i = 0; i < PW_count; i++) + { + if(ppPOA_PW_Prop[i]) + { + free(ppPOA_PW_Prop[i]); + ppPOA_PW_Prop[i] = NULL; + } + } + + free(ppPOA_PW_Prop); + ppPOA_PW_Prop = NULL; + + return 0; + } + + //NOTE: When opened successfully, phoenix filter wheel will goto 1st position,menas: index == 0; + + //Detect PW is moving + //You can ignore this step in your APP, in this demo, just waiting for PW stop moving + PWState pw_state = PW_STATE_OPENED; + do + { + POAGetPWState(handle, &pw_state); + }while(pw_state == PW_STATE_MOVING); + + //get the current position + goto_position = 0; + error = POAGetCurrentPosition(handle, &goto_position); + printf("get PW current position, pos: %d, error code: %s \n \n", goto_position, POAGetPWErrorString(error)); + + printf("Goto Poistion Testing: \n"); + + do + { + printf("--> Please input a number in the range[0 - %d], if the number < 0, this Goto Poistion Testing will quit: \n", position_count-1); + scanf("%d", &goto_position); + + if(goto_position < 0) + { + printf("goto poistion testing quit.... \n"); + break; + } + + if(goto_position >= position_count) + { + printf("The number you inputed is out of range.... \n"); + continue; + } + + error = POAGotoPosition(handle, goto_position); // goto position + + printf("got position: %d, error string: %s \n", goto_position, POAGetPWErrorString(error)); + + if(error == PW_OK) //waiting for PW stop moving + { + PWState pw_state = PW_STATE_OPENED; + + do + { + POAGetPWState(handle, &pw_state); + }while(pw_state == PW_STATE_MOVING); + } + + }while(1); + + + //Close PW + POAClosePW(handle); + + + //free the memory + for(i = 0; i < PW_count; i++) + { + if(ppPOA_PW_Prop[i]) + { + free(ppPOA_PW_Prop[i]); + ppPOA_PW_Prop[i] = NULL; + } + } + + free(ppPOA_PW_Prop); + ppPOA_PW_Prop = NULL; + + return 0; +} +#endif // _INCLUDE_PLAYERONE_MAIN_ + + diff --git a/src/filterwheeldriver_Play1.h b/src/filterwheeldriver_Play1.h new file mode 100644 index 0000000..78e5a05 --- /dev/null +++ b/src/filterwheeldriver_Play1.h @@ -0,0 +1,49 @@ +//************************************************************************** +//* Name: filterwheeldriver_PlayerOne.h +//* +//************************************************************************** +//#include "filterwheeldriver_PlayerOne.h" + +#ifndef _FILTERWHEELDRIVER_PLAYERONE_H_ + #define _FILTERWHEELDRIVER_PLAYERONE_H_ + +#ifndef _FILTERWHEELDRIVER_H_ + #include "filterwheeldriver.h" +#endif + +#ifndef PLAYERONEPW_H + #include "PlayerOnePW.h" +#endif + + +//************************************************************************************** +class FilterwheelPlayerOne: public FilterwheelDriver +{ + public: + + //CreateFilterWheelObjects_PlayerOne + // Construction + // + FilterwheelPlayerOne(const int argPlayerDeviceNumber); + virtual ~FilterwheelPlayerOne(void); + virtual bool AlpacaConnect(void); + + protected: + void ReadFilterWheelInfo(void); + + virtual int Read_CurrentFWstate(void); + virtual TYPE_ASCOM_STATUS Read_CurrentFilterPositon(int *rtnCurrentPosition = NULL); + virtual TYPE_ASCOM_STATUS Set_CurrentFilterPositon(const int newPosition); + + bool cForceReadPosition; + int cActualPosReadCout; + + int cPWindex; + PWProperties cPWProperties; + PWState cPWstate; + +}; + +void CreateFilterWheelObjects_PlayerOne(void); + +#endif // _FILTERWHEELDRIVER_PLAYERONE_H_ diff --git a/src/gps_data.cpp b/src/gps_data.cpp index b0d95b5..f093e40 100644 --- a/src/gps_data.cpp +++ b/src/gps_data.cpp @@ -9,9 +9,11 @@ //* = Mark L Sproul //***************************************************************************** //* Apr 9, 2024 Created gps_data.cpp +//* Apr 26, 2024 Started working on gps graph support +//* Apr 27, 2024 GPS graph working from alpacapi driver //***************************************************************************** -#define _ENABLE_GLOBAL_GPS_ +//#define _ENABLE_GLOBAL_GPS_ #ifdef _ENABLE_GLOBAL_GPS_ @@ -24,15 +26,18 @@ #include #include #include +//#include #include #include -#include //ioctl() call definitions +#include //* ioctl() call definitions +#define _DEBUG_TIMING_ #define _ENABLE_CONSOLE_DEBUG_ #include "ConsoleDebug.h" +#include "helper_functions.h" #include "ParseNMEA.h" #include "NMEA_helper.h" @@ -40,6 +45,10 @@ #include "serialport.h" #include "gps_data.h" +#ifdef _ENABLE_GPS_GRAPHS_ + #include "GPS_graph.h" + static void CreateGPSgrapicsDirectory(void); +#endif //=========================================================================== //* GPS info @@ -63,12 +72,16 @@ char theChar; char nmeaLineBuff[256]; struct stat fileStatus; int returnCode; +uint32_t lastGrapicsSave_ms; +uint32_t current_ms; +uint32_t delta_ms; CONSOLE_DEBUG(__FUNCTION__); CONSOLE_DEBUG(gSerialPortPath); CONSOLE_DEBUG(__FUNCTION__); ParseNMEA_init(&gNMEAdata); + lastGrapicsSave_ms = 0; //--------------------------------------------------- //* check to make sure the devices is present returnCode = stat(gSerialPortPath, &fileStatus); //* fstat - check for existence of file @@ -152,15 +165,29 @@ int returnCode; } } } +// #ifdef _ENABLE_GPS_GRAPHS_ +// current_ms = millis(); +// delta_ms = current_ms - lastGrapicsSave_ms; +// if (delta_ms > (1 * 60 * 1000)) +//// if (delta_ms > (10 * 1000)) +// { +// CreateGPSgraphics(); +// lastGrapicsSave_ms = current_ms; +// } +// +// #endif // _ENABLE_GPS_GRAPHS_ } } - //***************************************************************************** void GPS_StartThread(const char *serialPortPathArg, const char baudRate) { int threadErr; +#ifdef _ENABLE_GPS_GRAPHS_ + CreateGPSgrapicsDirectory(); +#endif + if (serialPortPathArg != NULL) { strcpy(gSerialPortPath, serialPortPathArg); @@ -178,12 +205,84 @@ int threadErr; } } +#ifdef _ENABLE_GPS_GRAPHS_ +//***************************************************************************** +static void CreateGPSgrapicsDirectory(void) +{ +int returnCode; +int mkdirErrCode; +struct stat fileStatus; + + + returnCode = stat(kGPSimageDirectory, &fileStatus); //* fstat - check for existence of file + if (returnCode == 0) + { +// CONSOLE_DEBUG_W_STR("Directory is present", kGPSimageDirectory); + } + else + { + mkdirErrCode = mkdir(kGPSimageDirectory, 0744); + if (mkdirErrCode == 0) + { + CONSOLE_DEBUG_W_NUM("mkdir() failed", mkdirErrCode); + } + } +} + +static int gGraphsCreatedCounter = 0; + +//***************************************************************************** +void CreateGPSgraphics(void) +{ + CONSOLE_DEBUG_W_NUM("gGraphsCreatedCounter\t=", gGraphsCreatedCounter); + + SETUP_TIMING(); + + gGraphsCreatedCounter++; +#ifdef _ENABLE_SATELLITE_TRAILS_ + CreateSatelliteTrailsGraph(NULL, kGPSimageDirectory, "satelliteTrails.jpg"); + CreateSatelliteElevationGraph(NULL, kGPSimageDirectory, elevationGraphFileName); +#endif + +#ifdef _ENABLE_LAT_LON_TRACKING_ + CreateLatLonHistoryPlot(NULL, kGPSimageDirectory, "latlonGraph.jpg"); +#endif + +#ifdef _ENABLE_ALTITUDE_TRACKING_ + CreateAltitudeHistoryPlot(NULL, kGPSimageDirectory, altGraphFileName); +#endif + +#ifdef _ENABLE_PDOP_TRACKING_ + CreatePDOPhistoryPlot(NULL, kGPSimageDirectory, pdopGraphFileName); +#endif + +#ifdef _ENABLE_NMEA_POSITION_ERROR_TRACKING_ + CreatePositionErrorHistoryPlot(NULL, kGPSimageDirectory, posErrGraphFileName); +#endif + +#ifdef _ENABLE_ALTITUDE_TRACKING_ + CreateAltitudeHistoryPlot(NULL, kGPSimageDirectory, altGraphFileName); +#endif // _ENABLE_ALTITUDE_TRACKING_ + +#ifdef _ENABLE_SATELLITE_ALMANAC_ + CreateSNRdistrbutionPlot( NULL, kGPSimageDirectory, snrGraphFileName); + CreateSatsInUseHistoryPlot( NULL, kGPSimageDirectory, satsInUseGraphFileName); +#endif // _ENABLE_SATELLITE_ALMANAC_ + + DEBUG_TIMING("Time to write out image files:"); +} +#endif // _ENABLE_GPS_GRAPHS_ + #ifdef _INCLUDE_GPSTEST_MAIN_ //***************************************************************************** int main(int argc, char **argv) { printf("Staring gps read data thread %s\r\n", __FUNCTION__); + CONSOLE_DEBUG_W_NUM("kLatLonTacking_ArraySize\t=", kLatLonTacking_ArraySize); + CONSOLE_DEBUG_W_NUM("kAltTacking_ArraySize \t=", kAltTacking_ArraySize); + CONSOLE_DEBUG_W_NUM("kPosErrTacking_ArraySize\t=", kPosErrTacking_ArraySize); + CONSOLE_DEBUG_W_NUM("kPDOPtacking_ArraySize \t=", kPDOPtacking_ArraySize); GPS_StartThread("/dev/ttyS0"); diff --git a/src/gps_data.h b/src/gps_data.h index 601062b..560f273 100644 --- a/src/gps_data.h +++ b/src/gps_data.h @@ -15,8 +15,18 @@ #ifndef _GPS_DATA_H_ #define _GPS_DATA_H_ +#ifndef _PARSE_NMEA_H_ + #include "ParseNMEA.h" +#endif +void CreateGPSgraphics(void); + +//* the folder name cannot start with "gps" as it confuses the parser +#define kGPSimageDirectory "graphs-gps" + +extern TYPE_NMEAInfoStruct gNMEAdata; + #define kMaxNMEAlen 80 diff --git a/src/helper_functions.h b/src/helper_functions.h index 470b3d3..d748763 100755 --- a/src/helper_functions.h +++ b/src/helper_functions.h @@ -31,6 +31,7 @@ #endif +#define kMinutesPerDay (24 * 60) double AsciiToDouble( const char *asciiString); diff --git a/src/slittracker.cpp b/src/slittracker.cpp index 9e5d352..a9e0826 100755 --- a/src/slittracker.cpp +++ b/src/slittracker.cpp @@ -831,7 +831,7 @@ const char webpageTitle[] = "AlpacaPi Slit-tracker setup"; SocketWriteData(mySocketFD, gHtmlHeader); SocketWriteData(mySocketFD, "\r\n"); - SocketWriteData(mySocketFD, "\r\n"); + SocketWriteData(mySocketFD, "\r\n"); sprintf(lineBuff, "%s\r\n", webpageTitle); SocketWriteData(mySocketFD, lineBuff); SocketWriteData(mySocketFD, "
    \r\n"); diff --git a/src/telescopedriver.cpp b/src/telescopedriver.cpp index 0387e46..09833d3 100755 --- a/src/telescopedriver.cpp +++ b/src/telescopedriver.cpp @@ -68,6 +68,11 @@ //* Jan 15, 2024 Added Get_IMU() //* Jan 16, 2024 Added Telescope_CalculateSideOfPier() //* Feb 11, 2024 Added IMU-Roll, IMU-Pitch, & IMU-Yaw to telescope readall +//* Apr 24, 2024 Working on GPS input for telescope site location +//* Apr 24, 2024 Added GPS_TelescopeThread() +//* Apr 24, 2024 Added Set_SiteLatitude(), Set_SiteLongitude(), Set_SiteAltitude() +//* Apr 25, 2024 Added averaging to Lat/Lon updates from GPS +//* APr 28, 2024 Added DumpTelescopeDriverStruct() //***************************************************************************** @@ -93,14 +98,24 @@ #include "sidereal.h" #include "observatory_settings.h" +#ifdef _ENABLE_GLOBAL_GPS_ +// #include "gps_data.h" + #include "ParseNMEA.h" +#endif +//---------------------------------------------------------------------- #include "telescopedriver.h" +#ifdef _ENABLE_TELESCOPE_EXP_SCI_ + #include "telescopedriver_ExpSci.h" +#endif + #ifdef _ENABLE_TELESCOPE_LX200_ #include "telescopedriver_lx200.h" #endif #ifdef _ENABLE_TELESCOPE_RIGEL_ + #include "telescopedriver_Rigel.h" #endif #ifdef _ENABLE_TELESCOPE_SKYWATCH_ @@ -117,12 +132,12 @@ #ifdef _ENABLE_IMU_ #include "imu_lib.h" -// #include "imu_lib_bno055.h" #endif #include "telescope_AlpacaCmds.h" #include "telescope_AlpacaCmds.cpp" +static void *GPS_TelescopeThread(void *arg); //************************************************************************************** int CreateTelescopeObjects(void) @@ -132,6 +147,12 @@ int telescopeCnt; CONSOLE_DEBUG(__FUNCTION__); telescopeCnt = 0; + + +#ifdef _ENABLE_TELESCOPE_EXP_SCI_ + telescopeCnt += CreateTelescopeObjects_ExploreScientific(); +#endif + #ifdef _ENABLE_TELESCOPE_LX200_ new TelescopeDriverLX200(kDevCon_Ethernet, "192.168.1.104:49152"); telescopeCnt++; @@ -262,14 +283,31 @@ int iii; // IMU_BNO055_StartBackgroundThread(); IMU_StartBackgroundThread(NULL); #endif // _ENABLE_IMU_ + + +#ifdef _ENABLE_GLOBAL_GPS_ +int threadErr; + + CONSOLE_DEBUG("Creating GPS_TelescopeThread"); + cGPStelescopeKeepRunning = true; + threadErr = pthread_create(&cGPStelescopeThreadID, NULL, &GPS_TelescopeThread, this); + if (threadErr != 0) + { + CONSOLE_DEBUG_W_NUM("threadErr=", threadErr); + } +#endif // _ENABLE_GLOBAL_GPS_ } + //************************************************************************************** // Destructor //************************************************************************************** TelescopeDriver::~TelescopeDriver(void) { CONSOLE_DEBUG(__FUNCTION__); +#ifdef _ENABLE_GLOBAL_GPS_ + cGPStelescopeKeepRunning = false; +#endif } @@ -295,7 +333,6 @@ int mySocket; mySocket = reqData->socket; strcpy(alpacaErrMsg, ""); - alpacaErrCode = kASCOM_Err_ActionNotImplemented; //* set up the json response JsonResponse_CreateHeader(reqData->jsonTextBuffer); @@ -317,6 +354,7 @@ int mySocket; //* look up the command // CONSOLE_DEBUG_W_STR("deviceCommand\t=", reqData->deviceCommand); + alpacaErrCode = kASCOM_Err_ActionNotImplemented; cmdEnumValue = FindCmdFromTable(reqData->deviceCommand, gTelescopeCmdTable, &cmdType); switch(cmdEnumValue) { @@ -637,8 +675,14 @@ int mySocket; break; case kCmd_Telescope_abortslew: //* Immediately stops a slew in progress. - alpacaErrCode = Put_AbortSlew(reqData, alpacaErrMsg); - CONSOLE_DEBUG_W_NUM("alpacaErrCode\t=", alpacaErrCode); + if (reqData->get_putIndicator == 'P') + { + alpacaErrCode = Put_AbortSlew(reqData, alpacaErrMsg); + } + else + { + CONSOLE_DEBUG("Abort slew is PUT only!!!!!"); + } break; case kCmd_Telescope_axisrates: //* Returns the rates at which the telescope may be moved about the specified axis. @@ -788,6 +832,10 @@ int mySocket; alpacaErrCode = ProcessCommand_Common(reqData, cmdEnumValue, alpacaErrMsg); break; } + if (alpacaErrCode != kASCOM_Err_Success) + { + CONSOLE_DEBUG_W_NUM("alpacaErrCode\t=", alpacaErrCode); + } // CONSOLE_DEBUG_W_NUM("Calling RecordCmdStats(), cmdEnumValue=", cmdEnumValue); RecordCmdStats(cmdEnumValue, reqData->get_putIndicator, alpacaErrCode); @@ -2489,6 +2537,8 @@ TYPE_ASCOM_STATUS TelescopeDriver::Put_AbortSlew(TYPE_GetPutRequestData *reqData TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_Success; CONSOLE_DEBUG(__FUNCTION__); +// DumpRequestStructure(__FUNCTION__, reqData); + // CONSOLE_DEBUG(reqData->contentData); alpacaErrMsg[0] = 0; @@ -3561,7 +3611,6 @@ TYPE_ASCOM_STATUS TelescopeDriver::Get_Readall(TYPE_GetPutRequestData *reqData, { TYPE_ASCOM_STATUS alpacaErrCode = kASCOM_Err_NotImplemented; int mySocket; -char dataString[256]; // CONSOLE_DEBUG(__FUNCTION__); #ifdef _DEBUG_CONFORM_ @@ -3640,13 +3689,14 @@ char dataString[256]; alpacaErrCode = Get_HourAngle( reqData, alpacaErrMsg, "HourAngle"); alpacaErrCode = Get_PhysicalSideOfPier( reqData, alpacaErrMsg, "PhysicalSideOfPier"); #ifdef _ENABLE_IMU_ +char imudataString[256]; alpacaErrCode = Get_IMU( reqData, alpacaErrMsg, "IMU"); - IMU_GetIMUtypeString(dataString); + IMU_GetIMUtypeString(imudataString); JsonResponse_Add_String(mySocket, reqData->jsonTextBuffer, kMaxJsonBuffLen, "IMU-Type", - dataString, + imudataString, INCLUDE_COMMA); #endif // _ENABLE_IMU_ @@ -3939,4 +3989,154 @@ double myElevation; return(sideOfPier); } +//************************************************************************************** +void DumpTelescopeDriverStruct(TYPE_TelescopeProperties *telescopeDriver) +{ + CONSOLE_DEBUG_W_NUM("CanUnpark \t=", telescopeDriver->CanUnpark); + CONSOLE_DEBUG_W_NUM("CanMoveAxis[kAxis_RA] \t=", telescopeDriver->CanMoveAxis[kAxis_RA]); + CONSOLE_DEBUG_W_NUM("CanMoveAxis[kAxis_DEC]\t=", telescopeDriver->CanMoveAxis[kAxis_DEC]); +} + +#ifdef _ENABLE_GLOBAL_GPS_ +//************************************************************************************** +void TelescopeDriver::Set_SiteLatitude(const double newSiteLatitude) +{ + if ((newSiteLatitude >= -90.0) && (newSiteLatitude <= 90.0)) + { + cTelescopeProp.SiteLatitude = newSiteLatitude; + } +} + +//************************************************************************************** +void TelescopeDriver::Set_SiteLongitude(const double newSiteLongitude) +{ + if ((newSiteLongitude >= -180.0) && (newSiteLongitude <= 360.0)) + { + cTelescopeProp.SiteLongitude = newSiteLongitude; + } +} + void Set_SiteAltitude(const double newSiteAlititude); +//************************************************************************************** +void TelescopeDriver::Set_SiteAltitude(const double newSiteAlititude) +{ + if ((newSiteAlititude >= -200.0) && (newSiteAlititude <= 10000.0)) + { + cTelescopeProp.SiteElevation = newSiteAlititude; + } +} + +#define kTelescopeLatLonAvgCnt 32 +//************************************************************************************** +static double ComputeAveage(const double *numberList, const int avgCount) +{ +double total; +int iii; + + total = 0.0; + for (iii=0; iiicGPStelescopeKeepRunning) + { + sleepDuration = 60; + if (gNMEAdata.validData) + { + if (gNMEAdata.validLatLon) + { +// CONSOLE_DEBUG("Updating Telescope lat/lon from gps"); + + //* save in the array for averaging + latitudeArray[latLonArrayIdx] = gNMEAdata.lat_average; + longitudeArray[latLonArrayIdx] = gNMEAdata.lon_average; + latLonArrayIdx++; + if (latLonArrayIdx >= kTelescopeLatLonAvgCnt) + { + latLonArrayIdx = 0; + } + if (latlonUpdateCnt > kTelescopeLatLonAvgCnt) + { + avgValue = ComputeAveage(latitudeArray, kTelescopeLatLonAvgCnt); + myTelescopeDriver->Set_SiteLatitude(avgValue); + avgValue = ComputeAveage(longitudeArray, kTelescopeLatLonAvgCnt); + myTelescopeDriver->Set_SiteLongitude(avgValue); + } + else + { + myTelescopeDriver->Set_SiteLatitude(gNMEAdata.lat_average); + myTelescopeDriver->Set_SiteLongitude(gNMEAdata.lon_average); + } + latlonUpdateCnt++; + } + if (gNMEAdata.validAlt) + { +// CONSOLE_DEBUG("Updating Telescope alititude from gps"); + altitudeArray[altArrayIdx] = gNMEAdata.alt_average; + altArrayIdx++; + if (altArrayIdx >= kTelescopeLatLonAvgCnt) + { + altArrayIdx = 0; + } + if (altitudeUpdateCnt > kTelescopeLatLonAvgCnt) + { + avgValue = ComputeAveage(altitudeArray, kTelescopeLatLonAvgCnt); + myTelescopeDriver->Set_SiteAltitude(avgValue); + } + else + { + myTelescopeDriver->Set_SiteAltitude(gNMEAdata.alt_average); + } + altitudeUpdateCnt++; + } + if (latlonUpdateCnt < 10) + { + sleepDuration = 15; + } + } + sleep(sleepDuration); + } + } +// else +// { +// CONSOLE_DEBUG("Invalid"); +// } + CONSOLE_DEBUG_W_STR(__FUNCTION__, "EXIT!!!!!!!!!!!!!!"); + return(NULL); +} +#endif // _ENABLE_GLOBAL_GPS_ + + + #endif // _ENABLE_TELESCOPE_ diff --git a/src/telescopedriver.h b/src/telescopedriver.h index 0158aff..07002ad 100755 --- a/src/telescopedriver.h +++ b/src/telescopedriver.h @@ -247,6 +247,14 @@ virtual bool DeviceState_Add_Content(const int socketFD, char *jsonTextBuffer bool cDriverSupports_SlewSettleTime; bool cDriverSupports_LimitSwitches; +#ifdef _ENABLE_GLOBAL_GPS_ + pthread_t cGPStelescopeThreadID; + public: + bool cGPStelescopeKeepRunning; + void Set_SiteLatitude(const double newSiteLatitude); + void Set_SiteLongitude(const double newSiteLongitude); + void Set_SiteAltitude(const double newSiteAlititude); +#endif // _ENABLE_GLOBAL_GPS_ }; diff --git a/src_imu/imu_lib.c b/src_imu/imu_lib.c index c7abb99..a098676 100644 --- a/src_imu/imu_lib.c +++ b/src_imu/imu_lib.c @@ -11,7 +11,7 @@ //* Jan 15, 2024 Added IMU_GetRoll_Pitch_Yaw() //* Jan 15, 2024 Moved IMU averaging from imu_lib_bno055.c to imu_lib.c //* Jan 15, 2024 The LIS2DH12 has roll off by 90 degrees, fixed in IMU_GetAverageRoll() -//* Feb 25, 2024 S Added IMU_GetIMUtypeString() +//* Feb 25, 2024 Added IMU_GetIMUtypeString() //***************************************************************************** #ifdef _ENABLE_IMU_ diff --git a/src_mlsLib/GPS_graph.c b/src_mlsLib/GPS_graph.c new file mode 100644 index 0000000..85418fb --- /dev/null +++ b/src_mlsLib/GPS_graph.c @@ -0,0 +1,1522 @@ +//************************************************************************************** +//* GPS graphing library +//* uses data accumulated by the ParseNMEA library to generate html outputs +//************************************************************************************** +//* Edit History +//* MLS = Mark Sproul +//************************************************************************************** +//* Apr 20, 2017 Added almanac graphing +//* Apr 21, 2017 Added DrawGPS_AlmanacGrid() +//* Apr 21, 2017 Added CreateSNRdistrbutionPlot() +//* Apr 24, 2017 Added NMEA sentence list +//* Apr 25, 2017 Added Legend to satellite position plot +//* May 3, 2017 Added plotting of altitude over time +//* May 9, 2017 Added sat numbers on almanac +//* May 15, 2017 Added CreateSatsInUseHistoryPlot() +//* Jun 8, 2017 Moved graphing routines to separate file +//* Jun 9, 2017 Added vertical line at the current time in the history plots +//* Jun 12, 2017 Added CreateSatelliteTrailsGraph() +//* Jun 13, 2017 Added CreateSatelliteElevationGraph() +//* Apr 27, 2024 Added _ENABLE_HTML_OUTPUT_ +//************************************************************************************** + +#ifdef _ENABLE_GPS_GRAPHS_ + + +#include +#include +#include +#include +#include +#include + +//#define _ENABLE_HTML_OUTPUT_ + +//* MLS Librarires +#define _ENABLE_CONSOLE_DEBUG_ +#include "ConsoleDebug.h" + + +#ifdef _USE_OPENCV_ + #include "web_graphics_opencv.h" +#else + #include "web_graphics.h" + #include "HTMLoutput.h" + #include "Statistics.h" +#endif + + +#include "ParseNMEA.h" + +#include "GPS_graph.h" + +#include "Statistics.c" + +#define kScreen_Width 800 +#define kScreen_Height 512 +//#define kDotSize 8 +#define kDotSize 5 +#define kSatSize 20 + +//#define kDeg2Rad (57.2957795130823) // 360 / (2 * pi) +#define degrees(r) (r * 180.0 / M_PI) +#define radians(deg) ((deg) * (M_PI / 180.0)) + +////***************************************************************************** +//const char elevationGraphFileName[] = "gps-elevation.jpg"; +//const char snrGraphFileName[] = "gps-snrplot.jpg"; +//const char pdopGraphFileName[] = "gps-pdop.jpg"; +//const char altGraphFileName[] = "gps-alt.jpg"; +//const char latlonGraphFileName[] = "gps-latlon.jpg"; +//const char satsInUseGraphFileName[] = "gps-satsInUse.jpg"; +//const char posErrGraphFileName[] = "gps-posErr.jpg"; +//const char magVarGraphFileName[] = "gps-magvar.jpg"; + +//***************************************************************************** +static short ReturnCompAngFromMapAng(short theMapAngle_Degrees) +{ +short computerAngle; + + computerAngle = 360 - theMapAngle_Degrees - 270; + while (computerAngle < 0) + { + computerAngle = 360 + computerAngle; + } + return(computerAngle); +} + + +//************************************************************************************** +static int gSnrDivions[] = { 10, 20, 30, 40, 50, 100 }; +static int gSnrColors[] = +{ + kGraphPointMode_RedDot, + kGraphPointMode_OrangeDot, + kGraphPointMode_YellowDot, + kGraphPointMode_BlueDot, + kGraphPointMode_GreenDot, + kGraphPointMode_DkGreenDot, + + -1 +}; + +//************************************************************************************** +void DrawGPS_AlmanacGrid(void) +{ +int xCenter, yCenter; +int outsideRadius; +int circleRadius; +int circleDiameter; +double degrees; +double percent; +int x1, y1; +int x2, y2; +int iii; +char legendText[32]; +int previousSNR; + + CONSOLE_DEBUG(__FUNCTION__); + +#ifdef _T6963_GRAPHICS_ + LCD.createCircle(xCenter, yCenter, circleRadius); +#endif + +#define kCircleStepDegrees 30.0 + + xCenter = kScreen_Width / 2; + yCenter = kScreen_Height / 2; + outsideRadius = (kScreen_Height / 2) - 10; + circleRadius = outsideRadius; + + + circleDiameter = 2 * circleRadius; + WebGraph_Draw2DCircleFilled(xCenter, yCenter, circleDiameter, circleDiameter, _gdColorLtGrey); + + degrees = kCircleStepDegrees; + while (degrees <= 90) + { + percent = degrees / 90.0; + circleRadius = percent * outsideRadius; + circleDiameter = 2 * circleRadius; + + WebGraph_Draw2DCircle(xCenter, yCenter, circleDiameter, circleDiameter, _gdColorBlack); + + degrees += kCircleStepDegrees; + } + + //* now draw horizontal and vertical lines + x1 = 0; + x2 = kScreen_Width; + y1 = yCenter; + y2 = yCenter; + WebGraph_Draw3Dline(x1, y1, 0, x2, y2, 0, _gdColorBlack); + + + x1 = xCenter; + x2 = xCenter; + y1 = 0; + y2 = kScreen_Height; + WebGraph_Draw3Dline(x1, y1, 0, x2, y2, 0, _gdColorBlack); + + +#define kLegendWidth 125 +// CONSOLE_DEBUG_W_NUM("_currentYsize", _currentYsize); + //* draw the legend + WebGraph_DrawLegend(0, -1, "SNR", kLegendWidth); + iii = 0; + previousSNR = 0; + while (gSnrColors[iii] >= 0) + { + sprintf(legendText, "%2d - %2d", previousSNR, gSnrDivions[iii]); + WebGraph_DrawLegend((iii + 1), gSnrColors[iii], legendText, kLegendWidth); + + previousSNR = gSnrDivions[iii] + 1; + iii++; + } +} + +//************************************************************************************** +static cv::Scalar GetColorFromSNRvalue(int snrValue) +{ +int iii; +cv::Scalar snrColor; + + iii = 0; + while ((gSnrColors[iii] >= 0) && (iii < 10)) + { + if (snrValue <= gSnrDivions[iii]) + { + snrColor = WebGraph_GetColorByIndex(gSnrColors[iii]); + break; + } + iii++; + } + + return(snrColor); +} + +//************************************************************************************** +static double CalcLabelStepValueY(const double maxYvalue) +{ +double labelStepY; + + if (maxYvalue > 200000) + { + labelStepY = 50000; + } + else if (maxYvalue > 100000) + { + labelStepY = 20000; + } + else if (maxYvalue > 20000) + { + labelStepY = 5000; + } + else if (maxYvalue > 10000) + { + labelStepY = 2000; + } + else if (maxYvalue > 5000) + { + labelStepY = 1000; + } + else if (maxYvalue > 2500) + { + labelStepY = 500; + } + else if (maxYvalue > 1000) + { + labelStepY = 200; + } + else + { + labelStepY = 100; + } + + if (maxYvalue < 10) + { + labelStepY = 1; + } + else if (maxYvalue < 50) + { + labelStepY = 5; + } + else if (maxYvalue < 100) + { + labelStepY = 10; + } + + return(labelStepY); +} + +//************************************************************************************** +static void DrawCurrentPointTimeOnGraph(double xValue, double scaleFactorX, double scaleFactorY, double yMax) +{ + WebGraph_Draw2DlineScaledXY(xValue, 0, xValue, 20000, scaleFactorX, scaleFactorY, _gdColorMagenta); + WebGraph_Draw2DlineScaledXY(xValue + 0.03, 0, xValue + 0.03, 20000, scaleFactorX, scaleFactorY, _gdColorMagenta); + WebGraph_Draw2DlineScaledXY(xValue + 0.06, 0, xValue + 0.06, 20000, scaleFactorX, scaleFactorY, _gdColorMagenta); +} + + +#ifdef _ENABLE_SATELLITE_ALMANAC_ +//************************************************************************************** +void DisplayGPSalmanac(TYPE_SatStatsStruct *theSatData, bool showSatNum) +{ +int xCenter, yCenter; +int circleRadius; +int circleDiameter; +int iii; +double dhy; // Hypotenuse +double daj; // Adjacent +double dop; // Oposite +int azm; +int azimuth; +int elevation; +int signal2Noise; +double azm_radians; +double elv_radians; +int satCenterX, satCenterY; +cv::Scalar snrColor; + + CONSOLE_DEBUG(__FUNCTION__); + + xCenter = kScreen_Width / 2; + yCenter = kScreen_Height / 2; + circleRadius = (kScreen_Height / 2) - 10; + circleDiameter = circleRadius * 2; + +// iii = 9; + for (iii=0; iii 0) + { + azimuth = theSatData[iii].azimuth; + signal2Noise = theSatData[iii].signal2Noise; + + azm = ReturnCompAngFromMapAng(azimuth); + + elv_radians = radians(elevation); + azm_radians = radians(azm); + + //* compute the distance out from the center + dhy = cos(elv_radians) * (circleRadius - 3); + daj = cos(azm_radians) * dhy; + dop = sin(azm_radians) * dhy; + + satCenterX = xCenter + daj; + satCenterY = yCenter + dop; + + #if defined(_GENERATE_GRAPHICS_) + snrColor = GetColorFromSNRvalue(signal2Noise); + + if (iii > 32) + { + snrColor = _gdColorMagenta; + } + if (iii >= 64) + { + snrColor = _gdColorCyan; + } + + WebGraph_Draw2DCircleFilled(satCenterX, satCenterY, kDotSize, kDotSize, snrColor); + + //* this option should only be called at the very end to show the current location of the sat + if (showSatNum) + { + char satNumText[32]; + int xOffset; + + sprintf(satNumText, "%d", theSatData[iii].satellitePRN); + #if 1 + #define kSatSizeOuter 31 + #define kSatSizeIner 21 + if (theSatData[iii].satellitePRN < 10) + { + xOffset = 4; + } + else + { + xOffset = 8; + } + WebGraph_Draw2DCircleFilled( satCenterX, satCenterY, kSatSizeOuter, kSatSizeOuter, snrColor); + WebGraph_Draw2DCircle( satCenterX, satCenterY, kSatSizeOuter, kSatSizeOuter, _gdColorBlack); + WebGraph_Draw2DCircleFilled( satCenterX, satCenterY, kSatSizeIner, kSatSizeIner, _gdColorWhite); + WebGraph_DrawScreenTextLg_translated( satNumText, + satCenterX - xOffset, + satCenterY + 8, + _gdColorBlack); + + #else + WebGraph_Draw2DCircleFilled(satCenterX, satCenterY, kSatSize, kSatSize, snrColor); + WebGraph_Draw2DCircle(satCenterX, satCenterY, kSatSize, kSatSize, _gdColorBlack); + WebGraph_DrawScreenTextLg_translated( satNumText, + satCenterX + 12, + satCenterY + 8, + _gdColorBlack); + #endif + } + + #elif defined(_T6963_GRAPHICS_) + LCD.createLine(satCenterX - 2, satCenterY, satCenterX + 2, satCenterY); + LCD.createLine(satCenterX, satCenterY - 2, satCenterX, satCenterY + 2); + + // LCD.createCircle(satCenterX, satCenterY, 2); + #endif + } + } +} + + +//************************************************************************************** +void CreateSatsInUseHistoryPlot(FILE *htmlFile, const char *imageFolderName, const char *satsInUseGraphFileName) +{ +double startX; +double endX; +double labelStepX; +double startY; +double endY; +double labelStepY; +double hourValues[kSatsInUseTracking_ArraySize]; +double satsInUse[kSatsInUseTracking_ArraySize]; +double satMode[kSatsInUseTracking_ArraySize]; +int satsInUseIdx; +int iii; +int maxSatsInUse; +int currentPtOnGraph; +double scaleFactorX; +double scaleFactorY; +//char legendText[32]; + + WebGraph_CreateImage(800, 400); + + satsInUseIdx = 0; + maxSatsInUse = 0; + for (iii=0; iii maxSatsInUse) + { + maxSatsInUse = gNMEAdata.satsInUse[iii]; + } + } + + startX = 0; + endX = 25; + startY = 0.0; + labelStepX = 2; + labelStepY = 1; + if (maxSatsInUse > 8) + { + endY = 11.8; + } + else + { + endY = 9.8; + } + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, + kSatsInUseTracking_ArraySize, hourValues, satMode, kGraphPointMode_DkGreenLine, &scaleFactorX, &scaleFactorY, true, true, true); + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, + kSatsInUseTracking_ArraySize, hourValues, satsInUse, kGraphPointMode_RedLine, NULL, NULL, true, true, true); + + + //***************************************************** + //* figure out where the "current" time on the graph is and draw a vertical line + currentPtOnGraph = gNMEAdata.gpsTime / kSatsInUseTracking_deltaTime; + DrawCurrentPointTimeOnGraph(hourValues[currentPtOnGraph], scaleFactorX, scaleFactorY, 20000); + + + WebGraph_DrawTitle("Sats in use History (Count vs Time (24-hrs))", _gdColorBlack); + + WebGraph_DrawLegend(0, kGraphPointMode_RedLine, "Sats in use", 300); + WebGraph_DrawLegend(1, kGraphPointMode_DkGreenLine, "Mode, 1=none,2=2D,3=3D", 300); + + WebGraph_SaveImage(imageFolderName, satsInUseGraphFileName); + + if (htmlFile != NULL) + { + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "\n", imageFolderName, satsInUseGraphFileName); + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "

    \n"); + } +} + + +#endif // _ENABLE_SATELLITE_ALMANAC_ + + +#ifdef _ENABLE_SATELLITE_TRAILS_ +//************************************************************************************** +void CreateSatelliteTrailsGraph(FILE *htmlFile, const char *imageFolderName, const char *gpsGraphFileName) +{ +int xCenter, yCenter; +int circleRadius; +int circleDiameter; +int iii; +int jjj; +double dhy; // Hypotenuse +double daj; // Adjacent +double dop; // Oposite +int azm; +int azimuth; +int elevation; +int signal2Noise; +double azm_radians; +double elv_radians; +int satCenterX, satCenterY; +cv::Scalar snrColor; + +#define kSatSizeOuter 31 +#define kSatSizeIner 21 + + CONSOLE_DEBUG(__FUNCTION__); + + xCenter = kScreen_Width / 2; + yCenter = kScreen_Height / 2; + circleRadius = (kScreen_Height / 2) - 10; + circleDiameter = circleRadius * 2; + + WebGraph_CreateImage(kScreen_Width, kScreen_Height); + _xCenter = 0; + _yCenter = kScreen_Height; + + DrawGPS_AlmanacGrid(); + + //* step thru the history and draw the track for each satellite + for (iii=0; iii 0) + { + azimuth = gSatTrails[jjj].azimuth[iii]; + signal2Noise = gSatTrails[jjj].signal2Noise[iii]; + + azm = ReturnCompAngFromMapAng(azimuth); + + elv_radians = radians(elevation); + azm_radians = radians(azm); + + //* compute the distance out from the center + dhy = cos(elv_radians) * (circleRadius - 3); + daj = cos(azm_radians) * dhy; + dop = sin(azm_radians) * dhy; + + satCenterX = xCenter + daj; + satCenterY = yCenter + dop; + + snrColor = GetColorFromSNRvalue(signal2Noise); + + if (jjj > 32) + { + snrColor = _gdColorMagenta; + } + if (jjj >= 64) + { + snrColor = _gdColorCyan; + } + + WebGraph_Draw2DCircleFilled(satCenterX, satCenterY, kDotSize, kDotSize, snrColor); + } + } + } + + //* now draw the sat in its last postion + if ((gSatTrailsLastIdx >= 0) && (gSatTrailsLastIdx < kSatTrails_ArraySize)) + { +// CONSOLE_DEBUG_W_NUM("gSatTrailsLastIdx", gSatTrailsLastIdx); + for (jjj=0; jjj 0) + { + azimuth = gSatTrails[jjj].azimuth[gSatTrailsLastIdx]; + signal2Noise = gSatTrails[jjj].signal2Noise[gSatTrailsLastIdx]; + + azm = ReturnCompAngFromMapAng(azimuth); + + elv_radians = radians(elevation); + azm_radians = radians(azm); + + //* compute the distance out from the center + dhy = cos(elv_radians) * (circleRadius - 3); + daj = cos(azm_radians) * dhy; + dop = sin(azm_radians) * dhy; + + satCenterX = xCenter + daj; + satCenterY = yCenter + dop; + + snrColor = GetColorFromSNRvalue(signal2Noise); + + + sprintf(satNumText, "%d", gSatTrails[jjj].satellitePRN); + + if (gSatTrails[jjj].satellitePRN < 10) + { + xOffset = 4; + } + else + { + xOffset = 8; + } + WebGraph_Draw2DCircleFilled(satCenterX, satCenterY, kSatSizeOuter, kSatSizeOuter, snrColor); + WebGraph_Draw2DCircle(satCenterX, satCenterY, kSatSizeOuter, kSatSizeOuter, _gdColorBlack); + WebGraph_Draw2DCircleFilled(satCenterX, satCenterY, kSatSizeIner, kSatSizeIner, _gdColorWhite); + WebGraph_DrawScreenTextLg( satNumText, + satCenterX - xOffset, + satCenterY + 8, + _gdColorBlack); + + } + } + } + + WebGraph_SaveImage(imageFolderName, gpsGraphFileName); + + if (htmlFile != NULL) + { + fprintf(htmlFile, "\n", imageFolderName, gpsGraphFileName); + fprintf(htmlFile, "

    \n"); + } +} + + +//************************************************************************************** +void CreateSatelliteElevationGraph(FILE *htmlFile, const char *imageFolderName, const char *elevationGraphFileName) +{ +double startX; +double endX; +double labelStepX; +double startY; +double endY; +double labelStepY; +double hourValues[kSatTrails_ArraySize]; +double satElevation[kSatTrails_ArraySize]; +int iii; +int jjj; +int currentPtOnGraph; +double scaleFactorX; +double scaleFactorY; +int lineColor; +bool satHasData; + + CONSOLE_DEBUG(__FUNCTION__); + WebGraph_CreateImage(800, 400); + WebGraph_DrawTitle("Satellite elevation vs Time (24 hrs)", _gdColorBlack); + + for (iii=0; iii\n"); + fprintf(htmlFile, "\n", imageFolderName, elevationGraphFileName); + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "

    \n"); + fprintf(htmlFile, "

    \n"); + } +} + +#endif // _ENABLE_SATELLITE_TRAILS_ + + + +#ifdef _ENABLE_SATELLITE_ALMANAC_ +//************************************************************************************** +void CreateSNRdistrbutionPlot(FILE *htmlFile, const char *imageFolderName, const char *snrGraphFileName) +{ +#define kMaxSNRcount 100 +double startX; +double endX; +double labelStepX; +double startY; +double endY; +double labelStepY; +double xValues[kMaxSNRcount]; +double snrCounts[kMaxSNRcount]; //* we use doubles because the graph function wants doubles +double maxSNRcount; +int iii; + + WebGraph_CreateImage(800, 400); + + maxSNRcount = 0; + for (iii=0; iii maxSNRcount) + { + maxSNRcount = snrCounts[iii]; + } + } +// CONSOLE_DEBUG_W_DBL("maxSNRcount", maxSNRcount); + + startX = 0; + endX = 109; + startY = 0.0; + endY = maxSNRcount * 1.2; + labelStepX = 10; + labelStepY = CalcLabelStepValueY(maxSNRcount); + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, kMaxSNRcount, xValues, snrCounts, kGraphPointMode_DkGreenLine, NULL, NULL, true, true, true); + + WebGraph_DrawTitle("SNR distribution (count vs SNR)", _gdColorBlack); + WebGraph_SaveImage(imageFolderName, snrGraphFileName); + if (htmlFile != NULL) + { + fprintf(htmlFile, "\n", imageFolderName, snrGraphFileName); + fprintf(htmlFile, "

    \n"); + } +} +#endif // _ENABLE_SATELLITE_ALMANAC_ + + +#ifdef _ENABLE_PDOP_TRACKING_ +//************************************************************************************** +void CreatePDOPhistoryPlot(FILE *htmlFile, const char *imageFolderName, const char *pdopGraphFileName) +{ +double startX; +double endX; +double labelStepX; +double startY; +double endY; +double labelStepY; +double hourValues[kPDOPtacking_ArraySize]; +double maxPDOP; +int iii; +int currentPtOnGraph; +double scaleFactorX; +double scaleFactorY; + + WebGraph_CreateImage(800, 400); + + maxPDOP = 0; + for (iii=0; iii maxPDOP) + { + maxPDOP = gNMEAdata.pdopHistory[iii]; + } + } + + startX = 0; + endX = 25; + startY = 0.0; + endY = maxPDOP * 1.2; + labelStepX = 2; + labelStepY = 5; + if (maxPDOP < 5) + { + labelStepY = 1; + } + else if (maxPDOP < 10) + { + labelStepY = 2; + } + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, kPDOPtacking_ArraySize, hourValues, gNMEAdata.pdopHistory, kGraphPointMode_RedLine, &scaleFactorX, &scaleFactorY, true, true, true); + + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, kPDOPtacking_ArraySize, hourValues, gNMEAdata.vdopHistory, kGraphPointMode_GreenLine, NULL, NULL, true, true, true); + + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, kPDOPtacking_ArraySize, hourValues, gNMEAdata.hdopHistory, kGraphPointMode_BlueLine, NULL, NULL, true, true, true); + + //***************************************************** + //* figure out where the "current" time on the graph is + currentPtOnGraph = gNMEAdata.gpsTime / kPDOPtacking_deltaTime; + DrawCurrentPointTimeOnGraph(hourValues[currentPtOnGraph], scaleFactorX, scaleFactorY, 20000); + + + +// CONSOLE_DEBUG_W_NUM("_currentYsize", _currentYsize); + WebGraph_DrawLegend(0, kGraphPointMode_RedLine, "PDOP", 150); + WebGraph_DrawLegend(1, kGraphPointMode_GreenLine, "VDOP", 150); + WebGraph_DrawLegend(2, kGraphPointMode_BlueLine, "HDOP", 150); + + WebGraph_DrawTitle("PDOP History (PDOP vs Time (24-hrs)) lower is better", _gdColorBlack); + WebGraph_SaveImage(imageFolderName, pdopGraphFileName); + if (htmlFile != NULL) + { + fprintf(htmlFile, "\n", imageFolderName, pdopGraphFileName); + fprintf(htmlFile, "

    \n"); + } + +} +#endif // _ENABLE_PDOP_TRACKING_ + + +#ifdef _ENABLE_LAT_LON_TRACKING_ +//************************************************************************************** +void CreateLatLonHistoryPlot(FILE *htmlFile, const char *imageFolderName, const char *latlonGraphFileName) +{ +double startX; +double endX; +double labelStepX; +double startY; +double endY; +double labelStepY; +double hourValues[kLatLonTacking_ArraySize]; +double validLatValues[kLatLonTacking_ArraySize]; +double validLonValues[kLatLonTacking_ArraySize]; +int validLatLonIdx; +//double latitude_avg; +//double latitude_std; +//double longitude_avg; +//double longitude_std; +double maxLatitude; +double minLatitude; +double minLongitude; +double maxLongitude; +int iii; +int ccc; +char legendText[32]; +int currentPtOnGraph; +double scaleFactorX; +double scaleFactorY; + + CONSOLE_DEBUG(__FUNCTION__); + WebGraph_CreateImage(800, 400); + + maxLatitude = 0; + minLatitude = 0; + minLongitude = 0; + maxLongitude = 0; + validLatLonIdx = 0; + for (iii=0; iii maxLatitude) + { + maxLatitude = gNMEAdata.latitudeHistory[iii]; + } + if (gNMEAdata.latitudeHistory[iii] < minLatitude) + { + minLatitude = gNMEAdata.latitudeHistory[iii]; + } + + if (gNMEAdata.longitudeHistory[iii] > maxLongitude) + { + maxLongitude = gNMEAdata.longitudeHistory[iii]; + } + if (gNMEAdata.longitudeHistory[iii] < minLongitude) + { + minLongitude = gNMEAdata.longitudeHistory[iii]; + } + + if ((gNMEAdata.latitudeHistory[iii] != 0.0) && (gNMEAdata.longitudeHistory[iii] != 0.0)) + { + validLatValues[validLatLonIdx] = gNMEAdata.latitudeHistory[iii]; + validLonValues[validLatLonIdx] = gNMEAdata.longitudeHistory[iii]; + + validLatLonIdx++; + } + } + + startX = 0; + endX = 25; + startY = 0.0; + endY = 95.0; + labelStepX = 2; + labelStepY = 10; + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, + kLatLonTacking_ArraySize, hourValues, gNMEAdata.latitudeHistory, kGraphPointMode_RedLine, &scaleFactorX, &scaleFactorY, true, true, true); + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, + kLatLonTacking_ArraySize, hourValues, gNMEAdata.longitudeHistory, kGraphPointMode_GreenLine, NULL, NULL, true, true, true); + + + //***************************************************** + //* figure out where the "current" time on the graph is + currentPtOnGraph = gNMEAdata.gpsTime / kLatLonTacking_deltaTime; + DrawCurrentPointTimeOnGraph(hourValues[currentPtOnGraph], scaleFactorX, scaleFactorY, 20000); + + + gNMEAdata.latitude_avg = STAT_CalcMean(validLatLonIdx, validLatValues); + gNMEAdata.latitude_std = STAT_CalcStdDeviation(validLatLonIdx, validLatValues); + + gNMEAdata.longitude_avg = STAT_CalcMean(validLatLonIdx, validLonValues); + gNMEAdata.longitude_std = STAT_CalcStdDeviation(validLatLonIdx, validLonValues); + +#define kLegendWidth_Lat 260 + + ccc = 0; + WebGraph_DrawLegend(ccc++, kGraphPointMode_RedLine, "Latitude", kLegendWidth_Lat); + WebGraph_DrawLegend(ccc++, kGraphPointMode_GreenLine, "Longitude", kLegendWidth_Lat); + + sprintf(legendText, "avg Lat = %7.3f", gNMEAdata.latitude_avg); + WebGraph_DrawLegend(ccc++, -1, legendText, kLegendWidth_Lat); + sprintf(legendText, "std Lat = %7.3f", gNMEAdata.latitude_std); + WebGraph_DrawLegend(ccc++, -1, legendText, kLegendWidth_Lat); + + sprintf(legendText, "avg Lon = %7.3f", gNMEAdata.longitude_avg); + WebGraph_DrawLegend(ccc++, -1, legendText, kLegendWidth_Lat); + sprintf(legendText, "std Lon = %7.3f", gNMEAdata.longitude_std); + WebGraph_DrawLegend(ccc++, -1, legendText, kLegendWidth_Lat); + + WebGraph_DrawTitle("Lat/Lon History (Lat/Lon vs Time (24-hrs))", _gdColorBlack); + + WebGraph_SaveImage(imageFolderName, latlonGraphFileName); + +#ifdef _NOT_SURE_YET_ + if (htmlFile != NULL) + { + double delataMiles; + double delataFeet; + + fprintf(htmlFile, "\n", imageFolderName, latlonGraphFileName); + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "

    \n"); + fprintf(htmlFile, "\n"); + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, ""); + PrintHTMLtableCell(htmlFile, "
    Avg"); + PrintHTMLtableCell(htmlFile, "
    Std Dev"); + PrintHTMLtableCell(htmlFile, "
    σ Miles"); + PrintHTMLtableCell(htmlFile, "
    σ Feet"); + fprintf(htmlFile, "
    \n"); + + + delataMiles = (latitude_std / 360.0) * 24901.0; + delataFeet = delataMiles * 5280; + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Latitude"); + PrintHTMLtableCellDouble(htmlFile, latitude_avg, kFormat_6_4, kUnits_degrees); + PrintHTMLtableCellDouble(htmlFile, latitude_std, kFormat_6_4, kUnits_degrees); + PrintHTMLtableCellDouble(htmlFile, delataMiles, kFormat_6_4, kUnits_none); + PrintHTMLtableCellDouble(htmlFile, delataFeet, kFormat_6_4, kUnits_feet); + fprintf(htmlFile, " \n"); + + delataMiles = (longitude_std / 360.0) * 24901.0; + delataFeet = delataMiles * 5280; + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Longitude"); + PrintHTMLtableCellDouble(htmlFile, longitude_avg, kFormat_6_4, kUnits_degrees); + PrintHTMLtableCellDouble(htmlFile, longitude_std, kFormat_6_4, kUnits_degrees); + PrintHTMLtableCellDouble(htmlFile, delataMiles, kFormat_6_4, kUnits_none); + PrintHTMLtableCellDouble(htmlFile, delataFeet, kFormat_6_4, kUnits_feet); + fprintf(htmlFile, " \n"); + + + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "

    \n"); + } +#endif // _NOT_SURE_YET_ +} +#endif // _ENABLE_LAT_LON_TRACKING_ + +#ifdef _ENABLE_ALTITUDE_TRACKING_ +//************************************************************************************** +void CreateAltitudeHistoryPlot(FILE *htmlFile, const char *imageFolderName, const char *altGraphFileName) +{ +double startX; +double endX; +double labelStepX; +double startY; +double endY; +double labelStepY; +double hourValues[kAltTacking_ArraySize]; +double validAltValues[kAltTacking_ArraySize]; +int validAltIdx; +double maxAltitude; +double minAltitude; +int iii; +int jjj; +double altitude_avg; +double altitude_std; +char legendText[32]; +int currentPtOnGraph; +double scaleFactorX; +double scaleFactorY; + + WebGraph_CreateImage(800, 400); + + maxAltitude = 0; + minAltitude = 0; + validAltIdx = 0; + for (iii=0; iii maxAltitude) + { + maxAltitude = gNMEAdata.altitudeHistory[iii]; + } + if (gNMEAdata.altitudeHistory[iii] < minAltitude) + { + minAltitude = gNMEAdata.altitudeHistory[iii]; + } + + if (gNMEAdata.altitudeHistory[iii] != 0.0) + { + validAltValues[validAltIdx] = gNMEAdata.altitudeHistory[iii]; + + validAltIdx++; + } + } + startX = 0; + endX = 25; + startY = 0.0; + endY = maxAltitude * 1.6; + if (minAltitude < 0) + { + startY = -600; + } + labelStepX = 2; + labelStepY = CalcLabelStepValueY(maxAltitude); + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, kAltTacking_ArraySize, hourValues, gNMEAdata.altitudeHistory, kGraphPointMode_RedLine, &scaleFactorX, &scaleFactorY, true, true, true); + + //***************************************************** + //* figure out where the "current" time on the graph is + currentPtOnGraph = gNMEAdata.gpsTime / kAltTacking_deltaTime; + DrawCurrentPointTimeOnGraph(hourValues[currentPtOnGraph], scaleFactorX, scaleFactorY, (maxAltitude * 2)); + + + altitude_avg = STAT_CalcMean(validAltIdx, validAltValues); + altitude_std = STAT_CalcStdDeviation(validAltIdx, validAltValues); + +#define kLegendWidth_Alt 255 + + jjj = 0; + WebGraph_DrawLegend(jjj++, kGraphPointMode_RedLine, "Altitude (ft)", kLegendWidth_Alt); + + sprintf(legendText, "avgerage = %5.1f", altitude_avg); + WebGraph_DrawLegend(jjj++, -1, legendText, kLegendWidth_Alt); + + sprintf(legendText, "min Alt = %5.1f", gNMEAdata.minAltitude); + WebGraph_DrawLegend(jjj++, -1, legendText, kLegendWidth_Alt); + + sprintf(legendText, "max Alt = %5.1f", gNMEAdata.maxAltitude); + WebGraph_DrawLegend(jjj++, -1, legendText, kLegendWidth_Alt); + + sprintf(legendText, "std dev = %5.1f", altitude_std); + WebGraph_DrawLegend(jjj++, -1, legendText, kLegendWidth_Alt); + + WebGraph_DrawTitle("Altitude History (Alt vs Time (24-hrs))", _gdColorBlack); + + WebGraph_SaveImage(imageFolderName, altGraphFileName); + + if (htmlFile != NULL) + { + fprintf(htmlFile, "\n", imageFolderName, altGraphFileName); + fprintf(htmlFile, "

    \n"); + } +} +#endif // _ENABLE_ALTITUDE_TRACKING_ + +#ifdef _ENABLE_NMEA_POSITION_ERROR_TRACKING_ +//************************************************************************************** +void CreatePositionErrorHistoryPlot(FILE *htmlFile, const char *imageFolderName, const char *posErrGraphFileName) +{ +double startX; +double endX; +double labelStepX; +double startY; +double endY; +double labelStepY; +double hourValues[kPosErrTacking_ArraySize]; +double maxError; +int iii; +int currentPtOnGraph; +double scaleFactorX; +double scaleFactorY; + + CONSOLE_DEBUG(__FUNCTION__); + + WebGraph_CreateImage(800, 400); + + maxError = 0; + for (iii=0; iii maxError) + { + maxError = gNMEAdata.horzPosErrArry[iii]; + } + if (gNMEAdata.vertPosErrArry[iii] > maxError) + { + maxError = gNMEAdata.vertPosErrArry[iii]; + } + if (gNMEAdata.sphrPosErrArry[iii] > maxError) + { + maxError = gNMEAdata.sphrPosErrArry[iii]; + } + } + + startX = 0; + endX = 25; + startY = 0.0; + endY = maxError * 1.2; + labelStepX = 2; + labelStepY = 10; + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, kPosErrTacking_ArraySize, hourValues, gNMEAdata.horzPosErrArry, kGraphPointMode_RedLine, &scaleFactorX, &scaleFactorY, true, true, true); + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, kPosErrTacking_ArraySize, hourValues, gNMEAdata.vertPosErrArry, kGraphPointMode_GreenLine, NULL, NULL, true, true, true); + + WebGraph_GraphDataArray(startX, endX, labelStepX, + startY, endY, labelStepY, kPosErrTacking_ArraySize, hourValues, gNMEAdata.sphrPosErrArry, kGraphPointMode_BlueLine, NULL, NULL, true, true, true); + + + //***************************************************** + //* figure out where the "current" time on the graph is + currentPtOnGraph = gNMEAdata.gpsTime / kPosErrTacking_deltaTime; + DrawCurrentPointTimeOnGraph(hourValues[currentPtOnGraph], scaleFactorX, scaleFactorY, 20000); + + + WebGraph_DrawLegend(0, kGraphPointMode_RedLine, "Horz Error (M)", 230); + WebGraph_DrawLegend(1, kGraphPointMode_GreenLine, "Vert Error (M)", 230); + WebGraph_DrawLegend(2, kGraphPointMode_BlueLine, "Spher Error (M)", 230); + + WebGraph_DrawTitle("Position Error History vs Time (24-hrs) (lower is better)", _gdColorBlack); + WebGraph_SaveImage(imageFolderName, posErrGraphFileName); + + if (htmlFile != NULL) + { + fprintf(htmlFile, "\n", imageFolderName, posErrGraphFileName); + fprintf(htmlFile, "

    \n"); + } +} +#endif + + +#ifdef _ENABLE_MAGNETIC_VARIATION_TRACKING_ + +//************************************************************************************** +static void CreateMagneticVariationHistoryPlot(FILE *htmlFile, const char *imageFolderName, const char *magVarGraphFileName) +{ +double startX; +double endX; +double labelStepX; +double startY; +double endY; +double labelStepY; +double hourValues[kMagVariationTracking_ArraySize]; +int iii; +int currentPtOnGraph; +double scaleFactorX; +double scaleFactorY; + + WebGraph_CreateImage(800, 400); + + for (iii=0; iii\n"); + fprintf(htmlFile, "\n", imageFolderName, magVarGraphFileName); + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "

    \n"); + fprintf(htmlFile, "

    \n"); + } +} +#endif // _ENABLE_MAGNETIC_VARIATION_TRACKING_ + + +#ifdef _ENABLE_HTML_OUTPUT_ + +//************************************************************************************** +int SaveGPS_HTMLandGRAPHS(const char *imageFolderName, const char *htmlFileName, bool dataIsLive) +{ +int iii; +int totalSentanceCnt; +int activeSatCnt; +FILE *htmlFile; +#ifdef _LIVE_DATA_ + char gpsGraphFileName[] = "gps-graph.jpg"; +#else + char gpsGraphFileName[] = "gps-graph1.jpg"; +#endif +char timeString[32]; + + + htmlFile = fopen(htmlFileName, "w"); + if (htmlFile != NULL) + { + + sprintf(timeString, "%02d:%02d:%02d", gNMEAdata.gpsTimeHHMMSS.hours, + gNMEAdata.gpsTimeHHMMSS.minutes, + gNMEAdata.gpsTimeHHMMSS.seconds); + + PrintHTMLheader(htmlFile, "GPS 24 hour performance", "Mark Sproul"); + fprintf(htmlFile, "

    \n"); + + fprintf(htmlFile, "\n"); + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Data source"); + if (dataIsLive) + { + PrintHTMLtableCell(htmlFile, "LIVE"); + } + else + { + PrintHTMLtableCell(htmlFile, "Logfile"); + } + fprintf(htmlFile, " \n"); + + + if (strlen(gNMEAdata.gpsModel) > 0) + { + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "GPS Model"); + PrintHTMLtableCell(htmlFile, gNMEAdata.gpsModel); + fprintf(htmlFile, " \n"); + } + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Valid Date"); + PrintHTMLtableCellBool(htmlFile, gNMEAdata.validDate); + fprintf(htmlFile, " \n"); + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Valid Time"); + PrintHTMLtableCellBool(htmlFile, gNMEAdata.validTime); + fprintf(htmlFile, " \n"); + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Valid Lat/Lon"); + PrintHTMLtableCellBool(htmlFile, gNMEAdata.validLatLon); + fprintf(htmlFile, " \n"); + + + if (strlen(gNMEAdata.mapDatum) > 0) + { + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Map Datum"); + PrintHTMLtableCell(htmlFile, gNMEAdata.mapDatum); + fprintf(htmlFile, " \n"); + } + +// fprintf(htmlFile, " \n"); +// PrintHTMLtableCell(htmlFile, "Time"); +// PrintHTMLtableCell(htmlFile, timeString); +// fprintf(htmlFile, " \n"); + + + if (gNMEAdata.gpsSensorTemp != 0) + { + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "GPS Sensor Temp"); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.gpsSensorTemp, kFormat_6_0, kUnits_degreesC); + fprintf(htmlFile, " \n"); + } + + if (gNMEAdata.zzAlt != 0) + { + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Altitude"); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.zzAlt, kFormat_6_0, kUnits_feet); + fprintf(htmlFile, " \n"); + } + if (gNMEAdata.altitudeMeters != 0) + { + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Altitude"); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.altitudeMeters, kFormat_6_0, kUnits_meters); + fprintf(htmlFile, " \n"); + } + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Latest Date string"); + PrintHTMLtableCell(htmlFile, gNMEAdata.theNN.Date); + fprintf(htmlFile, " \n"); + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Latest Time string"); + PrintHTMLtableCell(htmlFile, gNMEAdata.theNN.Time); + fprintf(htmlFile, " \n"); + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Latest Lat string"); + PrintHTMLtableCell(htmlFile, gNMEAdata.theNN.Lat); + fprintf(htmlFile, " \n"); + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Latest Lon string"); + PrintHTMLtableCell(htmlFile, gNMEAdata.theNN.Lon); + fprintf(htmlFile, " \n"); + + + if (gNMEAdata.magneticVariation != 0) + { + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Magnetic Variation"); + PrintHTMLtableCellDouble(htmlFile, gNMEAdata.magneticVariation, kFormat_6_1, kUnits_degrees); + fprintf(htmlFile, " \n"); + } + + + fprintf(htmlFile, "
    \n"); + + +#ifdef _ENABLE_SATELLITE_TRAILS_ + CreateSatelliteTrailsGraph(htmlFile, imageFolderName, gpsGraphFileName); + CreateSatelliteElevationGraph(htmlFile, imageFolderName, elevationGraphFileName); +#endif + +#ifdef _ENABLE_SATELLITE_ALMANAC_ + CreateSNRdistrbutionPlot(htmlFile, imageFolderName, snrGraphFileName); + + CreateSatsInUseHistoryPlot(htmlFile, imageFolderName, satsInUseGraphFileName); +#endif + + + +#ifdef _ENABLE_LAT_LON_TRACKING_ + CreateLatLonHistoryPlot(htmlFile, imageFolderName, latlonGraphFileName); +#endif + +#ifdef _ENABLE_ALTITUDE_TRACKING_ + CreateAltitudeHistoryPlot(htmlFile, imageFolderName, altGraphFileName); +#endif + + +#ifdef _ENABLE_PDOP_TRACKING_ + CreatePDOPhistoryPlot(htmlFile, imageFolderName, pdopGraphFileName); +#endif + +#ifdef _ENABLE_NMEA_POSITION_ERROR_TRACKING_ + if (gNMEAdata.PGRME_exists) + { + CONSOLE_DEBUG(__FUNCTION__); + CreatePositionErrorHistoryPlot(htmlFile, imageFolderName, posErrGraphFileName); + } +#endif + +#ifdef _ENABLE_MAGNETIC_VARIATION_TRACKING_ + if (gNMEAdata.magneticVariation != 0) + { + CreateMagneticVariationHistoryPlot(htmlFile, imageFolderName, magVarGraphFileName); + } +#endif + +#ifdef _ENABLE_SATELLITE_ALMANAC_ + //********************************************************************************* + fprintf(htmlFile, "\n"); + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "
    idx"); + PrintHTMLtableCell(htmlFile, "
    Sat PRN"); + PrintHTMLtableCell(htmlFile, "
    cnt"); + PrintHTMLtableCell(htmlFile, "
    elev"); + PrintHTMLtableCell(htmlFile, "
    az"); + PrintHTMLtableCell(htmlFile, "
    SNR"); + PrintHTMLtableCell(htmlFile, "
    max SNR"); + fprintf(htmlFile, "
    \n"); + + activeSatCnt = 0; + + for (iii=1; iii 0) + { + fprintf(htmlFile, " \n"); + PrintHTMLtableCell_INT(htmlFile, iii, kFormat_6_0, kUnits_none); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.theSats[iii].satellitePRN, kFormat_6_0, kUnits_none); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.theSats[iii].reportCnt, kFormat_6_0, kUnits_none); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.theSats[iii].elvevation, kFormat_6_0, kUnits_degrees); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.theSats[iii].azimuth, kFormat_6_0, kUnits_degrees); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.theSats[iii].signal2Noise, kFormat_6_0, kUnits_none); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.theSats[iii].maxSNR, kFormat_6_0, kUnits_none); + fprintf(htmlFile, " \n"); + + activeSatCnt++; + } + } + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "
    total"); + PrintHTMLtableCell_INT(htmlFile, activeSatCnt, kFormat_6_0, kUnits_none); + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "
    \n"); +#endif + + +#ifdef _ENABLE_NMEA_SENTANCE_TRACKING_ + //********************************************************************************* + fprintf(htmlFile, "\n"); + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "
    NMEA ID"); + PrintHTMLtableCell(htmlFile, "
    Count"); + PrintHTMLtableCell(htmlFile, "
    Last data"); + fprintf(htmlFile, "
    \n"); + + totalSentanceCnt = 0; + for (iii=0; iii 0) + { + totalSentanceCnt += gNMEAsentances[iii].count; + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, gNMEAsentances[iii].nmeaID); + PrintHTMLtableCell_INT(htmlFile, gNMEAsentances[iii].count, kFormat_6_0, kUnits_none); + PrintHTMLtableCell(htmlFile, gNMEAsentances[iii].lastData); + fprintf(htmlFile, " \n"); + } + } + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "
    total"); + PrintHTMLtableCell_INT(htmlFile, totalSentanceCnt, kFormat_6_0, kUnits_none); + fprintf(htmlFile, "
    \n"); + +// fprintf(htmlFile, " \n"); +// PrintHTMLtableCell(htmlFile, "
    total"); +// PrintHTMLtableCell_INT(htmlFile, gNMEAdataRecorded, kFormat_6_0, kUnits_none); +// fprintf(htmlFile, "
    \n"); + + + + fprintf(htmlFile, "
    \n"); +#endif + + //********************************************************** + fprintf(htmlFile, "\n"); + if (dataIsLive) + { + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Total time adjustments"); + PrintHTMLtableCell_INT(htmlFile, gTimeAdjustmentCount, kFormat_6_0, kUnits_none); + fprintf(htmlFile, " \n"); + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Clock was ahead"); + PrintHTMLtableCell_INT(htmlFile, gTimeAdjustmentAhead, kFormat_6_0, kUnits_none); + fprintf(htmlFile, " \n"); + + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Clock was behind"); + PrintHTMLtableCell_INT(htmlFile, gTimeAdjustmentBehind, kFormat_6_0, kUnits_none); + fprintf(htmlFile, " \n"); + } + fprintf(htmlFile, " \n"); + PrintHTMLtableCell(htmlFile, "Invalid Time reports"); + PrintHTMLtableCell_INT(htmlFile, gNMEAdata.invalidTimeCount, kFormat_6_0, kUnits_none); + fprintf(htmlFile, " \n"); + + + fprintf(htmlFile, "
    \n"); + + + fprintf(htmlFile, "
    \n"); + fprintf(htmlFile, "Compiled %s %s\n", __DATE__, __TIME__); + + + fclose(htmlFile); + htmlFile = NULL; + } + return 0; +} +#endif // _ENABLE_HTML_OUTPUT_ + + +#endif // _ENABLE_GPS_GRAPHS_ diff --git a/src_mlsLib/GPS_graph.h b/src_mlsLib/GPS_graph.h new file mode 100644 index 0000000..2c840c5 --- /dev/null +++ b/src_mlsLib/GPS_graph.h @@ -0,0 +1,28 @@ +//#include "GPS_graph.h" + + +int SaveGPS_HTMLandGRAPHS(const char *imageFolderName, const char *htmlFileName, bool dataIsLive); +void DrawGPS_AlmanacGrid(void); +void CreateSatelliteTrailsGraph( FILE *htmlFile, const char *imageFolderName, const char *gpsGraphFileName); +void CreateLatLonHistoryPlot( FILE *htmlFile, const char *imageFolderName, const char *latlonGraphFileName); +void CreatePDOPhistoryPlot( FILE *htmlFile, const char *imageFolderName, const char *pdopGraphFileName); +void CreatePositionErrorHistoryPlot( FILE *htmlFile, const char *imageFolderName, const char *posErrGraphFileName); +void CreateAltitudeHistoryPlot( FILE *htmlFile, const char *imageFolderName, const char *altGraphFileName); +void CreateSNRdistrbutionPlot( FILE *htmlFile, const char *imageFolderName, const char *snrGraphFileName); +void CreateSatsInUseHistoryPlot( FILE *htmlFile, const char *imageFolderName, const char *satsInUseGraphFileName); +void CreateSatelliteElevationGraph( FILE *htmlFile, const char *imageFolderName, const char *elevationGraphFileName); + +#ifdef _ENABLE_SATELLITE_ALMANAC_ + void DisplayGPSalmanac(TYPE_SatStatsStruct *theSatData, bool showSatNum); +#endif // _ENABLE_SATELLITE_ALMANAC_ + + +//***************************************************************************** +const char elevationGraphFileName[] = "gps-elevation.jpg"; +const char snrGraphFileName[] = "gps-snrplot.jpg"; +const char pdopGraphFileName[] = "gps-pdop.jpg"; +const char altGraphFileName[] = "gps-alt.jpg"; +const char latlonGraphFileName[] = "gps-latlon.jpg"; +const char satsInUseGraphFileName[] = "gps-satsInUse.jpg"; +const char posErrGraphFileName[] = "gps-posErr.jpg"; +const char magVarGraphFileName[] = "gps-magvar.jpg"; diff --git a/src_mlsLib/ParseNMEA.c b/src_mlsLib/ParseNMEA.c index 832a251..76f9a6c 100755 --- a/src_mlsLib/ParseNMEA.c +++ b/src_mlsLib/ParseNMEA.c @@ -7,6 +7,7 @@ //************************************************************************************** //* Edit History //************************************************************************************** +//* Apr 14, 1996 Put the boxes for the Heads-Up-Display into a Dialog Box template //* Apr 19, 1996 Separated NMEA and APRS Parse Routines //* Dec 11, 1996 Removed UpdateHUDdisplay to a different file //* Dec 26, 1996 Dave VanHorn dvanhron@cedar.net @@ -51,12 +52,19 @@ //* May 15, 2017 Added Mode tracking (1=no fix,2=2D,3=3D) //* May 15, 2017 Added Magnetic variation tracking //* May 25, 2017 Added parsing of $PRWIZCH sat signal data +//* Jun 9, 2017 Added gTimeAdjustmentCount +//* Jun 12, 2017 Added _ENABLE_SATELLITE_TRAILS_ +//* Jun 12, 2017 Added SaveSatelliteTrails() +//* Jun 15, 2017 Added min/max altitude tracking +//* Jul 11, 2017 Added logic in Check_And_Set_System_Time() to prevent setting time in the past +//* Jul 12, 2017 Time must be off by 2 or more seconds before update occurs //* Sep 5, 2023 Removing global gNMEAdata, replacing with pointer //* Sep 9, 2023 Added GetLatLonDouble() //* Sep 9, 2023 Added ParseNMEA_FormatLatLonStrings() //* Apr 10, 2024 Added ComputeLatLonAverage() //* Apr 12, 2024 Added timing tests to ComputeLatLonAverage() //* Apr 13, 2024 Added altitude to averaging logic +//* Apr 16, 2024 Added GetGPSmodeString() //************************************************************************************** #include @@ -102,6 +110,10 @@ static void NMEAtrack_Update(const unsigned long nmeaCode, const char *nmeaID, const char *fullString); #endif +int gTimeAdjustmentCount = 0; //* number of times we have adjusted the time +int gTimeAdjustmentAhead = 0; +int gTimeAdjustmentBehind = 0; + static int gMaxSatelliteSNRvalue = 0; static unsigned long gNMEAcheckSumErrCnt = 0; static unsigned long gUnknownNEMAcount = 0; @@ -110,6 +122,14 @@ static unsigned long gUnknownNEMAcount = 0; char gLastNMEAdata[512]; #endif + +#ifdef _ENABLE_SATELLITE_TRAILS_ + TYPE_SatTrailsStruct gSatTrails[kMaxNumOfSatallites]; + bool gSatTrailsNeedsInit = true; + int gSatTrailsLastIdx = 0; +#endif + + //************************************************************************************** //* this is done as a stucture so it can be easily passed to routines instead of being a global typedef struct @@ -631,6 +651,16 @@ static void TrackAltitudeValue(TYPE_NMEAInfoStruct *theNmeaInfo, const double al { int altIndex; + if (altitude_feet < theNmeaInfo->minAltitude) + { + theNmeaInfo->minAltitude = altitude_feet; + } + if (altitude_feet > theNmeaInfo->maxAltitude) + { + theNmeaInfo->maxAltitude = altitude_feet; + } + + //* we have a valid time, so we can save the altitude value altIndex = theNmeaInfo->gpsTime / kAltTacking_deltaTime; if (altIndex < kAltTacking_ArraySize) @@ -640,6 +670,62 @@ int altIndex; } #endif // _ENABLE_ALTITUDE_TRACKING_ +#ifdef _ENABLE_SATELLITE_TRAILS_ +//************************************************************************************** +void InitSatelliteTrails(void) +{ +int jj; + + for (jj=0; jjgpsTime > 0) + { + SaveSatelliteTrails(theNmeaInfo->gpsTime, theNmeaInfo->theSats); + } + #endif // _ENABLE_SATELLITE_TRAILS_ + + #endif } @@ -1632,20 +1732,20 @@ int ii; theNmeaInfo->sphericalPosErr = atof(nmeaArgs[5].argString); #ifdef _ENABLE_NMEA_POSITION_ERROR_TRACKING_ theNmeaInfo->gPGRME_exists = true; - if (theNmeaInfo->gpsTime > 0) - { - int trackIndex; + if (theNmeaInfo->gpsTime > 0) + { + int trackIndex; - //* we have a valid time, so we can save the altitude value - trackIndex = theNmeaInfo->gpsTime / kPosErrTacking_deltaTime; - if (trackIndex < kPosErrTacking_ArraySize) - { - theNmeaInfo->horzPosErrArry[trackIndex] = theNmeaInfo->horizontalPosErr; - theNmeaInfo->vertPosErrArry[trackIndex] = theNmeaInfo->verticalPosErr; - theNmeaInfo->sphrPosErrArry[trackIndex] = theNmeaInfo->sphericalPosErr; - } + //* we have a valid time, so we can save the altitude value + trackIndex = theNmeaInfo->gpsTime / kPosErrTacking_deltaTime; + if (trackIndex < kPosErrTacking_ArraySize) + { + theNmeaInfo->horzPosErrArry[trackIndex] = theNmeaInfo->horizontalPosErr; + theNmeaInfo->vertPosErrArry[trackIndex] = theNmeaInfo->verticalPosErr; + theNmeaInfo->sphrPosErrArry[trackIndex] = theNmeaInfo->sphericalPosErr; } + } #endif break; @@ -1879,7 +1979,7 @@ bool processedOK; //====================================================================== //* $Pxxx ==> Propritary data processedOK = ParseNMEAstringsProprietary(theNMEAstring, - nmeaData->, + nmeaData, &nmeaData->theNN, nmeaArgs); @@ -1910,6 +2010,10 @@ bool processedOK; #endif } } + else + { + CONSOLE_DEBUG_W_STR("Invalid NMEA data=", theNMEAstring); + } return(validString); } @@ -2042,6 +2146,7 @@ int ii; char theDateString[16]; char theTimeString[16]; bool allDigitsFlag; +bool timeStringValid; //TYPE_timeHHMMSS timeHHMMSS; int commaCntr; int slen; @@ -2089,6 +2194,7 @@ int slen; } //* make sure they are all digits allDigitsFlag = true; + timeStringValid = true; for (ii=0; ii<6; ii++) { if (isdigit(theDateString[ii]) == false) @@ -2102,7 +2208,12 @@ int slen; break; } } - + //* check for all 0's + if (strcmp(theTimeString, "000000") == 0) + { + timeStringValid = false; + nmeaData->invalidTimeCount++; //* keep track of the number of invalid time records + } //* do we have all valid data if (allDigitsFlag) { @@ -2193,12 +2304,33 @@ void GetCurrentLatLon_Strings(TYPE_NMEAInfoStruct *nmeaData, char *theLonStr,cha Get_Actual_LatLon_Strings(nmeaData->xxLon, nmeaData->yyLat, theLonStr, theLatStr, includeLabel); } +//***************************************************************************** +void GetGPSmodeString(char gpsMode1, char gpsMode2, char *modeString) +{ + modeString[0] = 0; + switch (gpsMode1) + { + case 'A': strcpy(modeString, "Automatic: "); break; + case 'M': strcpy(modeString, "Manual: "); break; + default: strcpy(modeString, "Unknown: "); break; + } + + switch (gpsMode2) + { + case '1': strcat(modeString, "Fix not available"); break; + case '2': strcat(modeString, "2D Fix"); break; + case '3': strcat(modeString, "3D Fix"); break; + default: strcat(modeString, "Unknown: "); break; + } +} + #pragma mark - #pragma mark NMEA sentance tracking #ifdef _ENABLE_NMEA_SENTANCE_TRACKING_ TYPE_NMEAsentance gNMEAsentances[kMaxNMEAsentances]; int gNMEAsentanceCnt = -1; +int gNMEAdataRecorded = 0; //************************************************************************************** static int QsortNMEAsentance(const void *e1, const void *e2) @@ -2222,6 +2354,7 @@ bool keepLooking; // CONSOLE_DEBUG_W_HEX("nmeaCode", nmeaCode); // CONSOLE_DEBUG_W_STR("nmeaID", nmeaID); // CONSOLE_DEBUG_W_STR("fullString", fullString); + gNMEAdataRecorded++; //* if the table is blank, zero it. if (gNMEAsentanceCnt < 0) @@ -2238,7 +2371,7 @@ bool keepLooking; //* now see if we can find it in the table ii = 0; keepLooking = true; - while (keepLooking && (ii + +//************************************************************************************** +//* These are configured in the Makefile //************************************************************************************** //* configuration options, comment out to save memory //#define _ENABLE_ALTITUDE_TRACKING_ @@ -47,12 +50,17 @@ //#define _ENABLE_NMEA_SENTANCE_TRACKING_ //#define _ENABLE_NMEA_POSITION_ERROR_TRACKING_ //#define _ENABLE_PROPRIETARY_PARSING_ -#define _ENABLE_SATELLITE_ALMANAC_ +//#define _ENABLE_SATELLITE_ALMANAC_ //#define _ENABLE_WAYPOINT_PARSING_ //************************************************************************************** +#if defined(_ENABLE_SATELLITE_TRAILS_) && !defined(_ENABLE_SATELLITE_ALMANAC_) + #error _ENABLE_SATELLITE_TRAILS_ cannot be enabled without _ENABLE_SATELLITE_ALMANAC_ +#endif + + #ifndef __cplusplus #include #endif @@ -119,12 +127,34 @@ typedef struct short elvevation; //* Elevation in degrees, 90 maximum short azimuth; //* Azimuth, degrees from true north, 000 to 359 short signal2Noise; //* Signal to Noise Ratio, 00-99 dB (null when not tracking) - short maxSNR; //* max SNR seen on this sat + short maxSNR; //* max SNR seen on this satellite char prn[kSatDataLen]; //* SV PRN number (Pseudo Random Noise) } TYPE_SatStatsStruct; #endif +#ifdef _ENABLE_SATELLITE_TRAILS_ +//***************************************************************************** +//* satetllite trails + +//* this HAS to be 60 +#define kSatTrails_deltaTime 60 //*seconds between data points +#define kSatTrails_ArraySize ((24 * 60 * 60) / kSatTrails_deltaTime) + +typedef struct +{ + short satellitePRN; //* SV PRN number (Pseudo Random Noise) + short elvevation[kSatTrails_ArraySize]; //* Elevation in degrees, 90 maximum + short azimuth[kSatTrails_ArraySize]; //* Azimuth, degrees from true north, 000 to 359 + short signal2Noise[kSatTrails_ArraySize]; //* Signal to Noise Ratio, 00-99 dB (null when not tracking) + +} TYPE_SatTrailsStruct; + +extern TYPE_SatTrailsStruct gSatTrails[kMaxNumOfSatallites]; +extern int gSatTrailsLastIdx; + +#endif + //***************************************************************************** // By having this stuff in a structure, it allows a single memset to clear the entire set typedef struct @@ -188,7 +218,7 @@ typedef struct } TYPE_timeHHMMSS; //* 15 minute interval -#define kLoggingIntervalMinutes 10 +#define kLoggingIntervalMinutes 1 #ifdef _ENABLE_PDOP_TRACKING_ #define kPDOPtacking_deltaTime (kLoggingIntervalMinutes * 60) @@ -237,6 +267,7 @@ typedef struct unsigned long gpsTime; // Time in seconds since midnight (GMT) TYPE_timeHHMMSS gpsTimeHHMMSS; //* Time in HH:MM:SS - added Oct 3, 2016 unsigned long deltaGPSTime; + unsigned long invalidTimeCount; LatLonType latitude; LatLonType longitude; double lat_double; @@ -293,6 +324,8 @@ typedef struct #ifdef _ENABLE_ALTITUDE_TRACKING_ double altitudeHistory[kAltTacking_ArraySize]; + double minAltitude; + double maxAltitude; #endif double horizontalPosErr; @@ -311,7 +344,15 @@ typedef struct double magVariationArray[kMagVariationTracking_ArraySize]; #endif + //------------------------------------------------------------------------------ + //* for AlpacaPi so that we can display this info on a live web page + double latitude_avg; + double latitude_std; + double longitude_avg; + double longitude_std; + + //------------------------------------------------------------------------------ //* for MacAPRS long xxLon; // Internal Units (100'ts of an arc second) long yyLat; // Internal Units (100'ts of an arc second) @@ -323,25 +364,26 @@ typedef struct extern TYPE_NMEAInfoStruct gNMEAdata; #ifdef _ENABLE_SATELLITE_ALMANAC_ -// int GetSatSignalStrength(int satNumber); int GetSatSignalStrength(TYPE_NMEAInfoStruct *nmeaData, int satNumber); #endif -void ParseNMEA_init(TYPE_NMEAInfoStruct *nmeaData); -bool ParseNMEAstring(TYPE_NMEAInfoStruct *nmeaData, char *theNMEAstring); -//bool ParseNMEA_TimeString(char *theNMEAstring, bool setSystemTime); -bool ParseNMEA_TimeString(TYPE_NMEAInfoStruct *nmeaData, char *theNMEAstring, bool setSystemTime); +void ParseNMEA_init( TYPE_NMEAInfoStruct *nmeaData); +bool ParseNMEAstring( TYPE_NMEAInfoStruct *nmeaData, char *theNMEAstring); +bool ParseNMEA_TimeString( TYPE_NMEAInfoStruct *nmeaData, char *theNMEAstring, bool setSystemTime); +void GetCurrentLatLon_Strings( TYPE_NMEAInfoStruct *nmeaData, char *theLonStr,char *theLatStr, bool includeLabel); +void DumpGPSdata( TYPE_NMEAInfoStruct *theNmeaInfo); void Get_Actual_LatLon_Strings(long theLon, long theLat, char *theLonStr,char *theLatStr, bool includeLabel); int Ascii2charsToInt(const char *charPtr); -//void GetCurrentLatLon_Strings(char *theLonStr,char *theLatStr, bool includeLabel); -void GetCurrentLatLon_Strings(TYPE_NMEAInfoStruct *nmeaData, char *theLonStr,char *theLatStr, bool includeLabel); int GetMaxSatSignalStrength(void); -void DumpGPSdata(TYPE_NMEAInfoStruct *theNmeaInfo); double GetLatLonDouble(LatLonType *latLonPtr); void ParseNMEA_FormatLatLonStrings(double latValue, char *latString, double lonValue, char *lonString); +void GetGPSmodeString(char gpsMode1, char gpsMode2, char *modeString); +extern int gTimeAdjustmentCount; //* number of times we have adjusted the time +extern int gTimeAdjustmentAhead; +extern int gTimeAdjustmentBehind; #ifdef _ENABLE_NMEA_SENTANCE_TRACKING_ @@ -360,6 +402,8 @@ typedef struct #define kMaxNMEAsentances 50 extern TYPE_NMEAsentance gNMEAsentances[kMaxNMEAsentances]; +extern int gNMEAsentanceCnt; +extern int gNMEAdataRecorded; #endif diff --git a/src_mlsLib/Statistics.c b/src_mlsLib/Statistics.c new file mode 100644 index 0000000..17d66e2 --- /dev/null +++ b/src_mlsLib/Statistics.c @@ -0,0 +1,247 @@ +//***************************************************************************** +//* Statistics.c +//* +//* by Mark Sproul 2016 +//***************************************************************************** +//* Nov 9, 2016 Started on Statistics.c +//* Nov 9, 2016 Added STAT_Rand_SD() +//* Nov 9, 2016 Added STAT_GenerateData_SD() +//* Nov 9, 2016 Added STAT_CalcMean() +//* Nov 9, 2016 Added STAT_CalcVariance() +//* Nov 9, 2016 Added STAT_CalcStdDeviation() +//* Dec 9, 2016 Added STAT_GetMinimum() & STAT_GetMaximum() +//* Jan 26, 2017 Added STAT_CalcSigmaForX() & STAT_CalcSigmaCurve() +//***************************************************************************** + + + +#include +#include +#include + +#define _ENABLE_CONSOLE_DEBUG_ +#include "ConsoleDebug.h" + + +#include "Statistics.h" + +#ifndef M_PI + #define M_PI (3.14159265358979323846) +#endif + +//***************************************************************************** +double STAT_Rand_SD(double mu, double sigma) +{ +double U1, U2, W, mult; +static double X1, X2; +static int call = 0; + + if (call == 1) + { + call = !call; + return (mu + sigma * (double) X2); + } + + do + { + U1 = -1 + ((double) rand() / RAND_MAX) * 2; + U2 = -1 + ((double) rand() / RAND_MAX) * 2; + + W = pow (U1, 2) + pow (U2, 2); + } while (W >= 1 || W == 0); + + mult = sqrt ((-2 * log (W)) / W); + X1 = U1 * mult; + X2 = U2 * mult; + + call = !call; + + return (mu + sigma * (double) X1); +} + + +//***************************************************************************** +void STAT_GenerateData_SD(const double mu, const double stadDev, const int numValues, double *dataArray) +{ +int ii; + + if (dataArray != NULL) + { + for (ii=0; ii myMax) + { + myMax = dataArray[ii]; + } + } + return(myMax); +} + + +#pragma mark - +//***************************************************************************** +//* https://en.wikipedia.org/wiki/Standard_deviation +//***************************************************************************** +double STAT_CalcSigmaForX(double xx, double mean, double sigma) +{ +double term1; +double term2; +double sigmaYvalue; + + term1 = 1.0 / (sigma * sqrt(2 * M_PI)); + term2 = exp(-0.5 * pow(((xx - mean) / sigma), 2)); + sigmaYvalue = term1 * term2; + return(sigmaYvalue); +} + +//***************************************************************************** +//* returns the max value +double STAT_CalcSigmaCurve(double mean, double sigma, int numValues, double *xValues, double *yValues) +{ +int ii; +double maxValue; + + maxValue = 0; + for (ii=0; ii maxValue) + { + maxValue = yValues[ii]; + } + } + return(maxValue); +} + + +#if 0 +#define kNumValues 1000 + +//***************************************************************************** +int main(int argc, char **argv) +{ +double array[kNumValues]; +double meanAvg; +double variance; +double std_deviation; +int ii; +unsigned int seedValue; + + if (argc > 1) + { + seedValue = atoi(argv[1]); + srand(seedValue); + } + + printf("Stat gen\r\n"); + + STAT_GenerateData_SD(100.0, 3, kNumValues, array); + + for (ii=0; ii Created web_graphics_opencv.cpp +//* Apr 26, 2024 Started on opencv version of web_graphics librar +//************************************************************************************** + +#include +#include + +#include "web_graphics_opencv.h" + +#define _ENABLE_CONSOLE_DEBUG_ +#include "ConsoleDebug.h" + +#define kLegendLineHeight 25 +#define kXdotLen 4 +#define kXcircleDiam 7 +#define kXcircleDiamLarge 15 + +cv::Scalar _gdColorBlack = CV_RGB(0, 0, 0); +cv::Scalar _gdColorGrey = CV_RGB(128, 128, 128); +cv::Scalar _gdColorLtGrey = CV_RGB(200, 200, 200); +cv::Scalar _gdColorWhite = CV_RGB(255, 255, 255); +cv::Scalar _gdColorRed = CV_RGB(255, 0, 0); +cv::Scalar _gdColorPink = CV_RGB(255, 0, 230); +cv::Scalar _gdColorGreen = CV_RGB(88, 255, 88); +cv::Scalar _gdColorDkGreen = CV_RGB(0, 196, 0); +cv::Scalar _gdColorBlue = CV_RGB(0, 0, 255); +cv::Scalar _gdColorCyan = CV_RGB(0, 255, 255); +cv::Scalar _gdColorMagenta = CV_RGB(255, 0, 255); +cv::Scalar _gdColorYellow = CV_RGB(255, 255, 0); +cv::Scalar _gdColorOrange = CV_RGB(255, 128, 0); +cv::Scalar _gdColorCopper = CV_RGB(0xC9, 0x63, 0x33); + + +int _xCenter; +int _yCenter; + +static int _currentXsize; +static int _currentYsize; +static double _cosZangle; +static double _sinZangle; + +static cv::Mat *gWebGrapicsImage = NULL; +static int gCurrentLineWidth = 1; +static cv::Scalar gCurrentColor = CV_RGB(255, 0, 0); + +#define kMaxColors 100 +static cv::Scalar gWebGraphicsColorTable[kMaxColors]; +static bool gWebGrapicsInitColorTable = true; +//***************************************************************************** +static void WebGraph_InitColorTable(void) +{ +int iii; + +// CONSOLE_DEBUG(__FUNCTION__); + for (iii=0; iii= 3) + cv::FILLED // int thickness CV_DEFAULT(1), + #else + CV_FILLED + #endif + ); + + } +} + +//***************************************************************************** +bool WebGraph_CheckImage(const char *routineName, const int lineNum) +{ + + return(false); +} + +//***************************************************************************** +int WebGraph_SaveImage(const char *pathName, const char *fileName) +{ +int openCVerr; +char outputFileName[256]; + + if (gWebGrapicsImage != NULL) + { + strcpy(outputFileName, pathName); + strcat(outputFileName, "/"); + strcat(outputFileName, fileName); + + openCVerr = cv::imwrite(outputFileName, *gWebGrapicsImage); + if (openCVerr == 0) + { + CONSOLE_DEBUG_W_NUM("cv::imwrite returned error\t=", openCVerr); + } + //---try------try------try------try------try------try--- + try + { + // CONSOLE_DEBUG("try delete cOpenCV_matImage"); + delete gWebGrapicsImage; + gWebGrapicsImage = NULL; + } + catch(cv::Exception& ex) + { + CONSOLE_DEBUG("delete gWebGrapicsImage; had an exception"); + CONSOLE_DEBUG_W_NUM("openCV error code\t=", ex.code); + } + } + + return(0); +} + + +//************************************************************************************** +int WebGraph_TranslateXvalue(int xCordinate, int zCordinate) +{ +int screenX; +int zXoffset; + + zXoffset = zCordinate * _cosZangle; + screenX = _xCenter + xCordinate + zXoffset; + return(screenX); +} + +//************************************************************************************** +int WebGraph_TranslateYvalue(int yCordinate, int zCordinate) +{ +int screenY; +int zYoffset; + + zYoffset = zCordinate * _sinZangle; + screenY = _yCenter - yCordinate + zYoffset; + return(screenY); +} + +//***************************************************************************** +void WebGraph_DrawScaleX2(double scaleX, cv::Scalar color) +{ + CONSOLE_DEBUG("Not finished"); +} + +//***************************************************************************** +void WebGraph_DrawAxis(int style, cv::Scalar color) +{ +int vectorLen; + +#ifdef _GRAPH_DEBUG_AXIS_ + CONSOLE_DEBUG_W_NUM("style\t=", style); +#endif + switch(style) + { + case kAxisStyle_3D: + _xCenter = _currentXsize / 4; + _yCenter = (_currentYsize / 2) + (_currentYsize / 10); + WebGraph_DrawVector(0, 0, 0, (_currentXsize / 2), 0, 0, color, "e1"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize / 2), 0, color, "e2"); + WebGraph_DrawVector(0, 0, 0, 0, 0, (_currentYsize / 5), color, "e3"); + break; + + case kAxisStyle_XYZ_abs: + _xCenter = _currentXsize / 4; + _yCenter = (_currentYsize / 2) + (_currentYsize / 10); + WebGraph_DrawVector(0, 0, 0, (_currentXsize / 2), 0, 0, color, "X"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize / 2), 0, color, "Y"); + WebGraph_DrawVector(0, 0, 0, 0, 0, (_currentYsize / 5), color, "Z"); + break; + + + case kAxisStyle_3D_abs: + _xCenter = _currentXsize / 4; + _yCenter = (_currentYsize / 2) + (_currentYsize / 10); + WebGraph_DrawVector(0, 0, 0, (_currentXsize / 2), 0, 0, color, "S"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize / 2), 0, color, "alpha"); + WebGraph_DrawVector(0, 0, 0, 0, 0, (_currentYsize / 5), color, "i-beta"); + break; + + case kAxisStyle_XY: + _xCenter = 75; + _yCenter = _currentYsize - 50; + WebGraph_DrawVector(0, 0, 0, (_currentXsize - 65), 0, 0, color, "X"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize - 60), 0, color, "Y"); + break; + + case kAxisStyle_XY_NoLabels: + _xCenter = 75; + _yCenter = _currentYsize - 50; + WebGraph_DrawVector(0, 0, 0, (_currentXsize - 65), 0, 0, color, ""); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize - 60), 0, color, ""); + break; + + + + case kAxisStyle_XY_640x800: + #ifdef _GRAPH_DEBUG_AXIS_ + CONSOLE_DEBUG("kAxisStyle_XY_640x800"); + #endif + _xCenter = 50; + _yCenter = _currentYsize - 150; + WebGraph_DrawVector(0, 0, 0, (_currentXsize - 65), 0, 0, color, "X"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize - 60), 0, color, "Y"); + break; + + + case kAxisStyle_XT: + _xCenter = 50; + _yCenter = _currentYsize - 50; + WebGraph_DrawVector(0, 0, 0, (_currentXsize - 65), 0, 0, color, "x"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize - 60), 0, color, "t"); + break; + + case kAxisStyle_UP: + _xCenter = 50; + _yCenter = _currentYsize - 50; + WebGraph_DrawVector(0, 0, 0, (_currentXsize - 65), 0, 0, color, "u"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize - 60), 0, color, "p (GPa)"); + break; + + case kAxisStyle_UP_centered: + _xCenter = _currentXsize / 2; + _yCenter = _currentYsize - 50; + vectorLen = (_currentXsize / 20) * 9; +// WebGraph_DrawVector(0, 0, 0, (_currentXsize - 65), 0, 0, color, "u"); + WebGraph_DrawVector(0, 0, 0, vectorLen, 0, 0, color, "u"); + WebGraph_DrawVector(0, 0, 0, -vectorLen, 0, 0, color, "-u"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize - 60), 0, color, "p (GPa)"); + break; + + + case kAxisStyle_UP_4Quads: + _xCenter = _currentXsize / 2; + _yCenter = _currentYsize / 2; + vectorLen = (_currentXsize / 20) * 9; + WebGraph_DrawVector(0, 0, 0, vectorLen, 0, 0, color, "u"); + WebGraph_DrawVector(0, 0, 0, -vectorLen, 0, 0, color, "-u"); + WebGraph_DrawVector(0, 0, 0, 0, ((_currentYsize / 2) - 40), 0, color, "p"); + WebGraph_DrawVector(0, 0, 0, 0, -((_currentYsize / 2) - 40), 0, color, "-p"); + break; + + case kAxisStyle_XY_abs: + _xCenter = 50; + _yCenter = _currentYsize - 30; + WebGraph_DrawVector(0, 0, 0, (_currentXsize - 65), 0, 0, color, "S"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize - 40), 0, color, "sqrt(alpha^2 + beta^2)"); + break; + + + case kAxisStyle_XY_centered: + _xCenter = _currentXsize / 2; + _yCenter = _currentYsize / 2; + vectorLen = (_currentXsize / 20) * 9; + WebGraph_DrawVector(0, 0, 0, vectorLen, 0, 0, color, ""); + WebGraph_DrawVector(0, 0, 0, -vectorLen, 0, 0, color, ""); + WebGraph_DrawVector(0, 0, 0, 0, vectorLen, 0, color, ""); + WebGraph_DrawVector(0, 0, 0, 0, -vectorLen, 0, color, ""); + break; + + case kAxisStyle_XY_compass: + _xCenter = _currentXsize / 2; + _yCenter = _currentYsize / 2; + vectorLen = (_currentXsize / 20) * 9; + WebGraph_DrawVector(0, 0, 0, vectorLen, 0, 0, color, "E (90)"); + WebGraph_DrawVector(0, 0, 0, -vectorLen, 0, 0, color, "W (270)"); + WebGraph_DrawVector(0, 0, 0, 0, vectorLen, 0, color, "N (0)"); + WebGraph_DrawVector(0, 0, 0, 0, -vectorLen, 0, color, "S (180)"); + break; + + + case kAxisStyle_PolarXY: + _xCenter = _currentXsize / 2; + _yCenter = _currentYsize / 2; + WebGraph_DrawVector(0, 0, 0, (_currentXsize / 3), 0, 0, color, "x"); + WebGraph_DrawVector(0, 0, 0, -(_currentXsize / 3), 0, 0, color, "-x"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize / 3), 0, color, "y"); + WebGraph_DrawVector(0, 0, 0, 0, -(_currentYsize / 3), 0, color, "-y"); + break; + + + + case kAxisStyle_e3e1: + _xCenter = _currentXsize / 2; + _yCenter = _currentYsize / 2; + WebGraph_DrawVector(0, 0, 0, (_currentXsize / 3), 0, 0, color, "e3"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize / 3), 0, color, "e1"); + WebGraph_Draw2DCircle(0, 0, 20, 20, color); + break; + + case kAxisStyle_e1e2: + _xCenter = _currentXsize / 2; + _yCenter = _currentYsize / 2; + WebGraph_DrawVector(0, 0, 0, (_currentXsize / 3), 0, 0, color, "e1"); + WebGraph_DrawVector(0, 0, 0, 0, (_currentYsize / 3), 0, color, "e2"); + WebGraph_Draw2DCircle(0, 0, 20, 20, color); + break; + + case kAxisStyle_AlhpaBeta: + _xCenter = _currentXsize / 2; + _yCenter = _currentYsize / 2; + vectorLen = (_currentXsize / 20) * 9; + + WebGraph_DrawVector(0, 0, 0, vectorLen, 0, 0, color, "i-beta"); + WebGraph_DrawVector(0, 0, 0, -vectorLen, 0, 0, color, ""); + WebGraph_DrawVector(0, 0, 0, 0, vectorLen, 0, color, "alpha"); + WebGraph_DrawVector(0, 0, 0, 0, -vectorLen, 0, color, ""); + break; + + + } + +#ifdef _GRAPH_DEBUG_AXIS_ + CONSOLE_DEBUG_W_NUM("_currentXsize\t=", _currentXsize); + CONSOLE_DEBUG_W_NUM("_currentYsize\t=", _currentYsize); + CONSOLE_DEBUG_W_NUM("_xCenter\t=", _xCenter); + CONSOLE_DEBUG_W_NUM("_yCenter\t=", _yCenter); +#endif + +// WebGraph_DrawText("e1", (_currentXsize / 3), 0, 0, color); +// WebGraph_DrawText("e2", 5, (_currentXsize / 3), 0, color); + +} + +//***************************************************************************** +void WebGraph_DrawScaleTickMarks_X(double deltaPixelsX, double startValueX, double deltaValueX, cv::Scalar color) +{ +double screenX_DBL; +int screenX, screenY; +double scaleValue; +char scaleText[32]; +bool useFractionFormat; +int tickCount; + +// CONSOLE_DEBUG(__FUNCTION__); + + screenY = -5; + screenX = 0; + scaleValue = startValueX; + screenX_DBL = screenX; + tickCount = 0; + if (deltaValueX < 1.0) + { + useFractionFormat = true; + } + else + { + useFractionFormat = false; + } + if (deltaPixelsX > 0) + { + while ((screenX < _currentXsize) && (tickCount < 1000)) + { + WebGraph_Draw3Dline(screenX, -3, 0, screenX, 3, 0, color); + + if (useFractionFormat || ((scaleValue > 0.0) && (scaleValue < 0.9))) + { + useFractionFormat = true; + if (deltaValueX >= 1.0) + { + sprintf(scaleText, "%3.1f", scaleValue); + } + else if (deltaValueX >= 0.1) + { + sprintf(scaleText, "%3.2f", scaleValue); + } + else if (deltaValueX >= 0.01) + { + sprintf(scaleText, "%3.2f", scaleValue); + } + else + { + sprintf(scaleText, "%3.3f", scaleValue); + } + } + else + { + sprintf(scaleText, "%1.0f", scaleValue); + } + + WebGraph_DrawText(scaleText, screenX, screenY, 0, color); + + scaleValue += deltaValueX; + screenX_DBL += deltaPixelsX; + screenX = screenX_DBL; + tickCount++; + } + } + else if (deltaPixelsX < 0) + { + while (-screenX < _currentXsize) + { + WebGraph_Draw3Dline(screenX, -3, 0, screenX, 3, 0, color); + + sprintf(scaleText, "%1.0f", scaleValue); + + WebGraph_DrawText(scaleText, screenX, screenY, 0, color); + + scaleValue += deltaValueX; + screenX += deltaPixelsX; + } + } + else + { + CONSOLE_DEBUG("Program error: deltaPixelsX is zero"); + } +} + +//***************************************************************************** +void WebGraph_DrawScaleTickMarks_Y(double deltaPixelsY, double startValueY, double deltaValueY, cv::Scalar color) +{ +double screenY_DBL; +int screenX, screenY; +double scaleValue; +char scaleText[32]; +bool useFractionFormat; +int loopCntr; + +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG("WebGraph_DrawScaleTickMarks_Y"); + CONSOLE_DEBUG_W_DBL("deltaPixelsY =", deltaPixelsY); + CONSOLE_DEBUG_W_DBL("deltaValueY =", deltaValueY); +#endif + + screenX = -5; + screenY = 0; + scaleValue = startValueY; + screenY_DBL = screenY; + + if (deltaValueY < 1.0) + { + useFractionFormat = true; + } + else + { + useFractionFormat = false; + } + if (deltaPixelsY > 0.0) + { + loopCntr = 0; + while ((screenY < _currentYsize) && (loopCntr < 1000)) + { + #ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_NUM("screenY =", screenY); + CONSOLE_DEBUG_W_DBL("deltaPixelsY =", deltaPixelsY); + #endif + WebGraph_Draw3DlineDashed(-3, screenY, 0, +3, screenY, 0, color); + + if (useFractionFormat || ((scaleValue > 0.0) && (scaleValue < 0.9))) + { + useFractionFormat = true; + if (deltaValueY >= 0.1) + { + sprintf(scaleText, "%3.1f", scaleValue); + } + else if (deltaValueY >= 0.01) + { + sprintf(scaleText, "%3.2f", scaleValue); + } + else if (deltaValueY < 0.001) + { + sprintf(scaleText, "%3.5f", scaleValue); + } + else + { + sprintf(scaleText, "%3.3f", scaleValue); + } + } + else + { + sprintf(scaleText, "%1.0f", scaleValue); + } + WebGraph_DrawText(scaleText, (screenX - 25), (screenY + 7), 0, color); + + scaleValue += deltaValueY; + screenY_DBL += deltaPixelsY; + screenY = screenY_DBL; + + loopCntr++; + } + if (loopCntr > 900) + { + CONSOLE_DEBUG_W_NUM("too many loops; loopCntr =", loopCntr); + } + } + else if (deltaPixelsY < 0.0) + { + screenX = -5; + screenY = 0; + scaleValue = startValueY; + while (-screenY < _currentYsize) + { + #ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_NUM("screenY =", screenY); + #endif + WebGraph_Draw3DlineDashed(-3, screenY, 0, +3, screenY, 0, color); + + if ((scaleValue > 0.0) && (scaleValue < 0.9)) + { + sprintf(scaleText, "%3.3f", scaleValue); + } + else + { + sprintf(scaleText, "%1.0f", scaleValue); + } + WebGraph_DrawText(scaleText, (screenX - 25), (screenY + 7), 0, color); + + scaleValue += deltaValueY; + screenY += deltaPixelsY; + } + } + else + { + CONSOLE_DEBUG("Program error: deltaPixelsY is zero"); + } + +// CONSOLE_DEBUG("WebGraph_DrawScaleTickMarks_Y EXIT"); + + +} + +//************************************************************************************** +static void WebGraph_DrawVectorArrowHead(int x1, int y1, int z1, int x2, int y2, int z2, cv::Scalar color) +{ +int deltaX, deltaY, deltaZ; +double angle; +double angle180; +int myX1; +int myY1; +int myX2; +int myY2; +int arrowDx; +int arrowDy; +double pointLen = 12.0; +double arrowPtAngle; + +#ifdef _DEBUG_IMAGE_ + CONSOLE_DEBUG_W_HEX("_gWebimGD\t=", _gWebimGD); +#endif + if (gWebGrapicsImage != NULL) + { + myX1 = WebGraph_TranslateXvalue(x1, z1); + myY1 = WebGraph_TranslateYvalue(y1, z1); + myX2 = WebGraph_TranslateXvalue(x2, z2); + myY2 = WebGraph_TranslateYvalue(y2, z2); + + deltaX = myX2 - myX1; + deltaY = -(myY2 - myY1); + deltaZ = z2 - z1; + + if ((deltaX == 0) && (myY1 > myY2) && (deltaZ == 0)) + { + angle = 90.0 * (M_PI / 180.0); + } + else if ((deltaX == 0) && (myY1 < myY2) && (deltaZ == 0)) + { + angle = -90.0 * (M_PI / 180.0); + } + else if ((deltaY == 0) && (myX1 < myX2) && (deltaZ == 0)) + { + angle = 0; + } + else if ((deltaY == 0) && (myX1 > myX2) && (deltaZ == 0)) + { + angle = 180.0 * (M_PI / 180.0); + } + else + { + angle = atan2((1.0 * deltaY), (1.0 * deltaX)); + } + angle180 = angle + M_PI; + + //* we now have the angle pointing from the end, pointing BACK along the vector + arrowPtAngle = 18.0 * (M_PI / 180.0); + + + //* draw 2 lines back along this line + arrowDx = pointLen * cos(angle180 + arrowPtAngle); + arrowDy = -pointLen * sin(angle180 + arrowPtAngle); + + WebGraph_Draw2Dline( myX2, + myY2, + myX2 + arrowDx, + myY2 + arrowDy, + color); + + arrowDx = pointLen * cos(angle180 - arrowPtAngle); + arrowDy = -pointLen * sin(angle180 - arrowPtAngle); + WebGraph_Draw2Dline( myX2, + myY2, + myX2 + arrowDx, + myY2 + arrowDy, + color); + + } + else + { + CONSOLE_DEBUG("gWebGrapicsImage is NULL"); + } +} + +//***************************************************************************** +void WebGraph_DrawVector(int x1, int y1, int z1, int x2, int y2, int z2, cv::Scalar color, const char *labelText) +{ +int myX1; +int myY1; +int myLabel_Y; +cv::Point textLoc; + + if (gWebGrapicsImage != NULL) + { + //* draw the line + WebGraph_Draw3Dline(x1, y1, z1, x2, y2, z2, color); + + //* now draw an arrow head + WebGraph_DrawVectorArrowHead(x1, y1, z1, x2, y2, z2, color); + + + if (strlen(labelText) > 0) + { + myX1 = WebGraph_TranslateXvalue(x2, z2); + myY1 = WebGraph_TranslateYvalue(y2, z2); + +#define kXlabelSpace 100 + + if (myX1 > (_currentXsize - kXlabelSpace)) + { + myX1 = _currentXsize - kXlabelSpace; + } + myLabel_Y = myY1 + 13; + if (myLabel_Y > (_currentYsize - 10)) + { + myLabel_Y = _currentYsize - 10; + } +// gdImageString(_gWebimGD, gdFontGetGiant(), (myX1 + 5), myLabel_Y, (unsigned char *)labelText, color); + textLoc.x = myX1 + 5; + textLoc.y = myLabel_Y; + //cv::FONT_HERSHEY_PLAIN, 0.7, 1); + cv::putText( *gWebGrapicsImage, + labelText, + textLoc, + cv::FONT_HERSHEY_PLAIN, + 1.0, + color, + 1 + ); + } + } + else + { + CONSOLE_DEBUG("gWebGrapicsImage is NULL"); + } +} + +//***************************************************************************** +void WebGraph_Draw2Dline(int x1, int y1, int x2, int y2, cv::Scalar color) +{ +cv::Point pt1; +cv::Point pt2; + + + if (gWebGrapicsImage != NULL) + { + pt1.x = x1; + pt1.y = y1; + + pt2.x = x2; + pt2.y = y2; + cv::line( *gWebGrapicsImage, + pt1, + pt2, + color, // color, + gCurrentLineWidth, // int thickness CV_DEFAULT(1), + 8, // int line_type CV_DEFAULT(8), + 0); // int shift CV_DEFAULT(0)); + } +} + + +//***************************************************************************** +void WebGraph_Draw3Dline(int x1, int y1, int z1, int x2, int y2, int z2, cv::Scalar color) +{ +int myX1; +int myY1; +int myX2; +int myY2; +cv::Point pt1; +cv::Point pt2; + + + myX1 = WebGraph_TranslateXvalue(x1, z1); + myY1 = WebGraph_TranslateYvalue(y1, z1); + + myX2 = WebGraph_TranslateXvalue(x2, z2); + myY2 = WebGraph_TranslateYvalue(y2, z2); + if (gWebGrapicsImage != NULL) + { + pt1.x = myX1; + pt1.y = myY1; + + pt2.x = myX2; + pt2.y = myY2; + cv::line( *gWebGrapicsImage, + pt1, + pt2, + color, // color, + gCurrentLineWidth, // int thickness CV_DEFAULT(1), + 8, // int line_type CV_DEFAULT(8), + 0); // int shift CV_DEFAULT(0)); + } +} + +//***************************************************************************** +void WebGraph_Draw3DlineDashed(int x1, int y1, int z1, int x2, int y2, int z2, cv::Scalar color) +{ +int myX1; +int myY1; +int myX2; +int myY2; +cv::Point pt1; +cv::Point pt2; + +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG("__FUNCTION__"); +#endif + + myX1 = WebGraph_TranslateXvalue(x1, z1); + myY1 = WebGraph_TranslateYvalue(y1, z1); + + myX2 = WebGraph_TranslateXvalue(x2, z2); + myY2 = WebGraph_TranslateYvalue(y2, z2); + + + if ((myX1 > -100000) && (myX2 > -100000) && (myY1 > -100000) && (myY2 > -100000)) + { + if (gWebGrapicsImage != NULL) + { + pt1.x = myX1; + pt1.y = myY1; + + pt2.x = myX2; + pt2.y = myY2; + cv::line( *gWebGrapicsImage, + pt1, + pt2, + color, // color, + gCurrentLineWidth, // int thickness CV_DEFAULT(1), + 8, // int line_type CV_DEFAULT(8), + 0); // int shift CV_DEFAULT(0)); + + } + else + { + CONSOLE_DEBUG("_gWebimGD is NULL"); + } + } + else + { +#ifdef _GRAPH_SHOW_ERRORS_ + CONSOLE_DEBUG("---------------------------------"); + CONSOLE_DEBUG_W_NUM("Parameters out of range x1", x1); + CONSOLE_DEBUG_W_NUM("Parameters out of range y1", y1); + CONSOLE_DEBUG_W_NUM("Parameters out of range x2", x2); + CONSOLE_DEBUG_W_NUM("Parameters out of range y2", y2); + + + CONSOLE_DEBUG_W_NUM("Parameters out of range myX1", myX1); + CONSOLE_DEBUG_W_NUM("Parameters out of range myX2", myX2); + CONSOLE_DEBUG_W_NUM("Parameters out of range myY1", myY1); + CONSOLE_DEBUG_W_NUM("Parameters out of range myY2", myY2); +#endif + } +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG("Done drawing dashed line"); +#endif + +} + +//***************************************************************************** +void WebGraph_DrawScreenTextLg(const char *theText, int x1, int y1, cv::Scalar color) +{ +cv::Point textLoc; + + if (gWebGrapicsImage != NULL) + { + textLoc.x = x1; + textLoc.y = y1; + //cv::FONT_HERSHEY_PLAIN, 0.7, 1); + cv::putText( *gWebGrapicsImage, + theText, + textLoc, + cv::FONT_HERSHEY_PLAIN, + 1.0, + color, + 1 + ); + } +} + +//***************************************************************************** +void WebGraph_DrawScreenTextLg_translated(const char *theText, int x1, int y1, cv::Scalar color) +{ +int myX1; +int myY1; +cv::Point textLoc; + + myX1 = WebGraph_TranslateXvalue(x1, 0); + myY1 = WebGraph_TranslateYvalue(y1, 0); + if (gWebGrapicsImage != NULL) + { + textLoc.x = myX1; + textLoc.y = myY1; + + //cv::FONT_HERSHEY_PLAIN, 0.7, 1); + cv::putText( *gWebGrapicsImage, + theText, + textLoc, + cv::FONT_HERSHEY_PLAIN, + 1.0, + color, + 1 + ); + } +} + +//***************************************************************************** +void WebGraph_DrawScale(double scaleX, double scaleY, cv::Scalar color) +{ + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +void WebGraph_Draw2DCircle(int centerX, int centerY, int sizeX, int sizeY, cv::Scalar color) +{ +// CONSOLE_DEBUG(__FUNCTION__); + if (gWebGrapicsImage != NULL) + { + cv::Point center; + cv::Size axes; + + if ((sizeX > 0) && (sizeY > 0)) + { + center.x = centerX; + center.y = centerY; +// axes.width = 1 * xRadius; +// axes.height = 1 * yRadius; + axes.width = sizeX / 2; + axes.height = sizeY / 2; + + cv::ellipse( *gWebGrapicsImage, + center, + axes, + 0.0, //* angle + 0.0, //* start_angle + 360.0, //* end_angle + color, // color, + gCurrentLineWidth + ); + } + else + { + CONSOLE_DEBUG_W_NUM("xCenter\t=", centerX); + CONSOLE_DEBUG_W_NUM("yCenter\t=", centerY); + CONSOLE_DEBUG_W_NUM("xRadius\t=", sizeX); + CONSOLE_DEBUG_W_NUM("yRadius\t=", sizeY); + CONSOLE_ABORT("Invalid arguments"); + } + } + else + { + CONSOLE_DEBUG("gWebGrapicsImage is NULL"); + } +} + +//***************************************************************************** +void WebGraph_Draw2DCircleDashed(int centerX, int centerY, int sizeX, int sizeY, cv::Scalar color) +{ + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +void WebGraph_Draw2DCircleFilled(int centerX, int centerY, int xRadius, int yRadius, cv::Scalar color) +{ +cv::Point center; +cv::Size axes; + +// CONSOLE_DEBUG(__FUNCTION__); + + if (gWebGrapicsImage != NULL) + { + if ((xRadius > 0) && (yRadius > 0)) + { + center.x = centerX; + center.y = centerY; + axes.width = xRadius / 2; + axes.height = yRadius / 2; + + cv::ellipse( *gWebGrapicsImage, + center, + axes, + 0.0, //* angle + 0.0, //* start_angle + 360.0, //* end_angle + color, // color, + #if (CV_MAJOR_VERSION >= 3) + cv::FILLED // int thickness CV_DEFAULT(1), + #else + CV_FILLED + #endif + ); + } + else + { + CONSOLE_DEBUG_W_NUM("xCenter\t=", centerX); + CONSOLE_DEBUG_W_NUM("yCenter\t=", centerY); + CONSOLE_DEBUG_W_NUM("xRadius\t=", xRadius); + CONSOLE_DEBUG_W_NUM("yRadius\t=", yRadius); + CONSOLE_ABORT("Invalid arguments"); + } + } + else + { + CONSOLE_DEBUG("gWebGrapicsImage is NULL"); + } +} + + +//***************************************************************************** +void WebGraph_Draw2DCircleFilled_translated(int centerX, int centerY, int xRadius, int yRadius, cv::Scalar color) +{ +int myX1; +int myY1; +cv::Point center; +cv::Size axes; + +// CONSOLE_DEBUG(__FUNCTION__); + + myX1 = WebGraph_TranslateXvalue(centerX, 0); + myY1 = WebGraph_TranslateYvalue(centerY, 0); + + if (gWebGrapicsImage != NULL) + { + if ((xRadius > 0) && (yRadius > 0)) + { +// center.x = centerX; +// center.y = centerY; + center.x = myX1; + center.y = myY1; + axes.width = xRadius / 2; + axes.height = yRadius / 2; + + cv::ellipse( *gWebGrapicsImage, + center, + axes, + 0.0, //* angle + 0.0, //* start_angle + 360.0, //* end_angle + color, // color, + #if (CV_MAJOR_VERSION >= 3) + cv::FILLED // int thickness CV_DEFAULT(1), + #else + CV_FILLED + #endif + ); + } + else + { + CONSOLE_DEBUG_W_NUM("xCenter\t=", centerX); + CONSOLE_DEBUG_W_NUM("yCenter\t=", centerY); + CONSOLE_DEBUG_W_NUM("xRadius\t=", xRadius); + CONSOLE_DEBUG_W_NUM("yRadius\t=", yRadius); + CONSOLE_ABORT("Invalid arguments"); + } + } + else + { + CONSOLE_DEBUG("gWebGrapicsImage is NULL"); + } +} + +//***************************************************************************** +void WebGraph_Draw2D_RegMark(int centerX, int centerY, int sizeX, int sizeY, cv::Scalar color) +{ + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +cv::Scalar WebGraph_GetColorByIndex(int colorIndex) +{ +cv::Scalar lineColor; + + //* make sure the color index is in range + while (colorIndex >= kGraphPointMode_Last) + { + colorIndex -= kGraphPointMode_Last; + } + switch (colorIndex) + { + case kGraphPointMode_RedLine: + case kGraphPointMode_RedLineDashed: + case kGraphPointMode_RedDot: + case kGraphPointMode_Red_X: + case kGraphPointMode_RedDot_Large: + lineColor = _gdColorRed; + break; + //---------------------------------------------------------------------- + case kGraphPointMode_GreenLine: + case kGraphPointMode_GreenLineDashed: + case kGraphPointMode_GreenDot: + case kGraphPointMode_Green_X: + case kGraphPointMode_GreenDot_Large: + lineColor = _gdColorGreen; + break; + //---------------------------------------------------------------------- + case kGraphPointMode_BlueLine: + case kGraphPointMode_BlueLineDashed: + case kGraphPointMode_BlueDot: + case kGraphPointMode_Blue_X: + case kGraphPointMode_BlueDot_Large: + lineColor = _gdColorBlue; + break; + //---------------------------------------------------------------------- + case kGraphPointMode_OrangeLine: + case kGraphPointMode_OrangeLineDashed: + case kGraphPointMode_OrangeDot: + case kGraphPointMode_Orange_X: + case kGraphPointMode_OrangeDot_Large: + lineColor = _gdColorOrange; + break; + //---------------------------------------------------------------------- + case kGraphPointMode_CyanLine: + case kGraphPointMode_CyanLineDashed: + case kGraphPointMode_CyanDot: + case kGraphPointMode_Cyan_X: + case kGraphPointMode_CyanDot_Large: + lineColor = _gdColorCyan; + break; + //---------------------------------------------------------------------- + case kGraphPointMode_MagentaLine: + case kGraphPointMode_MagentaLineDashed: + case kGraphPointMode_MagentaDot: + case kGraphPointMode_Magenta_X: + case kGraphPointMode_MagentaDot_Large: + lineColor = _gdColorMagenta; + break; + + //---------------------------------------------------------------------- + case kGraphPointMode_YellowLine: + case kGraphPointMode_YellowLineDashed: + case kGraphPointMode_YellowDot: + case kGraphPointMode_Yellow_X: + case kGraphPointMode_YellowDot_Large: + lineColor = _gdColorYellow; + break; + //---------------------------------------------------------------------- + case kGraphPointMode_GreyLine: + lineColor = _gdColorGrey; + break; + //---------------------------------------------------------------------- + case kGraphPointMode_DkGreenLine: + case kGraphPointMode_DkGreenDot: + lineColor = _gdColorDkGreen; + break; + //---------------------------------------------------------------------- + case kGraphPointMode_none: + case kGraphPointMode_BlackLine: + case kGraphPointMode_BlackLineDashed: + case kGraphPointMode_BlackDot: + case kGraphPointMode_Black_X: + case kGraphPointMode_BlackDot_Large: + lineColor = _gdColorBlack; + break; + //---------------------------------------------------------------------- + default: + lineColor = _gdColorBlack; + break; + } + return(lineColor); +} + +//***************************************************************************** +//* scaled routines +//***************************************************************************** +void WebGraph_Draw2DlineScaled(double x1, double y1, double x2, double y2, double scaleFactor, cv::Scalar color) +{ +// CONSOLE_DEBUG(__FUNCTION__); + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +void WebGraph_Draw2DlineScaledXY(double x1, double y1, double x2, double y2, double scaleFactorX, double scaleFactorY, cv::Scalar color) +{ +// CONSOLE_DEBUG(__FUNCTION__); +int myX1, myY1; +int myX2, myY2; + + myX1 = scaleFactorX * x1; + myY1 = scaleFactorY * y1; + myX2 = scaleFactorX * x2; + myY2 = scaleFactorY * y2; + WebGraph_Draw3Dline(myX1, myY1, 0, myX2, myY2, 0, color); + +} + +//***************************************************************************** +void WebGraph_Draw2DlineScaledXY_dashed(double x1, double y1, double x2, double y2, double scaleFactorX, double scaleFactorY, cv::Scalar color) +{ +// CONSOLE_DEBUG(__FUNCTION__); + CONSOLE_DEBUG("Not finished"); +int myX1, myY1; +int myX2, myY2; + + myX1 = scaleFactorX * x1; + myY1 = scaleFactorY * y1; + myX2 = scaleFactorX * x2; + myY2 = scaleFactorY * y2; + WebGraph_Draw3Dline(myX1, myY1, 0, myX2, myY2, 0, color); +} + +//***************************************************************************** +void WebGraph_Draw2DlineDashedScaled(double x1, double y1, double x2, double y2, double scaleFactor, cv::Scalar color) +{ +int myX1, myY1; +int myX2, myY2; + +// CONSOLE_DEBUG(__FUNCTION__); + +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_DBL("scaleFactor =", scaleFactor); +#endif + + myX1 = scaleFactor * x1; + myY1 = scaleFactor * y1; + myX2 = scaleFactor * x2; + myY2 = scaleFactor * y2; + WebGraph_Draw3DlineDashed(myX1, myY1, 0, myX2, myY2, 0, color); + +} + +//***************************************************************************** +void WebGraph_DrawTextScaled(const char *theText, double x1, double y1, double z1, cv::Scalar color, double scaleFactor) +{ +// CONSOLE_DEBUG(__FUNCTION__); + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +void WebGraph_DrawDimensionScaled(double x1, double y1, double z1, double x2, double y2, double z2, cv::Scalar color, const char *labelText, double scaleFactor) +{ +// CONSOLE_DEBUG(__FUNCTION__); + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +void WebGraph_DrawVectorScaled(double x1, double y1, double z1, double x2, double y2, double z2, cv::Scalar color, const char *labelText, double scaleFactor) +{ +int my_x1; +int my_y1; +int my_z1; +int my_x2; +int my_y2; +int my_z2; + +// CONSOLE_DEBUG(__FUNCTION__); + + my_x1 = x1 * scaleFactor; + my_y1 = y1 * scaleFactor; + my_z1 = z1 * scaleFactor; + my_x2 = x2 * scaleFactor; + my_y2 = y2 * scaleFactor; + my_z2 = z2 * scaleFactor; + + WebGraph_DrawVector(my_x1, my_y1, my_z1, my_x2, my_y2, my_z2, color, labelText); + +} + +//***************************************************************************** +void WebGraph_Draw2DArcScaled( double centerX, + double centerY, + double sizeX, + double sizeY, + double startAngle, + double endAngle, + int color, + double scaleFactor) +{ +// CONSOLE_DEBUG(__FUNCTION__); + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +void WebGraph_SetPixel(const int xLoc, const int yLoc, const cv::Scalar color) +{ +// CONSOLE_DEBUG(__FUNCTION__); + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +void WebGraph_SetPixelScaled(const int xLoc, const int yLoc, const cv::Scalar color, double scaleFactor) +{ +// CONSOLE_DEBUG(__FUNCTION__); + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +void WebGraph_DrawText(const char *theText, int x1, int y1, int z1, cv::Scalar color) +{ +int myX1; +int myY1; +cv::Point textLoc; + +// CONSOLE_DEBUG(__FUNCTION__); + + myX1 = WebGraph_TranslateXvalue(x1, z1); + myY1 = WebGraph_TranslateYvalue(y1, z1); + + if (gWebGrapicsImage != NULL) + { + textLoc.x = myX1; + textLoc.y = myY1; + + cv::putText( *gWebGrapicsImage, + theText, + textLoc, + cv::FONT_HERSHEY_PLAIN, + 1.0, + color, + 1 + ); + } + else + { + CONSOLE_DEBUG("gWebGrapicsImage is NULL"); + } +} + +//***************************************************************************** +void WebGraph_DrawTextLg_translated(const char *theText, int x1, int y1, int z1, cv::Scalar color) +{ +int myX1; +int myY1; +cv::Point textLoc; + + myX1 = WebGraph_TranslateXvalue(x1, z1); + myY1 = WebGraph_TranslateYvalue(y1, z1); + + if (gWebGrapicsImage != NULL) + { + textLoc.x = myX1; + textLoc.y = myY1; + + cv::putText( *gWebGrapicsImage, + theText, + textLoc, + cv::FONT_HERSHEY_PLAIN, + 1.0, + color, + 1 + ); + } + else + { + CONSOLE_DEBUG("gWebGrapicsImage is NULL"); + } +} + +//************************************************************************************** +static void WebGraph_DrawMarker(int myScreenX, + int myScreenY, + int pointMode, + cv::Scalar lineColor) +{ + switch (pointMode) + { + case kGraphPointMode_none: //* do nothing + break; + + case kGraphPointMode_RedDot: //* draw a little circle on the spot + case kGraphPointMode_GreenDot: + case kGraphPointMode_BlueDot: + case kGraphPointMode_OrangeDot: + case kGraphPointMode_CyanDot: + case kGraphPointMode_MagentaDot: + case kGraphPointMode_YellowDot: + case kGraphPointMode_BlackDot: + case kGraphPointMode_DkGreenDot: + WebGraph_Draw2DCircleFilled(myScreenX, myScreenY, kXcircleDiam, kXcircleDiam, lineColor); + break; + + case kGraphPointMode_RedDot_Large: + case kGraphPointMode_GreenDot_Large: + case kGraphPointMode_BlueDot_Large: + case kGraphPointMode_OrangeDot_Large: + case kGraphPointMode_CyanDot_Large: + case kGraphPointMode_MagentaDot_Large: + case kGraphPointMode_YellowDot_Large: + case kGraphPointMode_BlackDot_Large: + WebGraph_Draw2DCircleFilled(myScreenX, myScreenY, kXcircleDiamLarge, kXcircleDiamLarge, lineColor); + break; + + + //* draw a little x on the spot + case kGraphPointMode_Red_X: + case kGraphPointMode_Green_X: + case kGraphPointMode_Blue_X: + case kGraphPointMode_Orange_X: + case kGraphPointMode_Cyan_X: + case kGraphPointMode_Magenta_X: + case kGraphPointMode_Yellow_X: + case kGraphPointMode_Black_X: + WebGraph_Draw3Dline((myScreenX - kXdotLen), (myScreenY - kXdotLen), 0, (myScreenX + kXdotLen), (myScreenY + kXdotLen), 0, lineColor); + WebGraph_Draw3Dline((myScreenX - kXdotLen), (myScreenY + kXdotLen), 0, (myScreenX + kXdotLen), (myScreenY - kXdotLen), 0, lineColor); + break; + + default: //* do nothing + break; + + } +} + +//***************************************************************************** +void WebGraph_GraphDataArray(double startX, + double endX, + double labelStepX, + double startY, + double endY, + double labelStepY, + int numberCnt, + double *xValues, + double *yValues, + int pointColorMode, + double *rtnScaleX, + double *rtnScaleY, + bool drawAxis, + bool drawFullLengthVerticalTickMarks, + bool drawFullLengthHorizontalTickMarks) +{ +double xScaleFactor; +double yScaleFactor; +int iii; +double myX1; +double myY1; +double myX2; +double myY2; +int myScreenX; +int myScreenY; +double usableWidth; +double deltaX; +double deltaY; +cv::Scalar lineColor; + +// CONSOLE_DEBUG_W_DBL("web-endY", endY); + +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_NUM("numberCnt =", numberCnt); + CONSOLE_DEBUG_W_DBL("startX =", startX); + CONSOLE_DEBUG_W_DBL("endX =", endX); + CONSOLE_DEBUG_W_DBL("startY =", startY); + CONSOLE_DEBUG_W_DBL("endY =", endY); +#endif + if (drawAxis) + { + //* adjust this later + if ((_currentXsize == 640) && (_currentYsize == 800)) + { + WebGraph_DrawAxis(kAxisStyle_XY_640x800, _gdColorBlack); + } + else + { + // WebGraph_DrawAxis(kAxisStyle_XY, _gdColorBlack); + WebGraph_DrawAxis(kAxisStyle_XY_NoLabels, _gdColorBlack); + + } + } + + usableWidth = (1.0 * _currentXsize) - _xCenter; + + deltaX = endX - startX; + if (fabs(deltaX) > 0.0000001) + { + xScaleFactor = usableWidth / (endX - startX); + } + else + { + xScaleFactor = 1; + } +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_DBL("usableWidth =", usableWidth); + CONSOLE_DEBUG_W_DBL("endX - startX =", (endX - startX)); + CONSOLE_DEBUG_W_DBL("xScaleFactor =", xScaleFactor); + CONSOLE_DEBUG_W_DBL("labelStepX", labelStepX); +#endif + + deltaY = endY - startY; + if (fabs(deltaY) > 0.000000001) + { +// CONSOLE_DEBUG("deltaY != 0"); + yScaleFactor = (_yCenter) / (deltaY); + } + else + { + yScaleFactor = 1; + } +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_DBL("deltaY =", deltaY); + CONSOLE_DEBUG_W_DBL("endY - startY =", (endY - startY)); + CONSOLE_DEBUG_W_DBL("yScaleFactor =", yScaleFactor); + CONSOLE_DEBUG_W_DBL("labelStepY", labelStepY); +#endif + + lineColor = WebGraph_GetColorByIndex(pointColorMode); + + + if (xScaleFactor > 0.0) + { + if (labelStepX != 0.0) + { + WebGraph_DrawScaleTickMarks_X((xScaleFactor * labelStepX), startX, labelStepX, _gdColorBlack); + } + } + +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_DBL("yScaleFactor =", yScaleFactor); +#endif + + if (yScaleFactor > 0.0) + { + if (labelStepY != 0.0) + { + WebGraph_DrawScaleTickMarks_Y((yScaleFactor * labelStepY), startY, labelStepY, _gdColorBlack); + } + } + else + { + #ifdef _GRAPH_SHOW_ERRORS_ + CONSOLE_DEBUG_W_DBL("yScaleFactor < 0.0", yScaleFactor); + #endif + } +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG("debugging1"); +#endif + + if (drawFullLengthVerticalTickMarks) + { + //* draw vertical dashed lines at each of the tick marks + if ((startX < endX) && (labelStepX > 0.0)) + { + #ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_DBL("drawing verticl dashed lines; labelStepX=", labelStepX); + #endif + //* put vertical dash lines at every tick mark + myX1 = startX; + while (myX1 <= endX) + { + double myAdjustedX1; + + #ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_DBL("myX1=", myX1); + #endif + + myX1 += labelStepX; + myAdjustedX1 = myX1 - startX; + // WebGraph_Draw2DlineDashedScaled(myAdjustedX1, 0, myAdjustedX1, (_currentYsize * 5), xScaleFactor, _gdColorRed); + WebGraph_Draw2DlineDashedScaled(myAdjustedX1, 0, myAdjustedX1, ((_currentYsize / xScaleFactor) * 5), xScaleFactor, _gdColorGrey); + } + } + } + + if (drawFullLengthHorizontalTickMarks) + { + //* draw Horizontal dashed lines at each of the tick marks + if ((startY < endY) && (labelStepY > 0.0)) + { + #ifdef _DEBUG_HORIZONTAL_GRIDS_ + CONSOLE_DEBUG_W_DBL("drawing Horizontal dashed lines; labelStepY=", labelStepY); + CONSOLE_DEBUG_W_DBL("startY", startY); + CONSOLE_DEBUG_W_DBL("endY", endY); + #endif + //* put vertical dash lines at every tick mark + myY1 = startY; + while (myY1 <= endY) + { + double myAdjustedY1; + + #ifdef _DEBUG_HORIZONTAL_GRIDS_ + CONSOLE_DEBUG_W_DBL("myY1=", myY1); + #endif + myX1 = 0; + myX2 = ((_currentXsize / yScaleFactor) * 5); + myY1 += labelStepY; + myAdjustedY1 = myY1 - startY; + + WebGraph_Draw2DlineDashedScaled(myX1, myAdjustedY1, myX2, myAdjustedY1, yScaleFactor, _gdColorGrey); + } + } + } + + if (startY < 0) + { + WebGraph_Draw2DlineDashedScaled(0, -startY, _currentXsize, -startY, yScaleFactor, _gdColorGreen); + } + + for (iii=0; iii < (numberCnt - 1); iii++) + { + myX1 = xValues[iii] - startX; + myY1 = yValues[iii] - startY; + + if (iii == 0) + { + //* draw a marker at the first point + myScreenX = xScaleFactor * myX1; + myScreenY = yScaleFactor * myY1; + WebGraph_DrawMarker(myScreenX, myScreenY, pointColorMode, lineColor); + } + + myX2 = xValues[iii + 1] - startX; + myY2 = yValues[iii + 1] - startY; + +// CONSOLE_DEBUG_W_DBL("myX1 =", myX1); +// CONSOLE_DEBUG_W_DBL("myY1 =", myY1); + switch (pointColorMode) + { + case kGraphPointMode_RedLineDashed: + case kGraphPointMode_GreenLineDashed: + case kGraphPointMode_BlueLineDashed: + case kGraphPointMode_OrangeLineDashed: + case kGraphPointMode_CyanLineDashed: + case kGraphPointMode_MagentaLineDashed: + case kGraphPointMode_BlackLineDashed: + WebGraph_Draw2DlineScaledXY_dashed(myX1, myY1, myX2, myY2, xScaleFactor, yScaleFactor, lineColor); + break; + + default: + WebGraph_Draw2DlineScaledXY(myX1, myY1, myX2, myY2, xScaleFactor, yScaleFactor, lineColor); + break; + } + myScreenX = xScaleFactor * myX2; + myScreenY = yScaleFactor * myY2; + WebGraph_DrawMarker(myScreenX, myScreenY, pointColorMode, lineColor); + + } +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG_W_DBL("startX=", startX); + CONSOLE_DEBUG_W_DBL("endX=", endX); + CONSOLE_DEBUG_W_DBL("labelStepX=", labelStepX); +#endif + + +#ifdef _GRAPH_VERBOSE_ + CONSOLE_DEBUG("exit"); +#endif + if (rtnScaleX != NULL) + { + *rtnScaleX = xScaleFactor; + } + if (rtnScaleY != NULL) + { + *rtnScaleY = yScaleFactor; + } +} + +//***************************************************************************** +void WebGraph_DrawTitle(const char *titleText, const cv::Scalar color) +{ +int myScreenX; +int middleScreenX; +int myScreenY; +int textLength; +cv::Point textLoc; + + textLength = strlen(titleText); + middleScreenX = _currentXsize / 2; + myScreenX = middleScreenX - ((textLength / 2) * 10); + myScreenY = _currentYsize - 25; + + if (gWebGrapicsImage != NULL) + { + textLoc.x = myScreenX; + textLoc.y = myScreenY; + + cv::putText( *gWebGrapicsImage, + titleText, + textLoc, + cv::FONT_HERSHEY_PLAIN, + 1.0, + color, + 1 + ); + } +} + +//***************************************************************************** +void WebGraph_DrawLegend(const int index, const int pointColorMode, const char *legendText, const int lengendWidth) +{ +int myScreenX; +int myScreenY; +cv::Scalar pointColor; +cv::Rect myCVrect; +int myX1; +int myX2; +int myY1; + + myScreenX = _currentXsize - lengendWidth; + myScreenY = _currentYsize - 64; + myScreenY -= (index * kLegendLineHeight); + + pointColor = WebGraph_GetColorByIndex(pointColorMode); + + myX1 = WebGraph_TranslateXvalue(myScreenX, 0); + myY1 = WebGraph_TranslateYvalue(myScreenY, 0); + myX2 = myX1 + lengendWidth; + if (myX2 > (_currentXsize - 2)) + { + myX2 = _currentXsize - 2; + } + + if (gWebGrapicsImage != NULL) + { +// gdImageFilledRectangle(_gWebimGD, (myX1 - 25), +// (myY1 - (kLegendLineHeight / 2)), +// (myX2), +// (myY1 + (kLegendLineHeight / 2)), +// 0xe0e0e0); + + myCVrect.x = (myX1 - 25); + myCVrect.y = (myY1 - (kLegendLineHeight / 2)); +// myCVrect.width = myX2 - myX1; + myCVrect.width = _currentXsize - myCVrect.x; + myCVrect.height = kLegendLineHeight; + + cv::rectangle( *gWebGrapicsImage, + myCVrect, + _gdColorLtGrey, + #if (CV_MAJOR_VERSION >= 3) + cv::FILLED // int thickness CV_DEFAULT(1), + #else + CV_FILLED + #endif + ); + } + else + { + #ifdef _DEBUG_LEGEND_ + CONSOLE_DEBUG("myY1 is NULL"); + #endif + } + + switch(pointColorMode) + { + case kGraphPointMode_RedLine: + case kGraphPointMode_GreenLine: + case kGraphPointMode_BlueLine: + case kGraphPointMode_OrangeLine: + case kGraphPointMode_CyanLine: + case kGraphPointMode_MagentaLine: + case kGraphPointMode_YellowLine: + case kGraphPointMode_GreyLine: + case kGraphPointMode_DkGreenLine: + case kGraphPointMode_BlackLine: + WebGraph_Draw3Dline((myScreenX - 15), myScreenY, 0, + (myScreenX + 15), myScreenY, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY+1, 0, + (myScreenX + 15), myScreenY+1, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY-1, 0, + (myScreenX + 15), myScreenY-1, 0, pointColor); + break; + + case kGraphPointMode_RedDot: + case kGraphPointMode_GreenDot: + case kGraphPointMode_BlueDot: + case kGraphPointMode_OrangeDot: + case kGraphPointMode_CyanDot: + case kGraphPointMode_MagentaDot: + case kGraphPointMode_YellowDot: + case kGraphPointMode_BlackDot: + case kGraphPointMode_DkGreenDot: + WebGraph_Draw3Dline((myScreenX - 15), myScreenY, 0, + (myScreenX + 15), myScreenY, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY+1, 0, + (myScreenX + 15), myScreenY+1, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY-1, 0, + (myScreenX + 15), myScreenY-1, 0, pointColor); + WebGraph_Draw2DCircleFilled_translated(myScreenX, myScreenY, 10, 10, pointColor); + break; + + case kGraphPointMode_RedLineDashed: + case kGraphPointMode_GreenLineDashed: + case kGraphPointMode_BlueLineDashed: + case kGraphPointMode_OrangeLineDashed: + case kGraphPointMode_CyanLineDashed: + case kGraphPointMode_MagentaLineDashed: + case kGraphPointMode_YellowLineDashed: + case kGraphPointMode_BlackLineDashed: + WebGraph_Draw3DlineDashed( (myScreenX - 15), myScreenY, 0, + (myScreenX + 15), myScreenY, 0, pointColor); + WebGraph_Draw3DlineDashed( (myScreenX - 15), myScreenY+1, 0, + (myScreenX + 15), myScreenY+1, 0, pointColor); + WebGraph_Draw3DlineDashed( (myScreenX - 15), myScreenY-1, 0, + (myScreenX + 15), myScreenY-1, 0, pointColor); + break; + + case kGraphPointMode_Red_X: + case kGraphPointMode_Green_X: + case kGraphPointMode_Blue_X: + case kGraphPointMode_Orange_X: + case kGraphPointMode_Cyan_X: + case kGraphPointMode_Magenta_X: + case kGraphPointMode_Yellow_X: + case kGraphPointMode_Black_X: + WebGraph_Draw3Dline((myScreenX - 15), myScreenY, 0, + (myScreenX + 15), myScreenY, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY+1, 0, + (myScreenX + 15), myScreenY+1, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY-1, 0, + (myScreenX + 15), myScreenY-1, 0, pointColor); + + WebGraph_Draw3Dline((myScreenX - (2 * kXdotLen)), (myScreenY - (2 * kXdotLen)), 0, (myScreenX + (2 * kXdotLen)), (myScreenY + (2 * kXdotLen)), 0, pointColor); + WebGraph_Draw3Dline((myScreenX - (2 * kXdotLen)), (myScreenY + (2 * kXdotLen)), 0, (myScreenX + (2 * kXdotLen)), (myScreenY - (2 * kXdotLen)), 0, pointColor); + break; + + case kGraphPointMode_RedDot_Large: + case kGraphPointMode_GreenDot_Large: + case kGraphPointMode_BlueDot_Large: + case kGraphPointMode_OrangeDot_Large: + case kGraphPointMode_CyanDot_Large: + case kGraphPointMode_MagentaDot_Large: + case kGraphPointMode_YellowDot_Large: + case kGraphPointMode_BlackDot_Large: + WebGraph_Draw3Dline((myScreenX - 15), myScreenY, 0, + (myScreenX + 15), myScreenY, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY+1, 0, + (myScreenX + 15), myScreenY+1, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY-1, 0, + (myScreenX + 15), myScreenY-1, 0, pointColor); + WebGraph_Draw2DCircleFilled_translated(myScreenX, myScreenY, kXcircleDiamLarge, kXcircleDiamLarge, pointColor); + break; + + + default: + //* if its negative, dont do anything + if (pointColorMode >= 0) + { + + WebGraph_Draw3Dline((myScreenX - 15), myScreenY, 0, + (myScreenX + 15), myScreenY, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY+1, 0, + (myScreenX + 15), myScreenY+1, 0, pointColor); + WebGraph_Draw3Dline((myScreenX - 15), myScreenY-1, 0, + (myScreenX + 15), myScreenY-1, 0, pointColor); + } + break; + } + //* this adjustment moves the text lines up with the line graphic +#ifdef _USE_HERSHEY_FONTS_ + myScreenX += 30; +#else + myScreenX += 20; + myScreenY -= 10; +#endif + WebGraph_DrawTextLg_translated(legendText, myScreenX, myScreenY, 0, _gdColorBlack); +} + +//***************************************************************************** +void WebGraph_DrawAirplane(const int centerX, const int centerY, const int airplaneStyle, const double angle) +{ + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +void WebGraph_DrawTarget(const int centerX, const int centerY, const int targetType, double scale) +{ + CONSOLE_DEBUG("Not finished"); + +} + +//***************************************************************************** +int WebGraph_CheckTargetHit(const int targetType, const double hitXX_inches, const double hitYY_inches) +{ + CONSOLE_DEBUG("Not finished"); + + return(0); +} + +//***************************************************************************** +void WebGraph_GraphDistribution( double *dataArray, + const int numValues, + const int numBins, + const double meanValue, + const double halfWidthValue, + bool includeStdDev, + char *jpgFileName, + char *legend0text, + char *graphTitle) +{ + CONSOLE_DEBUG("Not finished"); + +} + + diff --git a/src_mlsLib/web_graphics_opencv.h b/src_mlsLib/web_graphics_opencv.h new file mode 100644 index 0000000..f86231d --- /dev/null +++ b/src_mlsLib/web_graphics_opencv.h @@ -0,0 +1,243 @@ +//************************************************************************************** +//* Web Graphics library (opencv version +//* (C) 2024 by Mark Sproul +//* +//* +//************************************************************************************** +//* Edit History +//************************************************************************************** +//* Apr 26, 2024 Created web_graphics_opencv.h +//************************************************************************************** +//#include "web_graphics_opencv.h" + +#ifndef _WEB_GRAPHICS_H_ +#define _WEB_GRAPHICS_H_ + +#ifndef _STDBOOL_H + #include +#endif + +#include +#include + + + +//************************************************************************************** +enum +{ + kAxisStyle_3D = 0, + kAxisStyle_3D_abs, +// kAxisStyle_XYZ, + kAxisStyle_XYZ_abs, + kAxisStyle_XY, + kAxisStyle_XY_NoLabels, + kAxisStyle_XY_640x800, + kAxisStyle_XT, + kAxisStyle_UP, + kAxisStyle_UP_centered, + kAxisStyle_UP_4Quads, + kAxisStyle_XY_abs, + kAxisStyle_XY_centered, + kAxisStyle_XY_compass, + kAxisStyle_PolarXY, + kAxisStyle_e3e1, + kAxisStyle_e1e2, + kAxisStyle_AlhpaBeta, + + kAxisStyle_last +}; + +//extern gdImagePtr _gWebimGD; //* gdLibrary image +extern cv::Scalar _gdColorWhite; +extern cv::Scalar _gdColorBlack; +extern cv::Scalar _gdColorGrey; +extern cv::Scalar _gdColorLtGrey; +extern cv::Scalar _gdColorRed; +extern cv::Scalar _gdColorPink; +extern cv::Scalar _gdColorGreen; +extern cv::Scalar _gdColorDkGreen; +extern cv::Scalar _gdColorBlue; +extern cv::Scalar _gdColorCyan; +extern cv::Scalar _gdColorMagenta; +extern cv::Scalar _gdColorYellow; +extern cv::Scalar _gdColorOrange; +extern cv::Scalar _gdColorCopper; + + +//extern int _currentXsize; +//extern int _currentYsize; +extern int _xCenter; +extern int _yCenter; +//extern double _cosZangle; +//extern double _sinZangle; + +#ifdef __cplusplus + extern "C" { +#endif + +void WebGraph_CreateImage(int xSize, int ySize); +bool WebGraph_CheckImage(const char *routineName, const int lineNum); + +int WebGraph_SaveImage(const char *pathName, const char *fileName); +int WebGraph_TranslateXvalue(int xCordinate, int zCordinate); +int WebGraph_TranslateYvalue(int yCordinate, int zCordinate); +void WebGraph_DrawScaleX2(double scaleX, cv::Scalar color); + +void WebGraph_DrawAxis(int style, cv::Scalar color); +void WebGraph_DrawScaleTickMarks_X(double deltaPixelsX, double startValueX, double deltaValueX, cv::Scalar color); +void WebGraph_DrawScaleTickMarks_Y(double deltaPixelsY, double startValueY, double deltaValueY, cv::Scalar color); +void WebGraph_DrawVector(int x1, int y1, int z1, int x2, int y2, int z2, cv::Scalar color, const char *labelText); +void WebGraph_Draw3Dline(int x1, int y1, int z1, int x2, int y2, int z2, cv::Scalar color); +void WebGraph_Draw3DlineDashed(int x1, int y1, int z1, int x2, int y2, int z2, cv::Scalar color); + +void WebGraph_DrawScreenTextLg(const char *theText, int x1, int y1, cv::Scalar color); +void WebGraph_DrawScreenTextLg_translated(const char *theText, int x1, int y1, cv::Scalar color); +void WebGraph_DrawScale(double scaleX, double scaleY, cv::Scalar color); + +void WebGraph_Draw2Dline(int x1, int y1, int x2, int y2, cv::Scalar color); +void WebGraph_Draw2DCircle(int centerX, int centerY, int sizeX, int sizeY, cv::Scalar color); +void WebGraph_Draw2DCircleDashed(int centerX, int centerY, int sizeX, int sizeY, cv::Scalar color); +void WebGraph_Draw2DCircleFilled(int centerX, int centerY, int sizeX, int sizeY, cv::Scalar color); +void WebGraph_Draw2D_RegMark(int centerX, int centerY, int sizeX, int sizeY, cv::Scalar color); +cv::Scalar WebGraph_GetColorByIndex(int colorIndex); + +//* scaled routines +void WebGraph_Draw2DlineScaled(double x1, double y1, double x2, double y2, double scaleFactor, cv::Scalar color); +void WebGraph_Draw2DlineScaledXY(double x1, double y1, double x2, double y2, double scaleFactorX, double scaleFactorY, cv::Scalar color); +void WebGraph_Draw2DlineScaledXY_dashed(double x1, double y1, double x2, double y2, double scaleFactorX, double scaleFactorY, cv::Scalar color); + +void WebGraph_Draw2DlineDashedScaled(double x1, double y1, double x2, double y2, double scaleFactor, cv::Scalar color); +void WebGraph_DrawTextScaled(const char *theText, double x1, double y1, double z1, cv::Scalar color, double scaleFactor); +void WebGraph_DrawDimensionScaled(double x1, double y1, double z1, double x2, double y2, double z2, cv::Scalar color, const char *labelText, double scaleFactor); +void WebGraph_DrawVectorScaled(double x1, double y1, double z1, double x2, double y2, double z2, cv::Scalar color, const char *labelText, double scaleFactor); + +void WebGraph_Draw2DArcScaled( double centerX, + double centerY, + double sizeX, + double sizeY, + double startAngle, + double endAngle, + int color, + double scaleFactor); + + +void WebGraph_SetPixel(const int xLoc, const int yLoc, const cv::Scalar color); +void WebGraph_SetPixelScaled(const int xLoc, const int yLoc, const cv::Scalar color, double scaleFactor); + + +void WebGraph_DrawText(const char *theText, int x1, int y1, int z1, cv::Scalar color); +void WebGraph_DrawTextLg(const char *theText, int x1, int y1, int z1, cv::Scalar color); +void WebGraph_GraphDataArray(double startX, + double endX, + double labelStepX, + double startY, + double endY, + double labelStepY, + int numberCnt, + double *xValues, + double *yValues, + int pointColorMode, + double *rtnScaleX, + double *rtnScaleY, + bool drawAxis, + bool drawFullLengthVerticalTickMarks, + bool drawFullLengthHorizontalTickMarks); +void WebGraph_DrawTitle(const char *titleText, const cv::Scalar color); +void WebGraph_DrawLegend(const int index, const int pointColorMode, const char *legendText, const int lengendWidth); + + +void WebGraph_DrawAirplane(const int centerX, const int centerY, const int airplaneStyle, const double angle); +void WebGraph_DrawTarget(const int centerX, const int centerY, const int targetType, double scale); +int WebGraph_CheckTargetHit(const int targetType, const double hitXX_inches, const double hitYY_inches); + +void WebGraph_GraphDistribution( double *dataArray, + const int numValues, + const int numBins, + const double meanValue, + const double halfWidthValue, + bool includeStdDev, + char *jpgFileName, + char *legend0text, + char *graphTitle); + + +//************************************************************************************** +enum +{ + kTargetType_Esilhouete = 0, + kTargetType_IPSC, + kTargetType_NRA600Yard, + kTargetType_NRA1000Yard, + + kTargetType_last +}; + +//* the number of colors per set in the list below +#define kGraphPoint_ColorsPerSet 8 + +//************************************************************************************** +enum +{ + kGraphPointMode_none = 0, + + kGraphPointMode_RedLine, //* this must be 1 + kGraphPointMode_GreenLine, //* there must be 10 lines in a row + kGraphPointMode_BlueLine, //* these must be in the same color order as below + kGraphPointMode_OrangeLine, + kGraphPointMode_CyanLine, + kGraphPointMode_MagentaLine, + kGraphPointMode_YellowLine, + kGraphPointMode_BlackLine, + + kGraphPointMode_RedLineDashed, //* these must be in the same color order as above + kGraphPointMode_GreenLineDashed, + kGraphPointMode_BlueLineDashed, + kGraphPointMode_OrangeLineDashed, + kGraphPointMode_CyanLineDashed, + kGraphPointMode_MagentaLineDashed, + kGraphPointMode_YellowLineDashed, + kGraphPointMode_BlackLineDashed, + + kGraphPointMode_RedDot, //* these must be in the same color order as above + kGraphPointMode_GreenDot, + kGraphPointMode_BlueDot, + kGraphPointMode_OrangeDot, + kGraphPointMode_CyanDot, + kGraphPointMode_MagentaDot, + kGraphPointMode_YellowDot, + kGraphPointMode_BlackDot, + + kGraphPointMode_Red_X, //* these must be in the same color order as above + kGraphPointMode_Green_X, + kGraphPointMode_Blue_X, + kGraphPointMode_Orange_X, + kGraphPointMode_Cyan_X, + kGraphPointMode_Magenta_X, + kGraphPointMode_Yellow_X, + kGraphPointMode_Black_X, + + + kGraphPointMode_DkGreenLine, + kGraphPointMode_DkGreenDot, + kGraphPointMode_GreyLine, + + kGraphPointMode_RedDot_Large, //* these must be in the same color order as above + kGraphPointMode_GreenDot_Large, + kGraphPointMode_BlueDot_Large, + kGraphPointMode_OrangeDot_Large, + kGraphPointMode_CyanDot_Large, + kGraphPointMode_MagentaDot_Large, + kGraphPointMode_YellowDot_Large, + kGraphPointMode_BlackDot_Large, + + + kGraphPointMode_Last +}; + + +#ifdef __cplusplus +} +#endif + +#endif // _WEB_GRAPHICS_H_ +