How can I create a synapse in the NEURON simulator using its Python interface? I would like to create 2 Sections and connect them with a synapse, but there aren't any functions for it on the Section API or in the Section docs:
from neuron import h
src = h.Section(name="source")
dest = h.Section(name="destination")
In NEURON synapses are of the family of PointProcesses. You can insert a PointProcess into a Section by accessing it on the HocInterpreter and giving it a Segment on the Section. You then have to create a NetCon from a voltage pointer on the presynaptic Section (src(x)._ref_v) to the target point process:
from neuron import h
dest = h.Section(name="destination")
synapse = h.ExpSyn(sec(0.5))
src = h.Section(name="source")
connection = h.NetCon(src(0.5)._ref_v, synapse)
Make sure to keep references to each piece around or they get garbage collected. Also make sure that you set the proper connection.weight (it's an array, so usually connection.weight[0]) and that you set the proper attributes on the point process for it to function as well.
Related
I'm getting very confused trying to setup my simulation correctly in PyDrake. What I want is to have an actuated robot (with e.g. an InverseDynamicsController on it) together with an object in the scene that the robot will manipulate. However, I'm struggling to sort out how to create and use the MultibodyPlant, SceneGraph, Context, Simulator combination correctly.
Here is roughly what I've tried to do:
builder = DiagramBuilder()
plant, scene_graph = AddMultibodyPlantSceneGraph(builder, time_step=1e-4)
parser = Parser(plant, scene_graph)
# Add my robot
robot = parser.AddModelFromFile(robot_urdf)
robot_base = plant.GetFrameByName('robot_base')
plant.WeldFrames(plant.world_frame(), robot_base)
# Add my object
parser.AddModelFromFile(FindResourceOrThrow("drake/my_object.urdf"))
plant.finalize()
# Add my controller
Kp = np.full(6, 100)
Ki = 2 * np.sqrt(Kp)
Kd = np.full(6, 1)
controller = builder.AddSystem(InverseDynamicsController(plant, Kp, Ki, Kd, False))
controller.set_name("sim_controller");
builder.Connect(plant.get_state_output_port(robot),
controller.get_input_port_estimated_state())
builder.Connect(controller.get_output_port_control(),
plant.get_actuation_input_port())
# Get the diagram, simulator, and contexts
diagram = builder.Build()
simulator = Simulator(diagram)
context = simulator.get_mutable_context()
plant_context = plant.GetMyContextFromRoot(context)
However, this has some undesirable qualities. First, as long as I've added the object, then I get this error:
Failure at systems/controllers/inverse_dynamics_controller.cc:32 in SetUp(): condition 'num_positions == dim' failed.
Second, with the object added, the object pose becomes part of my InverseKinematics problem, and when I do SetPositions with plant_context, I have to set both my arm joints AND the pose of the object, when I feel like I should only be setting the robot's joint positions with SetPositions.
I realize I've done something wrong with this setup, and I'm just wondering what is the correct way to have an instance of Simulator that I can run simulations with that has both an actuated robot, and a manipulable object? Am I supposed to create multiple plants? Multiple contexts? Who shares what with who?
I'd really appreciate some advice on this, or a pointer to an example. Drake is great, but I struggle to find minimal examples that do what I want.
Yes, you can add a separate MultibodyPlant for control. See https://github.com/RobotLocomotion/drake/blob/master/examples/planar_gripper/planar_gripper_simulation.cc for an example. The setup is similar to yours, though it's in C++. You can try mimicking the way the diagram is wired up there.
When you do have two plants, you want to call SetPositions on the simulation plant (not the control plant). You can set only the robot positions by using ModelInstanceIndex.
# Add my robot
robot = parser.AddModelFromFile(robot_urdf)
...
plant.SetPositions(plant_context, robot, robot_positions)
I've used Cheat Engine to get an Address and RealAddress for the X coordinate of my player in a game; Sea of Thieves. Unfortunately, the game crashes when I try to find the pointer by methods described online (ie clicking "Find out what access this address"). Since the Address and RealAddress don't seem to change (SoTGame.exe+699FE50 and 7FF6EA32FE50, respectively), is there a way to access the value at this address?
I'd like to use something like ReadWriteMemory (example code from the Git ReadMe w/my adaptations):
from ReadWriteMemory import ReadWriteMemory
rwm = ReadWriteMemory()
process = rwm.get_process_by_name('SoTGame.exe')
process.open()
#health_pointer= process.get_pointer(0x004e4dbc, offsets=[0xf4])
x_pointer = process.get_pointer(0x699FE50)
#health = process.read(health_pointer)
x = process.read(x_pointer)
print({'x': x})
Printing currently returns 0 while cheat engine is showing a very different number.
You want to access the address with offset to the module entry.
Calling get_process_by_name will return the pointer to the process base in memory, but here you want to offset this pointer to the module entry of the process.
The 0x699FE50 is your offset from the module entry, 'SoTGame.exe', hence finding and adding your module entry module_base (usually 0x00400000) will result in the correct address in memory.
In your case, get_pointer(module_base + 0x699FE50) should do the trick.
I'm attempting to use Autodesk Inventor's COM API to create a python script that will generate PDFs of a selection on Inventor Drawings, these PDFs will then be processed in particular ways that aren't important to my question. I'm using pywin32 to access the COM API, but I'm not particularly familiar with how COM APIs are used, and the pywin32 module.
This is the extent of the documentation for Inventor's API that I have been able to find (diagram of API Object Model Reference Document), and I have not been able to find documentation for the individual objects listed. As such, I'm basing my understanding of the use of these objects on what I can find from examples online (all in VB or iLogic - Inventor's own simple built-in language).
A big issue I'm coming up against is in creating the objects I'd like to use. Simplified example below:
from win32com.client import *
# user chooses file paths for open and save here...
drawing_filepath = ""
# Open Inventor application, and set visible (so I can tell it's opened for now)
app = Dispatch('Inventor.Application')
app.Visible = True
# Open the file to be saved as a pdf (returns a Document object)
app.Documents.Open(drawing_filepath)
# Cast the opened Document object to a DrawingDocument object (it is guaranteed to be a drawing)
drawing = CastTo(app.ActiveDocument, "DrawingDocument")
# Create and setup a print manager (so can use "Adobe PDF" printer to convert the drawings to PDF)
print_manager = ??? # How can I create this object
# I've tried:
# print_manager = Dispatch("Inventor.Application.Documents.DrawingDocument.DrawingPrintManager") #"Invalid class string"
# print_manager = drawing.DrawingPrintManager() #"object has no attribute 'DrawingPrintManger'
# print_manager = drawing.DrawingPrintManager # same as above
# print_manager = drawing.PrintManger # worked in the end
print_manager.Printer = "Adobe PDF"
print_manager.NumberOfCopies = 1
print_manager.ScaleMode = print_manager.PrintScaleModeEnum.kPrintFullScale
print_manager.PaperSize = print_manager.PrintSizeEnum.kPaperSizeA3
# Print PDF
print_manager.SubmitPrint()
So I can't figure out how to create a DrawingPrintManager to use! You can see I've avoided this issue when creating my DrawingDocument object, as I just happened to know that there is an ActiveDocument attribute that I can get from the application itself.
I also:
don't know what the full list of attributes and methods for DrawingPrintManager are, so I don't know how to set a save location
don't know for sure that the two Enums I'm trying to use are actually defined within DrawingPrintManager, but I can figure that out once I actually have a DrawingPrintManager to work with
If anyone with more experience in using COM APIs or pywin32 can help me out, I'd be really appreciative. And the same if anyone can point me towards any actual documentation of Inventor's API Objects, which would make things a lot easier.
Thanks
Edit: After posting I've almost immediately found that I can get a PrintManager (can't tell if a PrintManager or DrawingPrintManager) by accessing drawing.PrintManager rather than drawing.DrawingPrintManager.
This is a workaround however as it doesn't answer my question of how to create objects within pywin32.
My problem moving forward is finding where I can access the PrintScaleModeEnum and PrintSizeEnum objects, and finding how to set the save location of the printed PDF (which I think will be a a separate question, as it's probably unrelated to the COM API).
I'm not familiar with python and pywin32, but I try to answer your questions.
Documentation of Inventor API is available in local installation "C:\Users\Public\Documents\Autodesk\Inventor 2020\Local Help" or online https://help.autodesk.com/view/INVNTOR/2020/ENU/
Generaly you are not able to create new instances of Inventor API objects. You must obtain them as a result of appropriate method or property value.
For example:
You CAN'T do this
doc = new Inventor.Document()
You MUST do this
doc = app.Documents.Add(...)
With print manager is this
print_manager = drawing.PrintManger
# this returns object of type Inventor.DrawingPrintManager
# when drawing is of type Inventor.DrawingDocument
See this for more details
I am working on OPCUA in python. I am using freeopc. I have used their server_minimal & client_minimal example and it is running fine. I am having some issues understanding the code. As far as I know the OPCUA stack, it has address space which is like a collection of all the nodes. These nodes then further contains objects and these objects have variable from where we can read write data. Please correct me if I am wrong.
---------------------------------
Address space
---------------------------------
| |
| |
V V
Node1 Node2
|
Object1
|
Var1, Var2
So on the server side I want to know what is namespace
# setup our own namespace, not really necessary but should as spec
uri = "http://examples.freeopcua.github.io"
idx = server.register_namespace(uri)
What is the namespace used for.? What to put inside uri.?
On client side, I want to know:
After connecting to server, we are doing:
# Client has a few methods to get proxy to UA nodes that should always be in address space such as Root or Objects
root = client.get_root_node()
print("Objects node is: ", root)
What does get_root_node() means. Is it like we are connecting to address space of server where all the nodes are defined.?
# Node objects have methods to read and write node attributes as well as browse or populate address space
print("Children of root are: ", root.get_children())
root.get_children()-- Does this means getting the objects of the nodes.?
# Now getting a variable node using its browse path
myvar = root.get_child(["0:Objects", "2:MyObject", "2:MyVariable"])
obj = root.get_child(["0:Objects", "2:MyObject"])
root.get_child what does it means.?
Client output:
('Objects node is: ', Node(TwoByteNodeId(i=84)))
('Children of root are: ', [Node(NumericNodeId(i=85)), Node(NumericNodeId(i=86)), Node(NumericNodeId(i=87))])
Above code is taken from server_minimal.py client_minimal.py
Can anyone please explain these. I tried reading their docs but this is not mentioned there.
Thanks.
I'm working with freeopcua too and on some questions I think I have an answer
root = client.get_root_node()
will get you the node of the root of your server so basically 'adress space' in your diagram.
root.get_children()
will return a list of all nodes that are direct children of the root so in the example of your tree.
[node1, node2]. However add the root node this is 0:Objects, 0:Types, 0:Views
To see the tree of the server you can best use the opcua-client this is a GUI that will allow you to see the tree.
to do this start your server and then in your terminal typ;
$ opcua-client
(when on linux)
You can add limitation to get children e.g.:
objects = root.get_children(refs=ua.ObjectIds.HasChild, nodeclassmask=ua.NodeClass.Object)
This will only return other objects not methods or properties of your node.
The output you get is because Node doesn't have a real 'ToString()' the i is the id of the node (can also be seen with the GUI client).
the
Node.getChild(NodeId)
will return a node object if you're certain you added a value you can get it,s value by calling .get_value() on the return of this. NodeId is the specification of what child you want. So say you want var1 this would be
# First the code needed to add the node
node1 = root.add_object(2, "Node1") # root is the root node which can be obtained by either client.get_root_node or server.get_root_node
object1 = node1.add_object(3, "Object1")
object1.add_variable(4, "Var1", 42)
object1.add_variable(4, "Var2", 13)
# Now the code to ask the server for the node
var1_node = root.getChild(["2:Node1", "3:Object1", "4:Var1"])
# And to get its value
var1_node.get_value()
Important here is that to get a child you need to know where you are (you can get children from any Node object not only root) and then go down with a combination of "idx:Name" which is what you add when you added the value to the server in the first place.
Hoped this helped a bit (did not test the code so it might need some adjustments to actually run)
To understand this better you can use, Unified Automation UA Expert as a client.
https://www.unified-automation.com/downloads/opc-ua-clients.html
Start the server_minimal.py, open UA Expert add server using 'Custom Discovery' with "opc.tcp://localhost:4840/freeopcua/server/". You can easily view the entire address space.
I'd like to do the exact same thing that is explained here :
How to continuously monitor rhythmbox for track change using python
but with Clementine instead of Rhythmbox.
Problem is, I couldn't find the equivalent of playingUriChanged to give to the connect_to_signal method.
The only thing I could find with qdbus that seemed relevant was
signal void org.freedesktop.MediaPlayer.TrackChange(QVariantMap)
but it takes a parameter.
I'm not familiar with DBus so any help is appreciated.
Thanks
It does not take a parameter, it returns parameter (hash map)
code extracted from this script:
def TrackChange(Track):
# use Track["URI"], Track["title"], Track["artist"] etc
def Connect(name):
global root, player, tracklist
# first we connect to the objects
root_o = bus.get_object(name, "/")
player_o = bus.get_object(name, "/Player")
tracklist_o = bus.get_object(name, "/TrackList")
# there is only 1 interface per object
root = dbus.Interface(root_o, "org.freedesktop.MediaPlayer")
tracklist = dbus.Interface(tracklist_o, "org.freedesktop.MediaPlayer")
player = dbus.Interface(player_o, "org.freedesktop.MediaPlayer")
# connect to the TrackChange signal
player_o.connect_to_signal("TrackChange", TrackChange, dbus_interface="org.freedesktop.MediaPlayer")