source: BAORadio/libindi/libindi/libs/indibase/inditelescope.cpp @ 504

Last change on this file since 504 was 504, checked in by frichard, 13 years ago

-Version 0.8 de libini
-Formule de Marc
-Nouvelles fonctionnalités (goto nom-de l'objet etc...)

File size: 13.2 KB
Line 
1/*******************************************************************************
2  Copyright(c) 2010 Gerry Rozema. All rights reserved.
3
4  This program is free software; you can redistribute it and/or modify it
5  under the terms of the GNU General Public License as published by the Free
6  Software Foundation; either version 2 of the License, or (at your option)
7  any later version.
8
9  This program is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  more details.
13
14  You should have received a copy of the GNU General Public License along with
15  this program; if not, write to the Free Software Foundation, Inc., 59
16  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
18  The full GNU General Public License is included in this distribution in the
19  file called LICENSE.
20*******************************************************************************/
21
22#include "inditelescope.h"
23#include "libs/indicom.h"
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <stdarg.h>
29#include <math.h>
30#include <unistd.h>
31#include <time.h>
32#include <sys/ioctl.h>
33#include <fcntl.h>
34#include <termios.h>
35
36#define POLLMS 1000
37
38INDI::Telescope::Telescope()
39{
40    //ctor
41}
42
43INDI::Telescope::~Telescope()
44{
45    //dtor
46}
47
48bool INDI::Telescope::initProperties()
49{
50    DefaultDriver::initProperties();
51
52    EqNV = new INumberVectorProperty;
53
54    IUFillNumber(&EqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0);
55    IUFillNumber(&EqN[1],"DEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,0);
56    IUFillNumberVector(EqNV,EqN,2,deviceName(),"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RO,60,IPS_IDLE);
57
58    EqReqNV = new INumberVectorProperty;
59
60    IUFillNumber(&EqReqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0);
61    IUFillNumber(&EqReqN[1],"DEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,0);
62    IUFillNumberVector(EqReqNV,EqReqN,2,deviceName(),"EQUATORIAL_EOD_COORD_REQUEST","GOTO","Controls",IP_WO,60,IPS_IDLE);
63
64    LocationNV = new INumberVectorProperty;
65
66    IUFillNumber(&LocationN[0],"LAT","Lat (dd:mm:ss)","%010.6m",-90,90,0,0.0);
67    IUFillNumber(&LocationN[1],"LONG","Lon (dd:mm:ss)","%010.6m",0,360,0,0.0 );
68    IUFillNumberVector(LocationNV,LocationN,2,deviceName(),"GEOGRAPHIC_COORD","Scope Location","Location",IP_RW,60,IPS_OK);
69
70    CoordSV = new ISwitchVectorProperty;
71
72    IUFillSwitch(&CoordS[0],"TRACK","Track",ISS_OFF);
73    IUFillSwitch(&CoordS[1],"SLEW","Slew",ISS_OFF);
74    IUFillSwitch(&CoordS[2],"SYNC","Sync",ISS_OFF);
75    IUFillSwitchVector(CoordSV,CoordS,3,deviceName(),"ON_COORD_SET","On Set","Controls",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
76
77    ParkSV = new ISwitchVectorProperty;
78
79    IUFillSwitch(&ParkS[0],"PARK","Park",ISS_OFF);
80    IUFillSwitchVector(ParkSV,ParkS,1,deviceName(),"TELESCOPE_PARK","Park","Controls",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
81
82    PortTV = new ITextVectorProperty;
83
84    IUFillText(&PortT[0],"PORT","Port","/dev/ttyUSB0");
85    IUFillTextVector(PortTV,PortT,1,deviceName(),"DEVICE_PORT","Ports","Options",IP_RW,60,IPS_IDLE);
86
87    TrackState=SCOPE_PARKED;
88    return 0;
89}
90
91void INDI::Telescope::ISGetProperties (const char *dev)
92{
93    //  First we let our parent populate
94    //IDLog("INDI::Telescope::ISGetProperties %s\n",dev);
95    DefaultDriver::ISGetProperties(dev);
96
97    //  We may need the port set before we can connect
98    //IDDefText(&PortTV,NULL);
99    //LoadConfig();
100
101    if(isConnected())
102    {
103        //  Now we add our telescope specific stuff
104        defineSwitch(CoordSV);
105        defineNumber(EqNV);
106        defineNumber(EqReqNV);
107        defineNumber(LocationNV);
108        defineSwitch(ParkSV);
109    }
110    return;
111}
112
113bool INDI::Telescope::updateProperties()
114{
115    if(isConnected())
116    {
117        //  Now we add our telescope specific stuff
118        //IDLog("INDI::Telescope adding properties\n");
119        defineSwitch(CoordSV);
120        defineNumber(EqNV);
121        defineNumber(EqReqNV);
122        //IDDefText(&PortTV,NULL);
123        defineNumber(LocationNV);
124        defineSwitch(ParkSV);
125    } else
126    {
127        //IDLog("INDI::Telescope deleting properties\n");
128        deleteProperty(CoordSV->name);
129        deleteProperty(EqNV->name);
130        deleteProperty(EqReqNV->name);
131        //DeleteProperty(PortTV.name);
132        deleteProperty(LocationNV->name);
133        deleteProperty(ParkSV->name);
134
135        initProperties();
136    }
137    return true;
138}
139
140int INDI::Telescope::NewRaDec(double ra,double dec)
141{
142    //  Lets set our eq values to these numbers
143    //  which came from the hardware
144    EqN[0].value=ra;
145    EqN[1].value=dec;
146
147    if (TrackState == SCOPE_TRACKING && EqReqNV->s != IPS_OK)
148    {
149        EqReqNV->s = IPS_OK;
150        IDSetNumber(EqReqNV, NULL);
151    }
152    if ( (TrackState == SCOPE_PARKED || TrackState == SCOPE_IDLE) && EqReqNV->s != IPS_IDLE)
153    {
154        EqReqNV->s = IPS_IDLE;
155        IDSetNumber(EqReqNV, NULL);
156    }
157
158    return 0;
159}
160
161bool INDI::Telescope::ReadScopeStatus()
162{
163    //  Return an error, because we sholdn't get here
164    return false;
165}
166
167bool INDI::Telescope::Goto(double ra,double dec)
168{
169    //  if we get here, it's because our derived hardware class
170    //  does not support goto
171    return false;
172}
173
174bool INDI::Telescope::Sync(double ra,double dec)
175{
176    //  if we get here, our mount doesn't support sync
177    IDMessage(deviceName(),"Mount does not support Sync");
178    return false;
179}
180
181/**************************************************************************************
182** Process Text properties
183***************************************************************************************/
184bool INDI::Telescope::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
185{
186    //  Ok, lets see if this is a property wer process
187    //IDLog("INDI::Telescope got %d new text items name %s\n",n,name);
188    //  first check if it's for our device
189    if(strcmp(dev,deviceName())==0)
190    {
191        //  This is for our device
192        //  Now lets see if it's something we process here
193        if(strcmp(name,PortTV->name)==0)
194        {
195            //  This is our port, so, lets process it
196
197            //  Some clients insist on sending a port
198            //  and they may not be configured for the
199            //  correct port
200            //  If we are already connected
201            //  and running, it makes absolutely no sense
202            //  to accept a new port value
203            //  so lets just lie to them and say
204            //  we did this, but, dont actually change anything
205            //if(Connected) return true;
206
207            int rc;
208            //IDLog("calling update text\n");
209            PortTV->s=IPS_OK;
210            rc=IUUpdateText(PortTV,texts,names,n);
211            //IDLog("update text returns %d\n",rc);
212            //  Update client display
213            IDSetText(PortTV,NULL);
214            //SaveConfig();
215            //  We processed this one, so, tell the world we did it
216            return true;
217        }
218
219    }
220
221    return DefaultDriver::ISNewText(dev,name,texts,names,n);
222}
223
224/**************************************************************************************
225**
226***************************************************************************************/
227bool INDI::Telescope::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
228{
229    //  first check if it's for our device
230    //IDLog("INDI::Telescope::ISNewNumber %s\n",name);
231    if(strcmp(dev,deviceName())==0)
232    {
233        if(strcmp(name,"EQUATORIAL_EOD_COORD_REQUEST")==0)
234        {
235            //  this is for us, and it is a goto
236            bool rc=false;
237            double ra=-1;
238            double dec=-100;
239
240            for (int x=0; x<n; x++)
241            {
242
243                //IDLog("request stuff %s %4.2f\n",names[x],values[x]);
244
245                INumber *eqp = IUFindNumber (EqNV, names[x]);
246                if (eqp == &EqN[0])
247                {
248                    ra = values[x];
249                } else if (eqp == &EqN[1])
250                {
251                    dec = values[x];
252                }
253            }
254            //IDLog("Got %4.2f %4.2f\n",ra,dec);
255            if ((ra>=0)&&(ra<=24)&&(dec>=-90)&&(dec<=90))
256            {
257                //  we got an ra and a dec, both in range
258                //  And now we let the underlying hardware specific class
259                //  perform the goto
260                //  Ok, lets see if we should be doing a goto
261                //  or a sync
262                ISwitch *sw;
263                sw=IUFindSwitch(CoordSV,"SYNC");
264                if((sw != NULL)&&( sw->s==ISS_ON ))
265                {
266                    //IDLog("Got a sync, we dont process yet\n");
267                    rc=Sync(ra,dec);
268                } else {
269                    //  Ensure we are not showing Parked status
270                    ParkSV->s=IPS_IDLE;
271                    IDSetSwitch(ParkSV,NULL);
272                    rc=Goto(ra,dec);
273                }
274                //  Ok, now we have to put our switches back
275            }
276            return rc;
277        }
278
279        if(strcmp(name,"GEOGRAPHIC_COORD")==0)
280        {
281            //  Client wants to update the lat/long
282            //  For now, we'll allow this, but, in future
283            //  If we have lat/lon from gps, we'll prevent this
284            //  from being updated
285            LocationNV->s=IPS_OK;
286            IUUpdateNumber(LocationNV,values,names,n);
287            //  Update client display
288            IDSetNumber(LocationNV,NULL);
289        }
290    }
291
292
293
294    return DefaultDriver::ISNewNumber(dev,name,values,names,n);
295}
296
297/**************************************************************************************
298**
299***************************************************************************************/
300bool INDI::Telescope::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
301{
302    //IDLog("Enter IsNewSwitch for %s\n",name);
303    //for(int x=0; x<n; x++) {
304    //    IDLog("Switch %s %d\n",names[x],states[x]);
305    //}
306
307    if(strcmp(dev,deviceName())==0)
308    {
309        //  This one is for us
310        if(strcmp(name,"ON_COORD_SET")==0)
311        {
312            //  client is telling us what to do with co-ordinate requests
313            CoordSV->s=IPS_OK;
314            IUUpdateSwitch(CoordSV,states,names,n);
315            //  Update client display
316            IDSetSwitch(CoordSV,NULL);
317
318            for(int x=0; x<n; x++)
319            {
320
321
322            }
323            return true;
324        }
325
326        if(strcmp(name,"TELESCOPE_PARK")==0)
327        {
328            Park();
329        }
330    }
331
332    //  Nobody has claimed this, so, ignore it
333    return DefaultDriver::ISNewSwitch(dev,name,states,names,n);
334}
335
336bool INDI::Telescope::Connect()
337{
338    //  Parent class is wanting a connection
339    //IDLog("INDI::Telescope calling connect with %s\n",PortT[0].text);
340    bool rc=false;
341
342    if(isConnected()) return true;
343
344    //IDLog("Calling Connect\n");
345
346    rc=Connect(PortT[0].text);
347
348    if(rc)
349        SetTimer(POLLMS);
350    return rc;
351}
352
353bool INDI::Telescope::Connect(const char *port)
354{
355    //  We want to connect to a port
356    //  For now, we will assume it's a serial port
357    //struct termios tty;
358
359    int connectrc=0;
360    char errorMsg[MAXRBUF];
361    bool rc;
362
363
364    if ( (connectrc = tty_connect(port, B9600, 8, 0, 1, &PortFD)) != TTY_OK)
365    {
366        tty_error_msg(connectrc, errorMsg, MAXRBUF);
367
368        if (isDebug())
369            IDLog("Failed to connect o port %s. Error: %s", port, errorMsg);
370        IDMessage(deviceName(), "Failed to connect to port %s. Error: %s", port, errorMsg);
371
372        return false;
373
374    }
375
376    /* Flush the input (read) buffer */
377
378    tcflush(PortFD,TCIOFLUSH);
379
380    /* Test connection */
381    rc=ReadScopeStatus();
382    if(rc)
383    {
384        //  We got a valid scope status read
385        IDMessage(deviceName(),"Telescope is online.");
386        return rc;
387    }
388
389    //  Ok, we didn't get a valid read
390    //  So, we need to close our handle and send error messages
391    close(PortFD);
392    //IDMessage(deviceName(),"Didn't find a synscan mount on Serial Port");
393
394    return false;
395}
396
397bool INDI::Telescope::Disconnect()
398{
399    //  We dont actually close the serial connection
400    //  because clients can screw each other up if we allow that
401    //Connected=false;
402
403    close(PortFD);
404    IDMessage(deviceName(),"Telescope is offline.");
405
406    return true;
407}
408
409
410void INDI::Telescope::TimerHit()
411{
412    //IDLog("Timer Hit\n");
413    if(isConnected())
414    {
415        bool rc;
416
417        rc=ReadScopeStatus();
418        //IDLog("TrackState after read is %d\n",TrackState);
419        if(rc)
420        {
421            //  read was good
422            switch(TrackState)
423            {
424              case SCOPE_IDLE:
425              case SCOPE_PARKED:
426                EqNV->s=IPS_IDLE;
427                break;
428
429             case SCOPE_SLEWING:
430             case SCOPE_PARKING:
431                EqNV->s=IPS_BUSY;
432                break;
433
434            case SCOPE_TRACKING:
435                EqNV->s=IPS_OK;
436                break;
437            }
438        } else
439        {
440            //  read was not good
441            EqNV->s=IPS_ALERT;
442        }
443        //IDLog("IsConnected, re-arm timer\n");
444        //  Now update the Client data
445        IDSetNumber(EqNV,NULL);
446        SetTimer(POLLMS);
447    }
448}
449
450
451bool INDI::Telescope::Park()
452{
453    //  We want to park our telescope
454    //  but the scope doesn't seem to support park
455    //  or it wouldn't have gotten here
456    return false;
457}
458
Note: See TracBrowser for help on using the repository browser.